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.

961 lines
24 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. comm1632.c
  5. Abstract:
  6. Instructions with common (shared) WORD, and DWORD flavors (but not BYTE).
  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 "config.h"
  18. #include "threadst.h"
  19. #include "instr.h"
  20. #include "decoderp.h"
  21. #include "comm1632.h"
  22. extern OPERATION MANGLENAME(Group1Map)[];
  23. // ---------------- single-byte functions -------------------------------
  24. DISPATCHCOMMON(dispatch2)
  25. {
  26. eipTemp++;
  27. #if MSB==0x8000
  28. ((pfnDispatchInstruction)(Dispatch216[GET_BYTE(eipTemp)]))(State, Instr);
  29. #else
  30. ((pfnDispatchInstruction)(Dispatch232[GET_BYTE(eipTemp)]))(State, Instr);
  31. #endif
  32. }
  33. DISPATCHCOMMON(LOCKdispatch2)
  34. {
  35. eipTemp++;
  36. #if MSB==0x8000
  37. ((pfnDispatchInstruction)(LockDispatch216[GET_BYTE(eipTemp)]))(State, Instr);
  38. #else
  39. ((pfnDispatchInstruction)(LockDispatch232[GET_BYTE(eipTemp)]))(State, Instr);
  40. #endif
  41. }
  42. DISPATCHCOMMON(pushf)
  43. {
  44. Instr->Operation = OPNAME(Pushf);
  45. }
  46. DISPATCHCOMMON(popf)
  47. {
  48. Instr->Operation = OPNAME(Popf);
  49. }
  50. DISPATCHCOMMON(pusha)
  51. {
  52. Instr->Operation = OPNAME(PushA);
  53. }
  54. DISPATCHCOMMON(popa)
  55. {
  56. Instr->Operation = OPNAME(PopA);
  57. }
  58. DISPATCHCOMMON(push_iw)
  59. {
  60. Instr->Operation = OPNAME(Push);
  61. Instr->Operand1.Type = OPND_IMM;
  62. Instr->Operand1.Immed = GET_VAL(eipTemp+1);
  63. Instr->Size = 1+sizeof(UTYPE);
  64. }
  65. DISPATCHCOMMON(push_ibs)
  66. {
  67. Instr->Operation = OPNAME(Push);
  68. Instr->Operand1.Type = OPND_IMM;
  69. Instr->Operand1.Immed = (UTYPE)(STYPE)(char)GET_BYTE(eipTemp+1);
  70. Instr->Size = 2;
  71. }
  72. DISPATCHCOMMON(GROUP_1WS)
  73. {
  74. int cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  75. BYTE g = GET_BYTE(eipTemp+1);
  76. g = (g >> 3) & 0x07;
  77. Instr->Operation = MANGLENAME(Group1Map)[g];
  78. Instr->Operand2.Type = OPND_IMM;
  79. Instr->Operand2.Immed = (UTYPE)(STYPE)(char)GET_BYTE(eipTemp + cbInstr + 1);
  80. if (g == 7) {
  81. // Cmp takes both params as byval
  82. DEREF(Instr->Operand1);
  83. }
  84. Instr->Size = cbInstr+2;
  85. }
  86. DISPATCHCOMMON(LOCKGROUP_1WS)
  87. {
  88. int cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  89. BYTE g = GET_BYTE(eipTemp+1);
  90. g = (g >> 3) & 0x07;
  91. Instr->Operation = MANGLENAME(Group1LockMap)[g];
  92. Instr->Operand2.Type = OPND_IMM;
  93. Instr->Operand2.Immed = (UTYPE)(STYPE)(char)GET_BYTE(eipTemp + cbInstr + 1);
  94. if (g == 7) {
  95. // Cmp takes both params as byval
  96. DEREF(Instr->Operand1);
  97. }
  98. Instr->Size = cbInstr+2;
  99. }
  100. DISPATCHCOMMON(mov_rw_mw)
  101. {
  102. int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
  103. Instr->Operation = OPNAME(Mov);
  104. DEREF(Instr->Operand2);
  105. Instr->Size = cbInstr+1;
  106. }
  107. DISPATCHCOMMON(lea_rw_mw)
  108. {
  109. int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
  110. Instr->Operation = OPNAME(Mov);
  111. Instr->Size = cbInstr+1;
  112. }
  113. DISPATCHCOMMON(pop_mw)
  114. {
  115. int cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  116. Instr->Operation = OPNAME(Pop);
  117. Instr->Size = 1+cbInstr;
  118. }
  119. DISPATCHCOMMON(xchg_ax_cx)
  120. {
  121. Instr->Operation = OPNAME(Xchg);
  122. Instr->Operand1.Type = OPND_REGREF;
  123. Instr->Operand1.Reg = AREG;
  124. Instr->Operand2.Type = OPND_REGREF;
  125. Instr->Operand2.Reg = CREG;
  126. }
  127. DISPATCHCOMMON(xchg_ax_dx)
  128. {
  129. Instr->Operation = OPNAME(Xchg);
  130. Instr->Operand1.Type = OPND_REGREF;
  131. Instr->Operand1.Reg = AREG;
  132. Instr->Operand2.Type = OPND_REGREF;
  133. Instr->Operand2.Reg = DREG;
  134. }
  135. DISPATCHCOMMON(xchg_ax_bx)
  136. {
  137. Instr->Operation = OPNAME(Xchg);
  138. Instr->Operand1.Type = OPND_REGREF;
  139. Instr->Operand1.Reg = AREG;
  140. Instr->Operand2.Type = OPND_REGREF;
  141. Instr->Operand2.Reg = BREG;
  142. }
  143. DISPATCHCOMMON(xchg_ax_sp)
  144. {
  145. Instr->Operation = OPNAME(Xchg);
  146. Instr->Operand1.Type = OPND_REGREF;
  147. Instr->Operand1.Reg = AREG;
  148. Instr->Operand2.Type = OPND_REGREF;
  149. Instr->Operand2.Reg = SPREG;
  150. }
  151. DISPATCHCOMMON(xchg_ax_bp)
  152. {
  153. Instr->Operation = OPNAME(Xchg);
  154. Instr->Operand1.Type = OPND_REGREF;
  155. Instr->Operand1.Reg = AREG;
  156. Instr->Operand2.Type = OPND_REGREF;
  157. Instr->Operand2.Reg = BPREG;
  158. }
  159. DISPATCHCOMMON(xchg_ax_si)
  160. {
  161. Instr->Operation = OPNAME(Xchg);
  162. Instr->Operand1.Type = OPND_REGREF;
  163. Instr->Operand1.Reg = AREG;
  164. Instr->Operand2.Type = OPND_REGREF;
  165. Instr->Operand2.Reg = SIREG;
  166. }
  167. DISPATCHCOMMON(xchg_ax_di)
  168. {
  169. Instr->Operation = OPNAME(Xchg);
  170. Instr->Operand1.Type = OPND_REGREF;
  171. Instr->Operand1.Reg = AREG;
  172. Instr->Operand2.Type = OPND_REGREF;
  173. Instr->Operand2.Reg = DIREG;
  174. }
  175. DISPATCHCOMMON(cbw)
  176. {
  177. Instr->Operation = OPNAME(Cbw);
  178. }
  179. DISPATCHCOMMON(cwd)
  180. {
  181. Instr->Operation = OPNAME(Cwd);
  182. }
  183. DISPATCHCOMMON(mov_sp_iw)
  184. {
  185. Instr->Operation = OPNAME(Mov);
  186. Instr->Operand1.Type = OPND_REGREF;
  187. Instr->Operand1.Reg = SPREG;
  188. Instr->Operand2.Type = OPND_IMM;
  189. Instr->Operand2.Immed = GET_VAL(eipTemp+1);
  190. Instr->Size = 1+sizeof(UTYPE);
  191. }
  192. DISPATCHCOMMON(mov_bp_iw)
  193. {
  194. Instr->Operation = OPNAME(Mov);
  195. Instr->Operand1.Type = OPND_REGREF;
  196. Instr->Operand1.Reg = BPREG;
  197. Instr->Operand2.Type = OPND_IMM;
  198. Instr->Operand2.Immed = GET_VAL(eipTemp+1);
  199. Instr->Size = 1+sizeof(UTYPE);
  200. }
  201. DISPATCHCOMMON(mov_si_iw)
  202. {
  203. Instr->Operation = OPNAME(Mov);
  204. Instr->Operand1.Type = OPND_REGREF;
  205. Instr->Operand1.Reg = SIREG;
  206. Instr->Operand2.Type = OPND_IMM;
  207. Instr->Operand2.Immed = GET_VAL(eipTemp+1);
  208. Instr->Size = 1+sizeof(UTYPE);
  209. }
  210. DISPATCHCOMMON(mov_di_iw)
  211. {
  212. Instr->Operation = OPNAME(Mov);
  213. Instr->Operand1.Type = OPND_REGREF;
  214. Instr->Operand1.Reg = DIREG;
  215. Instr->Operand2.Type = OPND_IMM;
  216. Instr->Operand2.Immed = GET_VAL(eipTemp+1);
  217. Instr->Size = 1+sizeof(UTYPE);
  218. }
  219. DISPATCHCOMMON(loopne_b)
  220. {
  221. Instr->Operand1.Type = OPND_NOCODEGEN;
  222. Instr->Operand1.Immed = (CHAR)GET_BYTE(eipTemp+1)+2+eipTemp;
  223. if (Instr->Operand1.Immed > eipTemp) {
  224. Instr->Operation = OPNAME(CTRL_COND_Loopne_bFwd);
  225. } else {
  226. Instr->Operation = OPNAME(CTRL_COND_Loopne_b);
  227. }
  228. Instr->Size = 2;
  229. }
  230. DISPATCHCOMMON(loope_b)
  231. {
  232. Instr->Operand1.Type = OPND_NOCODEGEN;
  233. Instr->Operand1.Immed = (CHAR)GET_BYTE(eipTemp+1)+2+eipTemp;
  234. if (Instr->Operand1.Immed > eipTemp) {
  235. Instr->Operation = OPNAME(CTRL_COND_Loope_bFwd);
  236. } else {
  237. Instr->Operation = OPNAME(CTRL_COND_Loope_b);
  238. }
  239. Instr->Size = 2;
  240. }
  241. DISPATCHCOMMON(loop_b)
  242. {
  243. Instr->Operand1.Type = OPND_NOCODEGEN;
  244. Instr->Operand1.Immed = (CHAR)GET_BYTE(eipTemp+1)+2+eipTemp;
  245. if (Instr->Operand1.Immed > eipTemp) {
  246. Instr->Operation = OPNAME(CTRL_COND_Loop_bFwd);
  247. } else {
  248. Instr->Operation = OPNAME(CTRL_COND_Loop_b);
  249. }
  250. Instr->Size = 2;
  251. }
  252. DISPATCHCOMMON(jcxz_b)
  253. {
  254. Instr->Operand1.Type = OPND_NOCODEGEN;
  255. if (State->AdrPrefix) {
  256. // "ADR: jecxz" is the same as "DATA: jecxz"... which is "jcxz"
  257. Instr->Operand1.Immed = MAKELONG((char)GET_BYTE(eipTemp+1)+2+(short)LOWORD(eipTemp), HIWORD(eipTemp));
  258. if (Instr->Operand1.Immed > eipTemp) {
  259. Instr->Operation = OP_CTRL_COND_Jcxz_bFwd16;
  260. } else {
  261. Instr->Operation = OP_CTRL_COND_Jcxz_b16;
  262. }
  263. #if DBG
  264. State->AdrPrefix = FALSE;
  265. #endif
  266. } else {
  267. Instr->Operand1.Immed = (CHAR)GET_BYTE(eipTemp+1)+2+eipTemp;
  268. if (Instr->Operand1.Immed > eipTemp) {
  269. Instr->Operation = OPNAME(CTRL_COND_Jcxz_bFwd);
  270. } else {
  271. Instr->Operation = OPNAME(CTRL_COND_Jcxz_b);
  272. }
  273. }
  274. Instr->Size = 2;
  275. }
  276. DISPATCHCOMMON(GROUP_5)
  277. {
  278. int cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  279. BYTE g = GET_BYTE(eipTemp+1);
  280. switch ((g >> 3) & 0x07) {
  281. case 0: // inc modrmW
  282. Instr->Operation = OPNAME(Inc);
  283. break;
  284. case 1: // dec modrmW
  285. Instr->Operation = OPNAME(Dec);
  286. break;
  287. case 2: // call indirmodrmW
  288. DEREF(Instr->Operand1);
  289. Instr->Operand2.Type = OPND_IMM;
  290. Instr->Operand2.Immed = eipTemp + cbInstr + 1;
  291. Instr->Operation = OP_CTRL_INDIR_Call;
  292. break;
  293. case 3: // call indirFARmodrmW
  294. Instr->Operand2.Type = OPND_IMM;
  295. Instr->Operand2.Immed = eipTemp + cbInstr + 1;
  296. Instr->Operation = OP_CTRL_INDIR_Callf;
  297. break;
  298. case 4: // jmp indirmodrmW
  299. DEREF(Instr->Operand1);
  300. Instr->Operation = OP_CTRL_INDIR_Jmp;
  301. break;
  302. case 5: // jmp indirFARmodrmW
  303. Instr->Operation = OP_CTRL_INDIR_Jmpf;
  304. break;
  305. case 6: // push modrmW
  306. DEREF(Instr->Operand1);
  307. Instr->Operation = OPNAME(Push);
  308. break;
  309. case 7: // bad
  310. BAD_INSTR;
  311. break;
  312. }
  313. Instr->Size = cbInstr+1;
  314. }
  315. DISPATCHCOMMON(LOCKGROUP_5)
  316. {
  317. int cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  318. BYTE g = GET_BYTE(eipTemp+1);
  319. switch ((g >> 3) & 0x07) {
  320. case 0: // inc modrmW
  321. Instr->Operation = LOCKOPNAME(Inc);
  322. break;
  323. case 1: // dec modrmW
  324. Instr->Operation = LOCKOPNAME(Dec);
  325. break;
  326. default:
  327. BAD_INSTR;
  328. break;
  329. }
  330. Instr->Size = cbInstr+1;
  331. }
  332. DISPATCHCOMMON(inc_ax)
  333. {
  334. Instr->Operation = OPNAME(Inc);
  335. Instr->Operand1.Type = OPND_REGREF;
  336. Instr->Operand1.Reg = AREG;
  337. }
  338. DISPATCHCOMMON(inc_cx)
  339. {
  340. Instr->Operation = OPNAME(Inc);
  341. Instr->Operand1.Type = OPND_REGREF;
  342. Instr->Operand1.Reg = CREG;
  343. }
  344. DISPATCHCOMMON(inc_dx)
  345. {
  346. Instr->Operation = OPNAME(Inc);
  347. Instr->Operand1.Type = OPND_REGREF;
  348. Instr->Operand1.Reg = DREG;
  349. }
  350. DISPATCHCOMMON(inc_bx)
  351. {
  352. Instr->Operation = OPNAME(Inc);
  353. Instr->Operand1.Type = OPND_REGREF;
  354. Instr->Operand1.Reg = BREG;
  355. }
  356. DISPATCHCOMMON(inc_sp)
  357. {
  358. Instr->Operation = OPNAME(Inc);
  359. Instr->Operand1.Type = OPND_REGREF;
  360. Instr->Operand1.Reg = SPREG;
  361. }
  362. DISPATCHCOMMON(inc_bp)
  363. {
  364. Instr->Operation = OPNAME(Inc);
  365. Instr->Operand1.Type = OPND_REGREF;
  366. Instr->Operand1.Reg = BPREG;
  367. }
  368. DISPATCHCOMMON(inc_si)
  369. {
  370. Instr->Operation = OPNAME(Inc);
  371. Instr->Operand1.Type = OPND_REGREF;
  372. Instr->Operand1.Reg = SIREG;
  373. }
  374. DISPATCHCOMMON(inc_di)
  375. {
  376. Instr->Operation = OPNAME(Inc);
  377. Instr->Operand1.Type = OPND_REGREF;
  378. Instr->Operand1.Reg = DIREG;
  379. }
  380. DISPATCHCOMMON(dec_ax)
  381. {
  382. Instr->Operation = OPNAME(Dec);
  383. Instr->Operand1.Type = OPND_REGREF;
  384. Instr->Operand1.Reg = AREG;
  385. }
  386. DISPATCHCOMMON(dec_cx)
  387. {
  388. Instr->Operation = OPNAME(Dec);
  389. Instr->Operand1.Type = OPND_REGREF;
  390. Instr->Operand1.Reg = CREG;
  391. }
  392. DISPATCHCOMMON(dec_dx)
  393. {
  394. Instr->Operation = OPNAME(Dec);
  395. Instr->Operand1.Type = OPND_REGREF;
  396. Instr->Operand1.Reg = DREG;
  397. }
  398. DISPATCHCOMMON(dec_bx)
  399. {
  400. Instr->Operation = OPNAME(Dec);
  401. Instr->Operand1.Type = OPND_REGREF;
  402. Instr->Operand1.Reg = BREG;
  403. }
  404. DISPATCHCOMMON(dec_sp)
  405. {
  406. Instr->Operation = OPNAME(Dec);
  407. Instr->Operand1.Type = OPND_REGREF;
  408. Instr->Operand1.Reg = SPREG;
  409. }
  410. DISPATCHCOMMON(dec_bp)
  411. {
  412. Instr->Operation = OPNAME(Dec);
  413. Instr->Operand1.Type = OPND_REGREF;
  414. Instr->Operand1.Reg = BPREG;
  415. }
  416. DISPATCHCOMMON(dec_si)
  417. {
  418. Instr->Operation = OPNAME(Dec);
  419. Instr->Operand1.Type = OPND_REGREF;
  420. Instr->Operand1.Reg = SIREG;
  421. }
  422. DISPATCHCOMMON(dec_di)
  423. {
  424. Instr->Operation = OPNAME(Dec);
  425. Instr->Operand1.Type = OPND_REGREF;
  426. Instr->Operand1.Reg = DIREG;
  427. }
  428. DISPATCHCOMMON(push_ax)
  429. {
  430. Instr->Operation = OPNAME(Push);
  431. Instr->Operand1.Type = OPND_REGVALUE;
  432. Instr->Operand1.Reg = AREG;
  433. }
  434. DISPATCHCOMMON(push_cx)
  435. {
  436. Instr->Operation = OPNAME(Push);
  437. Instr->Operand1.Type = OPND_REGVALUE;
  438. Instr->Operand1.Reg = CREG;
  439. }
  440. DISPATCHCOMMON(push_dx)
  441. {
  442. Instr->Operation = OPNAME(Push);
  443. Instr->Operand1.Type = OPND_REGVALUE;
  444. Instr->Operand1.Reg = DREG;
  445. }
  446. DISPATCHCOMMON(push_bx)
  447. {
  448. Instr->Operation = OPNAME(Push);
  449. Instr->Operand1.Type = OPND_REGVALUE;
  450. Instr->Operand1.Reg = BREG;
  451. }
  452. DISPATCHCOMMON(push_sp)
  453. {
  454. Instr->Operation = OPNAME(Push);
  455. Instr->Operand1.Type = OPND_REGVALUE;
  456. Instr->Operand1.Reg = SPREG;
  457. }
  458. DISPATCHCOMMON(push_bp)
  459. {
  460. Instr->Operation = OPNAME(Push);
  461. Instr->Operand1.Type = OPND_REGVALUE;
  462. Instr->Operand1.Reg = BPREG;
  463. }
  464. DISPATCHCOMMON(push_si)
  465. {
  466. Instr->Operation = OPNAME(Push);
  467. Instr->Operand1.Type = OPND_REGVALUE;
  468. Instr->Operand1.Reg = SIREG;
  469. }
  470. DISPATCHCOMMON(push_di)
  471. {
  472. Instr->Operation = OPNAME(Push);
  473. Instr->Operand1.Type = OPND_REGVALUE;
  474. Instr->Operand1.Reg = DIREG;
  475. }
  476. DISPATCHCOMMON(pop_ax)
  477. {
  478. Instr->Operation = OPNAME(Pop);
  479. Instr->Operand1.Type = OPND_REGREF;
  480. Instr->Operand1.Reg = AREG;
  481. }
  482. DISPATCHCOMMON(pop_cx)
  483. {
  484. Instr->Operation = OPNAME(Pop);
  485. Instr->Operand1.Type = OPND_REGREF;
  486. Instr->Operand1.Reg = CREG;
  487. }
  488. DISPATCHCOMMON(pop_dx)
  489. {
  490. Instr->Operation = OPNAME(Pop);
  491. Instr->Operand1.Type = OPND_REGREF;
  492. Instr->Operand1.Reg = DREG;
  493. }
  494. DISPATCHCOMMON(pop_bx)
  495. {
  496. Instr->Operation = OPNAME(Pop);
  497. Instr->Operand1.Type = OPND_REGREF;
  498. Instr->Operand1.Reg = BREG;
  499. }
  500. DISPATCHCOMMON(pop_sp)
  501. {
  502. Instr->Operation = OPNAME(Pop);
  503. Instr->Operand1.Type = OPND_REGREF;
  504. Instr->Operand1.Reg = SPREG;
  505. }
  506. DISPATCHCOMMON(pop_bp)
  507. {
  508. Instr->Operation = OPNAME(Pop);
  509. Instr->Operand1.Type = OPND_REGREF;
  510. Instr->Operand1.Reg = BPREG;
  511. }
  512. DISPATCHCOMMON(pop_si)
  513. {
  514. Instr->Operation = OPNAME(Pop);
  515. Instr->Operand1.Type = OPND_REGREF;
  516. Instr->Operand1.Reg = SIREG;
  517. }
  518. DISPATCHCOMMON(pop_di)
  519. {
  520. Instr->Operation = OPNAME(Pop);
  521. Instr->Operand1.Type = OPND_REGREF;
  522. Instr->Operand1.Reg = DIREG;
  523. }
  524. DISPATCHCOMMON(bound)
  525. {
  526. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  527. Instr->Operation = OPNAME(Bound);
  528. Instr->Operand2.Type = OPND_REGVALUE;
  529. Instr->Size = 1+cbInstr;
  530. }
  531. DISPATCHCOMMON(retn_i)
  532. {
  533. Instr->Operation = OPNAME(CTRL_INDIR_Retn_i);
  534. Instr->Operand1.Type = OPND_IMM;
  535. Instr->Operand1.Immed = (DWORD)GET_SHORT(eipTemp+1);
  536. Instr->Size = 3;
  537. }
  538. DISPATCHCOMMON(retn)
  539. {
  540. Instr->Operation = OPNAME(CTRL_INDIR_Retn);
  541. }
  542. DISPATCHCOMMON(retf_i)
  543. {
  544. Instr->Operation = OPNAME(CTRL_INDIR_Retf_i);
  545. Instr->Operand1.Type = OPND_IMM;
  546. Instr->Operand1.Immed = (DWORD)GET_SHORT(eipTemp+1);
  547. Instr->Size = 3;
  548. }
  549. DISPATCHCOMMON(retf)
  550. {
  551. Instr->Operation = OPNAME(CTRL_INDIR_Retf);
  552. }
  553. DISPATCHCOMMON(enter)
  554. {
  555. Instr->Operation = OPNAME(Enter);
  556. Instr->Operand1.Type = OPND_IMM;
  557. Instr->Operand1.Immed = GET_BYTE(eipTemp+3); // Nesting Level
  558. Instr->Operand2.Type = OPND_IMM;
  559. Instr->Operand2.Immed = GET_SHORT(eipTemp+1); // Stack bytes to alloc
  560. Instr->Size = 4;
  561. }
  562. DISPATCHCOMMON(leave)
  563. {
  564. Instr->Operation = OPNAME(Leave);
  565. }
  566. //-------- double-byte functions -----------------------------------------------
  567. DISPATCHCOMMON(GROUP_8)
  568. {
  569. BYTE g = GET_BYTE(eipTemp+1);
  570. int cbInstr;
  571. switch ((g >> 3) & 0x07) {
  572. case 0: // bad
  573. case 1: // bad
  574. case 2: // bad
  575. case 3: // bad
  576. BAD_INSTR;
  577. break;
  578. case 4: // bt modrmw immb
  579. // Note: the difference between the Reg and Mem version of the btx
  580. // fragments is that the Reg version completely ignores any bits in the
  581. // second operand beyond the fifth bit. In contrast, the Mem version uses
  582. // them together with the first operand to determine the memory address.
  583. // When the second operand is an immediate, the correct thing to do is to
  584. // ignore them, and so we call the Reg version all the time.
  585. cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  586. Instr->Operation = OPNAME(BtReg);
  587. Instr->Operand2.Type = OPND_IMM;
  588. Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1);
  589. Instr->Size = cbInstr+3;
  590. break;
  591. case 5: // bts modrmw immb
  592. cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  593. Instr->Operation = OPNAME(BtsReg);
  594. Instr->Operand2.Type = OPND_IMM;
  595. Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1);
  596. Instr->Size = cbInstr+3;
  597. break;
  598. case 6: // btr modrmw immb
  599. cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  600. Instr->Operation = OPNAME(BtrReg);
  601. Instr->Operand2.Type = OPND_IMM;
  602. Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1);
  603. Instr->Size = cbInstr+3;
  604. break;
  605. case 7: // btc modrmw immb
  606. cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  607. Instr->Operation = OPNAME(BtcReg);
  608. Instr->Operand2.Type = OPND_IMM;
  609. Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1);
  610. Instr->Size = cbInstr+3;
  611. break;
  612. }
  613. }
  614. DISPATCHCOMMON(LOCKGROUP_8)
  615. {
  616. BYTE g = GET_BYTE(eipTemp+1);
  617. int cbInstr;
  618. switch ((g >> 3) & 0x07) {
  619. case 0: // bad
  620. case 1: // bad
  621. case 2: // bad
  622. case 3: // bad
  623. case 4: // bt modrmw immb
  624. BAD_INSTR;
  625. break;
  626. case 5: // bts modrmw immb
  627. cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  628. Instr->Operation = LOCKOPNAME(BtsReg);
  629. Instr->Operand2.Type = OPND_IMM;
  630. Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1);
  631. Instr->Size = cbInstr+3;
  632. break;
  633. case 6: // btr modrmw immb
  634. cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  635. Instr->Operation = LOCKOPNAME(BtrReg);
  636. Instr->Operand2.Type = OPND_IMM;
  637. Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1);
  638. Instr->Size = cbInstr+3;
  639. break;
  640. case 7: // btc modrmw immb
  641. cbInstr = MOD_RM(State, &Instr->Operand1, NULL);
  642. Instr->Operation = LOCKOPNAME(BtcReg);
  643. Instr->Operand2.Type = OPND_IMM;
  644. Instr->Operand2.Immed = GET_BYTE(eipTemp+cbInstr+1);
  645. Instr->Size = cbInstr+3;
  646. break;
  647. }
  648. }
  649. DISPATCHCOMMON(movzx_regw_modrmb)
  650. {
  651. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  652. Instr->Operation = OPNAME(Movzx8To);
  653. Instr->Operand2.Type = OPND_NOCODEGEN;
  654. Instr->Operand2.Reg = GET_REG(eipTemp+1);
  655. DEREF8(Instr->Operand1);
  656. Instr->Size = 2+cbInstr;
  657. }
  658. DISPATCHCOMMON(movsx_regw_modrmb)
  659. {
  660. int cbInstr = mod_rm_reg8(State, &Instr->Operand1, NULL);
  661. Instr->Operation = OPNAME(Movsx8To);
  662. Instr->Operand2.Type = OPND_NOCODEGEN;
  663. Instr->Operand2.Reg = GET_REG(eipTemp+1);
  664. DEREF8(Instr->Operand1);
  665. Instr->Size = 2+cbInstr;
  666. }
  667. DISPATCHCOMMON(les_rw_mw)
  668. {
  669. if ((GET_BYTE(eipTemp+1) & 0xc7) == 0xc4) {
  670. //
  671. // BOP instruction
  672. //
  673. PBOPINSTR Bop = (PBOPINSTR)eipTemp;
  674. Instr->Size = sizeof(BOPINSTR);
  675. if (Bop->BopNum == 0xfe) {
  676. //
  677. // BOP FE - Unsimulate
  678. //
  679. Instr->Operation = OP_Unsimulate;
  680. } else {
  681. //
  682. // Generate a BOP.
  683. //
  684. if (Bop->Flags & BOPFL_ENDCODE) {
  685. //
  686. // This BOP is flagged as being the end of Intel code.
  687. // This is typically BOP FD in x86-to-Risc callbacks.
  688. //
  689. Instr->Operation = OP_BOP_STOP_DECODE;
  690. } else {
  691. Instr->Operation = OP_BOP;
  692. }
  693. }
  694. } else {
  695. int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
  696. Instr->Operation = OPNAME(Les);
  697. Instr->Size = 1+cbInstr;
  698. }
  699. }
  700. DISPATCHCOMMON(lds_rw_mw)
  701. {
  702. int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
  703. Instr->Operation = OPNAME(Lds);
  704. Instr->Size = 1+cbInstr;
  705. }
  706. DISPATCHCOMMON(lss_rw_mw)
  707. {
  708. int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
  709. Instr->Operation = OPNAME(Lss);
  710. Instr->Size = 2+cbInstr;
  711. }
  712. DISPATCHCOMMON(lfs_rw_mw)
  713. {
  714. int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
  715. Instr->Operation = OPNAME(Lfs);
  716. Instr->Size = 2+cbInstr;
  717. }
  718. DISPATCHCOMMON(lgs_rw_mw)
  719. {
  720. int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
  721. Instr->Operation = OPNAME(Lgs);
  722. Instr->Size = 2+cbInstr;
  723. }
  724. DISPATCHCOMMON(bts_m_r)
  725. {
  726. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  727. DEREF(Instr->Operand2);
  728. if (Instr->Operand1.Type == OPND_REGREF){
  729. Instr->Operation = OPNAME(BtsReg);
  730. } else {
  731. Instr->Operation = OPNAME(BtsMem);
  732. }
  733. Instr->Size = 2+cbInstr;
  734. }
  735. DISPATCHCOMMON(btr_m_r)
  736. {
  737. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  738. DEREF(Instr->Operand2);
  739. if (Instr->Operand1.Type == OPND_REGREF){
  740. Instr->Operation = OPNAME(BtrReg);
  741. } else {
  742. Instr->Operation = OPNAME(BtrMem);
  743. }
  744. Instr->Size = 2+cbInstr;
  745. }
  746. DISPATCHCOMMON(btc_m_r)
  747. {
  748. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  749. DEREF(Instr->Operand2);
  750. if (Instr->Operand1.Type == OPND_REGREF){
  751. Instr->Operation = OPNAME(BtcReg);
  752. } else {
  753. Instr->Operation = OPNAME(BtcMem);
  754. }
  755. Instr->Size = 2+cbInstr;
  756. }
  757. DISPATCHCOMMON(LOCKbts_m_r)
  758. {
  759. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  760. DEREF(Instr->Operand2);
  761. if (Instr->Operand1.Type == OPND_REGREF){
  762. BAD_INSTR;
  763. } else {
  764. Instr->Operation = LOCKOPNAME(BtsMem);
  765. }
  766. Instr->Size = 2+cbInstr;
  767. }
  768. DISPATCHCOMMON(LOCKbtr_m_r)
  769. {
  770. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  771. DEREF(Instr->Operand2);
  772. if (Instr->Operand1.Type == OPND_REGREF){
  773. BAD_INSTR;
  774. } else {
  775. Instr->Operation = LOCKOPNAME(BtrMem);
  776. }
  777. Instr->Size = 2+cbInstr;
  778. }
  779. DISPATCHCOMMON(LOCKbtc_m_r)
  780. {
  781. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  782. DEREF(Instr->Operand2);
  783. if (Instr->Operand1.Type == OPND_REGREF){
  784. BAD_INSTR;
  785. } else {
  786. Instr->Operation = LOCKOPNAME(BtcMem);
  787. }
  788. Instr->Size = 2+cbInstr;
  789. }
  790. DISPATCHCOMMON(bt_m_r)
  791. {
  792. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  793. DEREF(Instr->Operand2);
  794. if (Instr->Operand1.Type == OPND_REGREF){
  795. Instr->Operation = OPNAME(BtReg);
  796. } else {
  797. Instr->Operation = OPNAME(BtMem);
  798. }
  799. Instr->Size = 2+cbInstr;
  800. }
  801. DISPATCHCOMMON(call_rel)
  802. {
  803. Instr->Operation = OP_CTRL_UNCOND_Call;
  804. Instr->Operand1.Type = OPND_IMM;
  805. Instr->Operand1.Immed = (STYPE)GET_VAL(eipTemp+1) + sizeof(UTYPE) + 1 + eipTemp;
  806. Instr->Operand2.Type = OPND_IMM;
  807. Instr->Operand2.Immed = eipTemp + sizeof(UTYPE) + 1;
  808. Instr->Size = sizeof(UTYPE) + 1;
  809. }
  810. DISPATCHCOMMON(jmp_rel)
  811. {
  812. Instr->Operand1.Type = OPND_NOCODEGEN;
  813. if (State->AdrPrefix) {
  814. short IP;
  815. // get the 16-bit loword from the 32-bit immediate value following
  816. // the JMP instruction, and add that value to the loword of EIP, and
  817. // use that value as the new IP register.
  818. IP = (short)GET_SHORT(eipTemp+1) +
  819. sizeof(UTYPE) + 1 + (short)LOWORD(eipTemp);
  820. Instr->Operand1.Immed = MAKELONG(IP, HIWORD(eipTemp));
  821. #if DBG
  822. State->AdrPrefix = FALSE;
  823. #endif
  824. } else {
  825. Instr->Operand1.Immed = (STYPE)GET_VAL(eipTemp+1) +
  826. sizeof(UTYPE) + 1 + eipTemp;
  827. }
  828. if (Instr->Operand1.Immed > eipTemp) {
  829. Instr->Operation = OP_CTRL_UNCOND_JmpFwd;
  830. } else {
  831. Instr->Operation = OP_CTRL_UNCOND_Jmp;
  832. }
  833. Instr->Size = sizeof(UTYPE) + 1;
  834. }
  835. DISPATCHCOMMON(shld_regw_modrmw_immb)
  836. {
  837. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  838. Instr->Operation = OPNAME(Shld);
  839. DEREF(Instr->Operand2);
  840. Instr->Operand3.Type = OPND_IMM;
  841. Instr->Operand3.Immed = GET_BYTE(eipTemp+cbInstr+1);
  842. Instr->Size = 3+cbInstr;
  843. }
  844. DISPATCHCOMMON(shld_regw_modrmw_cl)
  845. {
  846. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  847. Instr->Operation = OPNAME(Shld);
  848. DEREF(Instr->Operand2);
  849. Instr->Operand3.Type = OPND_REGVALUE;
  850. Instr->Operand3.Reg = GP_CL;
  851. Instr->Size = 2+cbInstr;
  852. }
  853. DISPATCHCOMMON(shrd_regw_modrmw_immb)
  854. {
  855. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  856. Instr->Operation = OPNAME(Shrd);
  857. DEREF(Instr->Operand2);
  858. Instr->Operand3.Type = OPND_IMM;
  859. Instr->Operand3.Immed = GET_BYTE(eipTemp+cbInstr+1);
  860. Instr->Size = 3+cbInstr;
  861. }
  862. DISPATCHCOMMON(shrd_regw_modrmw_cl)
  863. {
  864. int cbInstr = MOD_RM(State, &Instr->Operand1, &Instr->Operand2);
  865. Instr->Operation = OPNAME(Shrd);
  866. DEREF(Instr->Operand2);
  867. Instr->Operand3.Type = OPND_REGVALUE;
  868. Instr->Operand3.Reg = GP_CL;
  869. Instr->Size = 2+cbInstr;
  870. }
  871. DISPATCHCOMMON(bsr_modrmw_regw)
  872. {
  873. int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
  874. Instr->Operation = OPNAME(Bsr);
  875. DEREF(Instr->Operand2);
  876. Instr->Size = 2+cbInstr;
  877. }
  878. DISPATCHCOMMON(bsf_modrmw_regw)
  879. {
  880. int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
  881. Instr->Operation = OPNAME(Bsf);
  882. DEREF(Instr->Operand2);
  883. Instr->Size = 2+cbInstr;
  884. }
  885. DISPATCHCOMMON(lar)
  886. {
  887. int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
  888. Instr->Operation = OPNAME(Lar);
  889. DEREF(Instr->Operand2);
  890. Instr->Size = 2+cbInstr;
  891. }
  892. DISPATCHCOMMON(lsl)
  893. {
  894. int cbInstr = MOD_RM(State, &Instr->Operand2, &Instr->Operand1);
  895. Instr->Operation = OPNAME(Lsl);
  896. DEREF(Instr->Operand2);
  897. Instr->Size = 2+cbInstr;
  898. }