ops2.c 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769
  1. /****************************************************************************
  2. *
  3. * Realmode X86 Emulator Library
  4. *
  5. * Copyright (C) 2007 Freescale Semiconductor, Inc.
  6. * Jason Jin <Jason.jin@freescale.com>
  7. *
  8. * Copyright (C) 1991-2004 SciTech Software, Inc.
  9. * Copyright (C) David Mosberger-Tang
  10. * Copyright (C) 1999 Egbert Eich
  11. *
  12. * ========================================================================
  13. *
  14. * Permission to use, copy, modify, distribute, and sell this software and
  15. * its documentation for any purpose is hereby granted without fee,
  16. * provided that the above copyright notice appear in all copies and that
  17. * both that copyright notice and this permission notice appear in
  18. * supporting documentation, and that the name of the authors not be used
  19. * in advertising or publicity pertaining to distribution of the software
  20. * without specific, written prior permission. The authors makes no
  21. * representations about the suitability of this software for any purpose.
  22. * It is provided "as is" without express or implied warranty.
  23. *
  24. * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  25. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  26. * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  27. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  28. * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  29. * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  30. * PERFORMANCE OF THIS SOFTWARE.
  31. *
  32. * ========================================================================
  33. *
  34. * Language: ANSI C
  35. * Environment: Any
  36. * Developer: Kendall Bennett
  37. *
  38. * Description: This file includes subroutines to implement the decoding
  39. * and emulation of all the x86 extended two-byte processor
  40. * instructions.
  41. *
  42. ****************************************************************************/
  43. #include <common.h>
  44. #include <linux/compiler.h>
  45. #include "x86emu/x86emui.h"
  46. /*----------------------------- Implementation ----------------------------*/
  47. /****************************************************************************
  48. PARAMETERS:
  49. op1 - Instruction op code
  50. REMARKS:
  51. Handles illegal opcodes.
  52. ****************************************************************************/
  53. void x86emuOp2_illegal_op(
  54. u8 op2)
  55. {
  56. START_OF_INSTR();
  57. ERR_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
  58. TRACE_REGS();
  59. printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
  60. M.x86.R_CS, M.x86.R_IP-2,op2);
  61. HALT_SYS();
  62. END_OF_INSTR();
  63. }
  64. #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
  65. /****************************************************************************
  66. REMARKS:
  67. Handles opcode 0x0f,0x80-0x8F
  68. ****************************************************************************/
  69. int x86emu_check_jump_condition(u8 op)
  70. {
  71. switch (op) {
  72. case 0x0:
  73. DECODE_PRINTF("JO\t");
  74. return ACCESS_FLAG(F_OF);
  75. case 0x1:
  76. DECODE_PRINTF("JNO\t");
  77. return !ACCESS_FLAG(F_OF);
  78. break;
  79. case 0x2:
  80. DECODE_PRINTF("JB\t");
  81. return ACCESS_FLAG(F_CF);
  82. break;
  83. case 0x3:
  84. DECODE_PRINTF("JNB\t");
  85. return !ACCESS_FLAG(F_CF);
  86. break;
  87. case 0x4:
  88. DECODE_PRINTF("JZ\t");
  89. return ACCESS_FLAG(F_ZF);
  90. break;
  91. case 0x5:
  92. DECODE_PRINTF("JNZ\t");
  93. return !ACCESS_FLAG(F_ZF);
  94. break;
  95. case 0x6:
  96. DECODE_PRINTF("JBE\t");
  97. return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
  98. break;
  99. case 0x7:
  100. DECODE_PRINTF("JNBE\t");
  101. return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
  102. break;
  103. case 0x8:
  104. DECODE_PRINTF("JS\t");
  105. return ACCESS_FLAG(F_SF);
  106. break;
  107. case 0x9:
  108. DECODE_PRINTF("JNS\t");
  109. return !ACCESS_FLAG(F_SF);
  110. break;
  111. case 0xa:
  112. DECODE_PRINTF("JP\t");
  113. return ACCESS_FLAG(F_PF);
  114. break;
  115. case 0xb:
  116. DECODE_PRINTF("JNP\t");
  117. return !ACCESS_FLAG(F_PF);
  118. break;
  119. case 0xc:
  120. DECODE_PRINTF("JL\t");
  121. return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
  122. break;
  123. case 0xd:
  124. DECODE_PRINTF("JNL\t");
  125. return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
  126. break;
  127. case 0xe:
  128. DECODE_PRINTF("JLE\t");
  129. return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
  130. ACCESS_FLAG(F_ZF));
  131. break;
  132. default:
  133. DECODE_PRINTF("JNLE\t");
  134. return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
  135. ACCESS_FLAG(F_ZF));
  136. }
  137. }
  138. void x86emuOp2_long_jump(u8 op2)
  139. {
  140. s32 target;
  141. int cond;
  142. /* conditional jump to word offset. */
  143. START_OF_INSTR();
  144. cond = x86emu_check_jump_condition(op2 & 0xF);
  145. target = (s16) fetch_word_imm();
  146. target += (s16) M.x86.R_IP;
  147. DECODE_PRINTF2("%04x\n", target);
  148. TRACE_AND_STEP();
  149. if (cond)
  150. M.x86.R_IP = (u16)target;
  151. DECODE_CLEAR_SEGOVR();
  152. END_OF_INSTR();
  153. }
  154. /****************************************************************************
  155. REMARKS:
  156. Handles opcode 0x0f,0x90-0x9F
  157. ****************************************************************************/
  158. void x86emuOp2_set_byte(u8 op2)
  159. {
  160. int mod, rl, rh;
  161. uint destoffset;
  162. u8 *destreg;
  163. __maybe_unused char *name = 0;
  164. int cond = 0;
  165. START_OF_INSTR();
  166. switch (op2) {
  167. case 0x90:
  168. name = "SETO\t";
  169. cond = ACCESS_FLAG(F_OF);
  170. break;
  171. case 0x91:
  172. name = "SETNO\t";
  173. cond = !ACCESS_FLAG(F_OF);
  174. break;
  175. case 0x92:
  176. name = "SETB\t";
  177. cond = ACCESS_FLAG(F_CF);
  178. break;
  179. case 0x93:
  180. name = "SETNB\t";
  181. cond = !ACCESS_FLAG(F_CF);
  182. break;
  183. case 0x94:
  184. name = "SETZ\t";
  185. cond = ACCESS_FLAG(F_ZF);
  186. break;
  187. case 0x95:
  188. name = "SETNZ\t";
  189. cond = !ACCESS_FLAG(F_ZF);
  190. break;
  191. case 0x96:
  192. name = "SETBE\t";
  193. cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
  194. break;
  195. case 0x97:
  196. name = "SETNBE\t";
  197. cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
  198. break;
  199. case 0x98:
  200. name = "SETS\t";
  201. cond = ACCESS_FLAG(F_SF);
  202. break;
  203. case 0x99:
  204. name = "SETNS\t";
  205. cond = !ACCESS_FLAG(F_SF);
  206. break;
  207. case 0x9a:
  208. name = "SETP\t";
  209. cond = ACCESS_FLAG(F_PF);
  210. break;
  211. case 0x9b:
  212. name = "SETNP\t";
  213. cond = !ACCESS_FLAG(F_PF);
  214. break;
  215. case 0x9c:
  216. name = "SETL\t";
  217. cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
  218. break;
  219. case 0x9d:
  220. name = "SETNL\t";
  221. cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
  222. break;
  223. case 0x9e:
  224. name = "SETLE\t";
  225. cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
  226. ACCESS_FLAG(F_ZF));
  227. break;
  228. case 0x9f:
  229. name = "SETNLE\t";
  230. cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
  231. ACCESS_FLAG(F_ZF));
  232. break;
  233. }
  234. DECODE_PRINTF(name);
  235. FETCH_DECODE_MODRM(mod, rh, rl);
  236. if (mod < 3) {
  237. destoffset = decode_rmXX_address(mod, rl);
  238. TRACE_AND_STEP();
  239. store_data_byte(destoffset, cond ? 0x01 : 0x00);
  240. } else { /* register to register */
  241. destreg = DECODE_RM_BYTE_REGISTER(rl);
  242. TRACE_AND_STEP();
  243. *destreg = cond ? 0x01 : 0x00;
  244. }
  245. DECODE_CLEAR_SEGOVR();
  246. END_OF_INSTR();
  247. }
  248. /****************************************************************************
  249. REMARKS:
  250. Handles opcode 0x0f,0xa0
  251. ****************************************************************************/
  252. void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
  253. {
  254. START_OF_INSTR();
  255. DECODE_PRINTF("PUSH\tFS\n");
  256. TRACE_AND_STEP();
  257. push_word(M.x86.R_FS);
  258. DECODE_CLEAR_SEGOVR();
  259. END_OF_INSTR();
  260. }
  261. /****************************************************************************
  262. REMARKS:
  263. Handles opcode 0x0f,0xa1
  264. ****************************************************************************/
  265. void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
  266. {
  267. START_OF_INSTR();
  268. DECODE_PRINTF("POP\tFS\n");
  269. TRACE_AND_STEP();
  270. M.x86.R_FS = pop_word();
  271. DECODE_CLEAR_SEGOVR();
  272. END_OF_INSTR();
  273. }
  274. /****************************************************************************
  275. REMARKS:
  276. Handles opcode 0x0f,0xa3
  277. ****************************************************************************/
  278. void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
  279. {
  280. int mod, rl, rh;
  281. uint srcoffset;
  282. int bit,disp;
  283. START_OF_INSTR();
  284. DECODE_PRINTF("BT\t");
  285. FETCH_DECODE_MODRM(mod, rh, rl);
  286. if (mod < 3) {
  287. srcoffset = decode_rmXX_address(mod, rl);
  288. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  289. u32 srcval;
  290. u32 *shiftreg;
  291. DECODE_PRINTF(",");
  292. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  293. TRACE_AND_STEP();
  294. bit = *shiftreg & 0x1F;
  295. disp = (s16)*shiftreg >> 5;
  296. srcval = fetch_data_long(srcoffset+disp);
  297. CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
  298. } else {
  299. u16 srcval;
  300. u16 *shiftreg;
  301. DECODE_PRINTF(",");
  302. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  303. TRACE_AND_STEP();
  304. bit = *shiftreg & 0xF;
  305. disp = (s16)*shiftreg >> 4;
  306. srcval = fetch_data_word(srcoffset+disp);
  307. CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
  308. }
  309. } else { /* register to register */
  310. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  311. u32 *srcreg,*shiftreg;
  312. srcreg = DECODE_RM_LONG_REGISTER(rl);
  313. DECODE_PRINTF(",");
  314. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  315. TRACE_AND_STEP();
  316. bit = *shiftreg & 0x1F;
  317. CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
  318. } else {
  319. u16 *srcreg,*shiftreg;
  320. srcreg = DECODE_RM_WORD_REGISTER(rl);
  321. DECODE_PRINTF(",");
  322. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  323. TRACE_AND_STEP();
  324. bit = *shiftreg & 0xF;
  325. CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
  326. }
  327. }
  328. DECODE_CLEAR_SEGOVR();
  329. END_OF_INSTR();
  330. }
  331. /****************************************************************************
  332. REMARKS:
  333. Handles opcode 0x0f,0xa4
  334. ****************************************************************************/
  335. void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
  336. {
  337. int mod, rl, rh;
  338. uint destoffset;
  339. u8 shift;
  340. START_OF_INSTR();
  341. DECODE_PRINTF("SHLD\t");
  342. FETCH_DECODE_MODRM(mod, rh, rl);
  343. if (mod < 3) {
  344. destoffset = decode_rmXX_address(mod, rl);
  345. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  346. u32 destval;
  347. u32 *shiftreg;
  348. DECODE_PRINTF(",");
  349. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  350. DECODE_PRINTF(",");
  351. shift = fetch_byte_imm();
  352. DECODE_PRINTF2("%d\n", shift);
  353. TRACE_AND_STEP();
  354. destval = fetch_data_long(destoffset);
  355. destval = shld_long(destval,*shiftreg,shift);
  356. store_data_long(destoffset, destval);
  357. } else {
  358. u16 destval;
  359. u16 *shiftreg;
  360. DECODE_PRINTF(",");
  361. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  362. DECODE_PRINTF(",");
  363. shift = fetch_byte_imm();
  364. DECODE_PRINTF2("%d\n", shift);
  365. TRACE_AND_STEP();
  366. destval = fetch_data_word(destoffset);
  367. destval = shld_word(destval,*shiftreg,shift);
  368. store_data_word(destoffset, destval);
  369. }
  370. } else { /* register to register */
  371. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  372. u32 *destreg,*shiftreg;
  373. destreg = DECODE_RM_LONG_REGISTER(rl);
  374. DECODE_PRINTF(",");
  375. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  376. DECODE_PRINTF(",");
  377. shift = fetch_byte_imm();
  378. DECODE_PRINTF2("%d\n", shift);
  379. TRACE_AND_STEP();
  380. *destreg = shld_long(*destreg,*shiftreg,shift);
  381. } else {
  382. u16 *destreg,*shiftreg;
  383. destreg = DECODE_RM_WORD_REGISTER(rl);
  384. DECODE_PRINTF(",");
  385. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  386. DECODE_PRINTF(",");
  387. shift = fetch_byte_imm();
  388. DECODE_PRINTF2("%d\n", shift);
  389. TRACE_AND_STEP();
  390. *destreg = shld_word(*destreg,*shiftreg,shift);
  391. }
  392. }
  393. DECODE_CLEAR_SEGOVR();
  394. END_OF_INSTR();
  395. }
  396. /****************************************************************************
  397. REMARKS:
  398. Handles opcode 0x0f,0xa5
  399. ****************************************************************************/
  400. void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
  401. {
  402. int mod, rl, rh;
  403. uint destoffset;
  404. START_OF_INSTR();
  405. DECODE_PRINTF("SHLD\t");
  406. FETCH_DECODE_MODRM(mod, rh, rl);
  407. if (mod < 3) {
  408. destoffset = decode_rmXX_address(mod, rl);
  409. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  410. u32 destval;
  411. u32 *shiftreg;
  412. DECODE_PRINTF(",");
  413. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  414. DECODE_PRINTF(",CL\n");
  415. TRACE_AND_STEP();
  416. destval = fetch_data_long(destoffset);
  417. destval = shld_long(destval,*shiftreg,M.x86.R_CL);
  418. store_data_long(destoffset, destval);
  419. } else {
  420. u16 destval;
  421. u16 *shiftreg;
  422. DECODE_PRINTF(",");
  423. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  424. DECODE_PRINTF(",CL\n");
  425. TRACE_AND_STEP();
  426. destval = fetch_data_word(destoffset);
  427. destval = shld_word(destval,*shiftreg,M.x86.R_CL);
  428. store_data_word(destoffset, destval);
  429. }
  430. } else { /* register to register */
  431. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  432. u32 *destreg,*shiftreg;
  433. destreg = DECODE_RM_LONG_REGISTER(rl);
  434. DECODE_PRINTF(",");
  435. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  436. DECODE_PRINTF(",CL\n");
  437. TRACE_AND_STEP();
  438. *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
  439. } else {
  440. u16 *destreg,*shiftreg;
  441. destreg = DECODE_RM_WORD_REGISTER(rl);
  442. DECODE_PRINTF(",");
  443. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  444. DECODE_PRINTF(",CL\n");
  445. TRACE_AND_STEP();
  446. *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
  447. }
  448. }
  449. DECODE_CLEAR_SEGOVR();
  450. END_OF_INSTR();
  451. }
  452. /****************************************************************************
  453. REMARKS:
  454. Handles opcode 0x0f,0xa8
  455. ****************************************************************************/
  456. void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
  457. {
  458. START_OF_INSTR();
  459. DECODE_PRINTF("PUSH\tGS\n");
  460. TRACE_AND_STEP();
  461. push_word(M.x86.R_GS);
  462. DECODE_CLEAR_SEGOVR();
  463. END_OF_INSTR();
  464. }
  465. /****************************************************************************
  466. REMARKS:
  467. Handles opcode 0x0f,0xa9
  468. ****************************************************************************/
  469. void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
  470. {
  471. START_OF_INSTR();
  472. DECODE_PRINTF("POP\tGS\n");
  473. TRACE_AND_STEP();
  474. M.x86.R_GS = pop_word();
  475. DECODE_CLEAR_SEGOVR();
  476. END_OF_INSTR();
  477. }
  478. /****************************************************************************
  479. REMARKS:
  480. Handles opcode 0x0f,0xaa
  481. ****************************************************************************/
  482. void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
  483. {
  484. int mod, rl, rh;
  485. uint srcoffset;
  486. int bit,disp;
  487. START_OF_INSTR();
  488. DECODE_PRINTF("BTS\t");
  489. FETCH_DECODE_MODRM(mod, rh, rl);
  490. if (mod < 3) {
  491. srcoffset = decode_rmXX_address(mod, rl);
  492. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  493. u32 srcval,mask;
  494. u32 *shiftreg;
  495. DECODE_PRINTF(",");
  496. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  497. TRACE_AND_STEP();
  498. bit = *shiftreg & 0x1F;
  499. disp = (s16)*shiftreg >> 5;
  500. srcval = fetch_data_long(srcoffset+disp);
  501. mask = (0x1 << bit);
  502. CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
  503. store_data_long(srcoffset+disp, srcval | mask);
  504. } else {
  505. u16 srcval,mask;
  506. u16 *shiftreg;
  507. DECODE_PRINTF(",");
  508. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  509. TRACE_AND_STEP();
  510. bit = *shiftreg & 0xF;
  511. disp = (s16)*shiftreg >> 4;
  512. srcval = fetch_data_word(srcoffset+disp);
  513. mask = (u16)(0x1 << bit);
  514. CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
  515. store_data_word(srcoffset+disp, srcval | mask);
  516. }
  517. } else { /* register to register */
  518. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  519. u32 *srcreg,*shiftreg;
  520. u32 mask;
  521. srcreg = DECODE_RM_LONG_REGISTER(rl);
  522. DECODE_PRINTF(",");
  523. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  524. TRACE_AND_STEP();
  525. bit = *shiftreg & 0x1F;
  526. mask = (0x1 << bit);
  527. CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
  528. *srcreg |= mask;
  529. } else {
  530. u16 *srcreg,*shiftreg;
  531. u16 mask;
  532. srcreg = DECODE_RM_WORD_REGISTER(rl);
  533. DECODE_PRINTF(",");
  534. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  535. TRACE_AND_STEP();
  536. bit = *shiftreg & 0xF;
  537. mask = (u16)(0x1 << bit);
  538. CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
  539. *srcreg |= mask;
  540. }
  541. }
  542. DECODE_CLEAR_SEGOVR();
  543. END_OF_INSTR();
  544. }
  545. /****************************************************************************
  546. REMARKS:
  547. Handles opcode 0x0f,0xac
  548. ****************************************************************************/
  549. void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
  550. {
  551. int mod, rl, rh;
  552. uint destoffset;
  553. u8 shift;
  554. START_OF_INSTR();
  555. DECODE_PRINTF("SHLD\t");
  556. FETCH_DECODE_MODRM(mod, rh, rl);
  557. if (mod < 3) {
  558. destoffset = decode_rmXX_address(mod, rl);
  559. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  560. u32 destval;
  561. u32 *shiftreg;
  562. DECODE_PRINTF(",");
  563. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  564. DECODE_PRINTF(",");
  565. shift = fetch_byte_imm();
  566. DECODE_PRINTF2("%d\n", shift);
  567. TRACE_AND_STEP();
  568. destval = fetch_data_long(destoffset);
  569. destval = shrd_long(destval,*shiftreg,shift);
  570. store_data_long(destoffset, destval);
  571. } else {
  572. u16 destval;
  573. u16 *shiftreg;
  574. DECODE_PRINTF(",");
  575. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  576. DECODE_PRINTF(",");
  577. shift = fetch_byte_imm();
  578. DECODE_PRINTF2("%d\n", shift);
  579. TRACE_AND_STEP();
  580. destval = fetch_data_word(destoffset);
  581. destval = shrd_word(destval,*shiftreg,shift);
  582. store_data_word(destoffset, destval);
  583. }
  584. } else { /* register to register */
  585. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  586. u32 *destreg,*shiftreg;
  587. destreg = DECODE_RM_LONG_REGISTER(rl);
  588. DECODE_PRINTF(",");
  589. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  590. DECODE_PRINTF(",");
  591. shift = fetch_byte_imm();
  592. DECODE_PRINTF2("%d\n", shift);
  593. TRACE_AND_STEP();
  594. *destreg = shrd_long(*destreg,*shiftreg,shift);
  595. } else {
  596. u16 *destreg,*shiftreg;
  597. destreg = DECODE_RM_WORD_REGISTER(rl);
  598. DECODE_PRINTF(",");
  599. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  600. DECODE_PRINTF(",");
  601. shift = fetch_byte_imm();
  602. DECODE_PRINTF2("%d\n", shift);
  603. TRACE_AND_STEP();
  604. *destreg = shrd_word(*destreg,*shiftreg,shift);
  605. }
  606. }
  607. DECODE_CLEAR_SEGOVR();
  608. END_OF_INSTR();
  609. }
  610. /****************************************************************************
  611. REMARKS:
  612. Handles opcode 0x0f,0xad
  613. ****************************************************************************/
  614. void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
  615. {
  616. int mod, rl, rh;
  617. uint destoffset;
  618. START_OF_INSTR();
  619. DECODE_PRINTF("SHLD\t");
  620. FETCH_DECODE_MODRM(mod, rh, rl);
  621. if (mod < 3) {
  622. destoffset = decode_rmXX_address(mod, rl);
  623. DECODE_PRINTF(",");
  624. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  625. u32 destval;
  626. u32 *shiftreg;
  627. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  628. DECODE_PRINTF(",CL\n");
  629. TRACE_AND_STEP();
  630. destval = fetch_data_long(destoffset);
  631. destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
  632. store_data_long(destoffset, destval);
  633. } else {
  634. u16 destval;
  635. u16 *shiftreg;
  636. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  637. DECODE_PRINTF(",CL\n");
  638. TRACE_AND_STEP();
  639. destval = fetch_data_word(destoffset);
  640. destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
  641. store_data_word(destoffset, destval);
  642. }
  643. } else { /* register to register */
  644. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  645. u32 *destreg,*shiftreg;
  646. destreg = DECODE_RM_LONG_REGISTER(rl);
  647. DECODE_PRINTF(",");
  648. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  649. DECODE_PRINTF(",CL\n");
  650. TRACE_AND_STEP();
  651. *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
  652. } else {
  653. u16 *destreg,*shiftreg;
  654. destreg = DECODE_RM_WORD_REGISTER(rl);
  655. DECODE_PRINTF(",");
  656. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  657. DECODE_PRINTF(",CL\n");
  658. TRACE_AND_STEP();
  659. *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
  660. }
  661. }
  662. DECODE_CLEAR_SEGOVR();
  663. END_OF_INSTR();
  664. }
  665. /****************************************************************************
  666. REMARKS:
  667. Handles opcode 0x0f,0xaf
  668. ****************************************************************************/
  669. void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
  670. {
  671. int mod, rl, rh;
  672. uint srcoffset;
  673. START_OF_INSTR();
  674. DECODE_PRINTF("IMUL\t");
  675. FETCH_DECODE_MODRM(mod, rh, rl);
  676. if (mod < 3) {
  677. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  678. u32 *destreg;
  679. u32 srcval;
  680. u32 res_lo,res_hi;
  681. destreg = DECODE_RM_LONG_REGISTER(rh);
  682. DECODE_PRINTF(",");
  683. srcoffset = decode_rmXX_address(mod, rl);
  684. srcval = fetch_data_long(srcoffset);
  685. TRACE_AND_STEP();
  686. imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
  687. if (res_hi != 0) {
  688. SET_FLAG(F_CF);
  689. SET_FLAG(F_OF);
  690. } else {
  691. CLEAR_FLAG(F_CF);
  692. CLEAR_FLAG(F_OF);
  693. }
  694. *destreg = (u32)res_lo;
  695. } else {
  696. u16 *destreg;
  697. u16 srcval;
  698. u32 res;
  699. destreg = DECODE_RM_WORD_REGISTER(rh);
  700. DECODE_PRINTF(",");
  701. srcoffset = decode_rmXX_address(mod, rl);
  702. srcval = fetch_data_word(srcoffset);
  703. TRACE_AND_STEP();
  704. res = (s16)*destreg * (s16)srcval;
  705. if (res > 0xFFFF) {
  706. SET_FLAG(F_CF);
  707. SET_FLAG(F_OF);
  708. } else {
  709. CLEAR_FLAG(F_CF);
  710. CLEAR_FLAG(F_OF);
  711. }
  712. *destreg = (u16)res;
  713. }
  714. } else { /* register to register */
  715. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  716. u32 *destreg,*srcreg;
  717. u32 res_lo,res_hi;
  718. destreg = DECODE_RM_LONG_REGISTER(rh);
  719. DECODE_PRINTF(",");
  720. srcreg = DECODE_RM_LONG_REGISTER(rl);
  721. TRACE_AND_STEP();
  722. imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
  723. if (res_hi != 0) {
  724. SET_FLAG(F_CF);
  725. SET_FLAG(F_OF);
  726. } else {
  727. CLEAR_FLAG(F_CF);
  728. CLEAR_FLAG(F_OF);
  729. }
  730. *destreg = (u32)res_lo;
  731. } else {
  732. u16 *destreg,*srcreg;
  733. u32 res;
  734. destreg = DECODE_RM_WORD_REGISTER(rh);
  735. DECODE_PRINTF(",");
  736. srcreg = DECODE_RM_WORD_REGISTER(rl);
  737. res = (s16)*destreg * (s16)*srcreg;
  738. if (res > 0xFFFF) {
  739. SET_FLAG(F_CF);
  740. SET_FLAG(F_OF);
  741. } else {
  742. CLEAR_FLAG(F_CF);
  743. CLEAR_FLAG(F_OF);
  744. }
  745. *destreg = (u16)res;
  746. }
  747. }
  748. DECODE_CLEAR_SEGOVR();
  749. END_OF_INSTR();
  750. }
  751. /****************************************************************************
  752. REMARKS:
  753. Handles opcode 0x0f,0xb2
  754. ****************************************************************************/
  755. void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
  756. {
  757. int mod, rh, rl;
  758. u16 *dstreg;
  759. uint srcoffset;
  760. START_OF_INSTR();
  761. DECODE_PRINTF("LSS\t");
  762. FETCH_DECODE_MODRM(mod, rh, rl);
  763. if (mod < 3) {
  764. dstreg = DECODE_RM_WORD_REGISTER(rh);
  765. DECODE_PRINTF(",");
  766. srcoffset = decode_rmXX_address(mod, rl);
  767. DECODE_PRINTF("\n");
  768. TRACE_AND_STEP();
  769. *dstreg = fetch_data_word(srcoffset);
  770. M.x86.R_SS = fetch_data_word(srcoffset + 2);
  771. } else { /* register to register */
  772. /* UNDEFINED! */
  773. TRACE_AND_STEP();
  774. }
  775. DECODE_CLEAR_SEGOVR();
  776. END_OF_INSTR();
  777. }
  778. /****************************************************************************
  779. REMARKS:
  780. Handles opcode 0x0f,0xb3
  781. ****************************************************************************/
  782. void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
  783. {
  784. int mod, rl, rh;
  785. uint srcoffset;
  786. int bit,disp;
  787. START_OF_INSTR();
  788. DECODE_PRINTF("BTR\t");
  789. FETCH_DECODE_MODRM(mod, rh, rl);
  790. if (mod < 3) {
  791. srcoffset = decode_rmXX_address(mod, rl);
  792. DECODE_PRINTF(",");
  793. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  794. u32 srcval,mask;
  795. u32 *shiftreg;
  796. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  797. TRACE_AND_STEP();
  798. bit = *shiftreg & 0x1F;
  799. disp = (s16)*shiftreg >> 5;
  800. srcval = fetch_data_long(srcoffset+disp);
  801. mask = (0x1 << bit);
  802. CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
  803. store_data_long(srcoffset+disp, srcval & ~mask);
  804. } else {
  805. u16 srcval,mask;
  806. u16 *shiftreg;
  807. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  808. TRACE_AND_STEP();
  809. bit = *shiftreg & 0xF;
  810. disp = (s16)*shiftreg >> 4;
  811. srcval = fetch_data_word(srcoffset+disp);
  812. mask = (u16)(0x1 << bit);
  813. CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
  814. store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
  815. }
  816. } else { /* register to register */
  817. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  818. u32 *srcreg,*shiftreg;
  819. u32 mask;
  820. srcreg = DECODE_RM_LONG_REGISTER(rl);
  821. DECODE_PRINTF(",");
  822. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  823. TRACE_AND_STEP();
  824. bit = *shiftreg & 0x1F;
  825. mask = (0x1 << bit);
  826. CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
  827. *srcreg &= ~mask;
  828. } else {
  829. u16 *srcreg,*shiftreg;
  830. u16 mask;
  831. srcreg = DECODE_RM_WORD_REGISTER(rl);
  832. DECODE_PRINTF(",");
  833. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  834. TRACE_AND_STEP();
  835. bit = *shiftreg & 0xF;
  836. mask = (u16)(0x1 << bit);
  837. CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
  838. *srcreg &= ~mask;
  839. }
  840. }
  841. DECODE_CLEAR_SEGOVR();
  842. END_OF_INSTR();
  843. }
  844. /****************************************************************************
  845. REMARKS:
  846. Handles opcode 0x0f,0xb4
  847. ****************************************************************************/
  848. void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
  849. {
  850. int mod, rh, rl;
  851. u16 *dstreg;
  852. uint srcoffset;
  853. START_OF_INSTR();
  854. DECODE_PRINTF("LFS\t");
  855. FETCH_DECODE_MODRM(mod, rh, rl);
  856. if (mod < 3) {
  857. dstreg = DECODE_RM_WORD_REGISTER(rh);
  858. DECODE_PRINTF(",");
  859. srcoffset = decode_rmXX_address(mod, rl);
  860. DECODE_PRINTF("\n");
  861. TRACE_AND_STEP();
  862. *dstreg = fetch_data_word(srcoffset);
  863. M.x86.R_FS = fetch_data_word(srcoffset + 2);
  864. } else { /* register to register */
  865. /* UNDEFINED! */
  866. TRACE_AND_STEP();
  867. }
  868. DECODE_CLEAR_SEGOVR();
  869. END_OF_INSTR();
  870. }
  871. /****************************************************************************
  872. REMARKS:
  873. Handles opcode 0x0f,0xb5
  874. ****************************************************************************/
  875. void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
  876. {
  877. int mod, rh, rl;
  878. u16 *dstreg;
  879. uint srcoffset;
  880. START_OF_INSTR();
  881. DECODE_PRINTF("LGS\t");
  882. FETCH_DECODE_MODRM(mod, rh, rl);
  883. if (mod < 3) {
  884. dstreg = DECODE_RM_WORD_REGISTER(rh);
  885. DECODE_PRINTF(",");
  886. srcoffset = decode_rmXX_address(mod, rl);
  887. DECODE_PRINTF("\n");
  888. TRACE_AND_STEP();
  889. *dstreg = fetch_data_word(srcoffset);
  890. M.x86.R_GS = fetch_data_word(srcoffset + 2);
  891. } else { /* register to register */
  892. /* UNDEFINED! */
  893. TRACE_AND_STEP();
  894. }
  895. DECODE_CLEAR_SEGOVR();
  896. END_OF_INSTR();
  897. }
  898. /****************************************************************************
  899. REMARKS:
  900. Handles opcode 0x0f,0xb6
  901. ****************************************************************************/
  902. void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
  903. {
  904. int mod, rl, rh;
  905. uint srcoffset;
  906. START_OF_INSTR();
  907. DECODE_PRINTF("MOVZX\t");
  908. FETCH_DECODE_MODRM(mod, rh, rl);
  909. if (mod < 3) {
  910. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  911. u32 *destreg;
  912. u32 srcval;
  913. destreg = DECODE_RM_LONG_REGISTER(rh);
  914. DECODE_PRINTF(",");
  915. srcoffset = decode_rmXX_address(mod, rl);
  916. srcval = fetch_data_byte(srcoffset);
  917. DECODE_PRINTF("\n");
  918. TRACE_AND_STEP();
  919. *destreg = srcval;
  920. } else {
  921. u16 *destreg;
  922. u16 srcval;
  923. destreg = DECODE_RM_WORD_REGISTER(rh);
  924. DECODE_PRINTF(",");
  925. srcoffset = decode_rmXX_address(mod, rl);
  926. srcval = fetch_data_byte(srcoffset);
  927. DECODE_PRINTF("\n");
  928. TRACE_AND_STEP();
  929. *destreg = srcval;
  930. }
  931. } else { /* register to register */
  932. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  933. u32 *destreg;
  934. u8 *srcreg;
  935. destreg = DECODE_RM_LONG_REGISTER(rh);
  936. DECODE_PRINTF(",");
  937. srcreg = DECODE_RM_BYTE_REGISTER(rl);
  938. DECODE_PRINTF("\n");
  939. TRACE_AND_STEP();
  940. *destreg = *srcreg;
  941. } else {
  942. u16 *destreg;
  943. u8 *srcreg;
  944. destreg = DECODE_RM_WORD_REGISTER(rh);
  945. DECODE_PRINTF(",");
  946. srcreg = DECODE_RM_BYTE_REGISTER(rl);
  947. DECODE_PRINTF("\n");
  948. TRACE_AND_STEP();
  949. *destreg = *srcreg;
  950. }
  951. }
  952. DECODE_CLEAR_SEGOVR();
  953. END_OF_INSTR();
  954. }
  955. /****************************************************************************
  956. REMARKS:
  957. Handles opcode 0x0f,0xb7
  958. ****************************************************************************/
  959. void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
  960. {
  961. int mod, rl, rh;
  962. uint srcoffset;
  963. u32 *destreg;
  964. u32 srcval;
  965. u16 *srcreg;
  966. START_OF_INSTR();
  967. DECODE_PRINTF("MOVZX\t");
  968. FETCH_DECODE_MODRM(mod, rh, rl);
  969. if (mod < 3) {
  970. destreg = DECODE_RM_LONG_REGISTER(rh);
  971. DECODE_PRINTF(",");
  972. srcoffset = decode_rmXX_address(mod, rl);
  973. srcval = fetch_data_word(srcoffset);
  974. DECODE_PRINTF("\n");
  975. TRACE_AND_STEP();
  976. *destreg = srcval;
  977. } else { /* register to register */
  978. destreg = DECODE_RM_LONG_REGISTER(rh);
  979. DECODE_PRINTF(",");
  980. srcreg = DECODE_RM_WORD_REGISTER(rl);
  981. DECODE_PRINTF("\n");
  982. TRACE_AND_STEP();
  983. *destreg = *srcreg;
  984. }
  985. DECODE_CLEAR_SEGOVR();
  986. END_OF_INSTR();
  987. }
  988. /****************************************************************************
  989. REMARKS:
  990. Handles opcode 0x0f,0xba
  991. ****************************************************************************/
  992. void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
  993. {
  994. int mod, rl, rh;
  995. uint srcoffset;
  996. u8 shift;
  997. int bit;
  998. START_OF_INSTR();
  999. FETCH_DECODE_MODRM(mod, rh, rl);
  1000. switch (rh) {
  1001. case 4:
  1002. DECODE_PRINTF("BT\t");
  1003. break;
  1004. case 5:
  1005. DECODE_PRINTF("BTS\t");
  1006. break;
  1007. case 6:
  1008. DECODE_PRINTF("BTR\t");
  1009. break;
  1010. case 7:
  1011. DECODE_PRINTF("BTC\t");
  1012. break;
  1013. default:
  1014. ERR_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
  1015. TRACE_REGS();
  1016. printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
  1017. M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
  1018. HALT_SYS();
  1019. }
  1020. if (mod < 3) {
  1021. srcoffset = decode_rmXX_address(mod, rl);
  1022. shift = fetch_byte_imm();
  1023. DECODE_PRINTF2(",%d\n", shift);
  1024. TRACE_AND_STEP();
  1025. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1026. u32 srcval, mask;
  1027. bit = shift & 0x1F;
  1028. srcval = fetch_data_long(srcoffset);
  1029. mask = (0x1 << bit);
  1030. CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
  1031. switch (rh) {
  1032. case 5:
  1033. store_data_long(srcoffset, srcval | mask);
  1034. break;
  1035. case 6:
  1036. store_data_long(srcoffset, srcval & ~mask);
  1037. break;
  1038. case 7:
  1039. store_data_long(srcoffset, srcval ^ mask);
  1040. break;
  1041. default:
  1042. break;
  1043. }
  1044. } else {
  1045. u16 srcval, mask;
  1046. bit = shift & 0xF;
  1047. srcval = fetch_data_word(srcoffset);
  1048. mask = (0x1 << bit);
  1049. CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
  1050. switch (rh) {
  1051. case 5:
  1052. store_data_word(srcoffset, srcval | mask);
  1053. break;
  1054. case 6:
  1055. store_data_word(srcoffset, srcval & ~mask);
  1056. break;
  1057. case 7:
  1058. store_data_word(srcoffset, srcval ^ mask);
  1059. break;
  1060. default:
  1061. break;
  1062. }
  1063. }
  1064. } else { /* register to register */
  1065. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1066. u32 *srcreg;
  1067. u32 mask;
  1068. srcreg = DECODE_RM_LONG_REGISTER(rl);
  1069. shift = fetch_byte_imm();
  1070. DECODE_PRINTF2(",%d\n", shift);
  1071. TRACE_AND_STEP();
  1072. bit = shift & 0x1F;
  1073. mask = (0x1 << bit);
  1074. CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
  1075. switch (rh) {
  1076. case 5:
  1077. *srcreg |= mask;
  1078. break;
  1079. case 6:
  1080. *srcreg &= ~mask;
  1081. break;
  1082. case 7:
  1083. *srcreg ^= mask;
  1084. break;
  1085. default:
  1086. break;
  1087. }
  1088. } else {
  1089. u16 *srcreg;
  1090. u16 mask;
  1091. srcreg = DECODE_RM_WORD_REGISTER(rl);
  1092. shift = fetch_byte_imm();
  1093. DECODE_PRINTF2(",%d\n", shift);
  1094. TRACE_AND_STEP();
  1095. bit = shift & 0xF;
  1096. mask = (0x1 << bit);
  1097. CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
  1098. switch (rh) {
  1099. case 5:
  1100. *srcreg |= mask;
  1101. break;
  1102. case 6:
  1103. *srcreg &= ~mask;
  1104. break;
  1105. case 7:
  1106. *srcreg ^= mask;
  1107. break;
  1108. default:
  1109. break;
  1110. }
  1111. }
  1112. }
  1113. DECODE_CLEAR_SEGOVR();
  1114. END_OF_INSTR();
  1115. }
  1116. /****************************************************************************
  1117. REMARKS:
  1118. Handles opcode 0x0f,0xbb
  1119. ****************************************************************************/
  1120. void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
  1121. {
  1122. int mod, rl, rh;
  1123. uint srcoffset;
  1124. int bit,disp;
  1125. START_OF_INSTR();
  1126. DECODE_PRINTF("BTC\t");
  1127. FETCH_DECODE_MODRM(mod, rh, rl);
  1128. if (mod < 3) {
  1129. srcoffset = decode_rmXX_address(mod, rl);
  1130. DECODE_PRINTF(",");
  1131. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1132. u32 srcval,mask;
  1133. u32 *shiftreg;
  1134. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  1135. TRACE_AND_STEP();
  1136. bit = *shiftreg & 0x1F;
  1137. disp = (s16)*shiftreg >> 5;
  1138. srcval = fetch_data_long(srcoffset+disp);
  1139. mask = (0x1 << bit);
  1140. CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
  1141. store_data_long(srcoffset+disp, srcval ^ mask);
  1142. } else {
  1143. u16 srcval,mask;
  1144. u16 *shiftreg;
  1145. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  1146. TRACE_AND_STEP();
  1147. bit = *shiftreg & 0xF;
  1148. disp = (s16)*shiftreg >> 4;
  1149. srcval = fetch_data_word(srcoffset+disp);
  1150. mask = (u16)(0x1 << bit);
  1151. CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
  1152. store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
  1153. }
  1154. } else { /* register to register */
  1155. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1156. u32 *srcreg,*shiftreg;
  1157. u32 mask;
  1158. srcreg = DECODE_RM_LONG_REGISTER(rl);
  1159. DECODE_PRINTF(",");
  1160. shiftreg = DECODE_RM_LONG_REGISTER(rh);
  1161. TRACE_AND_STEP();
  1162. bit = *shiftreg & 0x1F;
  1163. mask = (0x1 << bit);
  1164. CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
  1165. *srcreg ^= mask;
  1166. } else {
  1167. u16 *srcreg,*shiftreg;
  1168. u16 mask;
  1169. srcreg = DECODE_RM_WORD_REGISTER(rl);
  1170. DECODE_PRINTF(",");
  1171. shiftreg = DECODE_RM_WORD_REGISTER(rh);
  1172. TRACE_AND_STEP();
  1173. bit = *shiftreg & 0xF;
  1174. mask = (u16)(0x1 << bit);
  1175. CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
  1176. *srcreg ^= mask;
  1177. }
  1178. }
  1179. DECODE_CLEAR_SEGOVR();
  1180. END_OF_INSTR();
  1181. }
  1182. /****************************************************************************
  1183. REMARKS:
  1184. Handles opcode 0x0f,0xbc
  1185. ****************************************************************************/
  1186. void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
  1187. {
  1188. int mod, rl, rh;
  1189. uint srcoffset;
  1190. START_OF_INSTR();
  1191. DECODE_PRINTF("BSF\n");
  1192. FETCH_DECODE_MODRM(mod, rh, rl);
  1193. if (mod < 3) {
  1194. srcoffset = decode_rmXX_address(mod, rl);
  1195. DECODE_PRINTF(",");
  1196. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1197. u32 srcval, *dstreg;
  1198. dstreg = DECODE_RM_LONG_REGISTER(rh);
  1199. TRACE_AND_STEP();
  1200. srcval = fetch_data_long(srcoffset);
  1201. CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
  1202. for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
  1203. if ((srcval >> *dstreg) & 1) break;
  1204. } else {
  1205. u16 srcval, *dstreg;
  1206. dstreg = DECODE_RM_WORD_REGISTER(rh);
  1207. TRACE_AND_STEP();
  1208. srcval = fetch_data_word(srcoffset);
  1209. CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
  1210. for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
  1211. if ((srcval >> *dstreg) & 1) break;
  1212. }
  1213. } else { /* register to register */
  1214. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1215. u32 *srcreg, *dstreg;
  1216. srcreg = DECODE_RM_LONG_REGISTER(rl);
  1217. DECODE_PRINTF(",");
  1218. dstreg = DECODE_RM_LONG_REGISTER(rh);
  1219. TRACE_AND_STEP();
  1220. CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
  1221. for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
  1222. if ((*srcreg >> *dstreg) & 1) break;
  1223. } else {
  1224. u16 *srcreg, *dstreg;
  1225. srcreg = DECODE_RM_WORD_REGISTER(rl);
  1226. DECODE_PRINTF(",");
  1227. dstreg = DECODE_RM_WORD_REGISTER(rh);
  1228. TRACE_AND_STEP();
  1229. CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
  1230. for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
  1231. if ((*srcreg >> *dstreg) & 1) break;
  1232. }
  1233. }
  1234. DECODE_CLEAR_SEGOVR();
  1235. END_OF_INSTR();
  1236. }
  1237. /****************************************************************************
  1238. REMARKS:
  1239. Handles opcode 0x0f,0xbd
  1240. ****************************************************************************/
  1241. void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
  1242. {
  1243. int mod, rl, rh;
  1244. uint srcoffset;
  1245. START_OF_INSTR();
  1246. DECODE_PRINTF("BSF\n");
  1247. FETCH_DECODE_MODRM(mod, rh, rl);
  1248. if (mod < 3) {
  1249. srcoffset = decode_rmXX_address(mod, rl);
  1250. DECODE_PRINTF(",");
  1251. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1252. u32 srcval, *dstreg;
  1253. dstreg = DECODE_RM_LONG_REGISTER(rh);
  1254. TRACE_AND_STEP();
  1255. srcval = fetch_data_long(srcoffset);
  1256. CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
  1257. for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
  1258. if ((srcval >> *dstreg) & 1) break;
  1259. } else {
  1260. u16 srcval, *dstreg;
  1261. dstreg = DECODE_RM_WORD_REGISTER(rh);
  1262. TRACE_AND_STEP();
  1263. srcval = fetch_data_word(srcoffset);
  1264. CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
  1265. for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
  1266. if ((srcval >> *dstreg) & 1) break;
  1267. }
  1268. } else { /* register to register */
  1269. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1270. u32 *srcreg, *dstreg;
  1271. srcreg = DECODE_RM_LONG_REGISTER(rl);
  1272. DECODE_PRINTF(",");
  1273. dstreg = DECODE_RM_LONG_REGISTER(rh);
  1274. TRACE_AND_STEP();
  1275. CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
  1276. for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
  1277. if ((*srcreg >> *dstreg) & 1) break;
  1278. } else {
  1279. u16 *srcreg, *dstreg;
  1280. srcreg = DECODE_RM_WORD_REGISTER(rl);
  1281. DECODE_PRINTF(",");
  1282. dstreg = DECODE_RM_WORD_REGISTER(rh);
  1283. TRACE_AND_STEP();
  1284. CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
  1285. for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
  1286. if ((*srcreg >> *dstreg) & 1) break;
  1287. }
  1288. }
  1289. DECODE_CLEAR_SEGOVR();
  1290. END_OF_INSTR();
  1291. }
  1292. /****************************************************************************
  1293. REMARKS:
  1294. Handles opcode 0x0f,0xbe
  1295. ****************************************************************************/
  1296. void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
  1297. {
  1298. int mod, rl, rh;
  1299. uint srcoffset;
  1300. START_OF_INSTR();
  1301. DECODE_PRINTF("MOVSX\t");
  1302. FETCH_DECODE_MODRM(mod, rh, rl);
  1303. if (mod < 3) {
  1304. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1305. u32 *destreg;
  1306. u32 srcval;
  1307. destreg = DECODE_RM_LONG_REGISTER(rh);
  1308. DECODE_PRINTF(",");
  1309. srcoffset = decode_rmXX_address(mod, rl);
  1310. srcval = (s32)((s8)fetch_data_byte(srcoffset));
  1311. DECODE_PRINTF("\n");
  1312. TRACE_AND_STEP();
  1313. *destreg = srcval;
  1314. } else {
  1315. u16 *destreg;
  1316. u16 srcval;
  1317. destreg = DECODE_RM_WORD_REGISTER(rh);
  1318. DECODE_PRINTF(",");
  1319. srcoffset = decode_rmXX_address(mod, rl);
  1320. srcval = (s16)((s8)fetch_data_byte(srcoffset));
  1321. DECODE_PRINTF("\n");
  1322. TRACE_AND_STEP();
  1323. *destreg = srcval;
  1324. }
  1325. } else { /* register to register */
  1326. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1327. u32 *destreg;
  1328. u8 *srcreg;
  1329. destreg = DECODE_RM_LONG_REGISTER(rh);
  1330. DECODE_PRINTF(",");
  1331. srcreg = DECODE_RM_BYTE_REGISTER(rl);
  1332. DECODE_PRINTF("\n");
  1333. TRACE_AND_STEP();
  1334. *destreg = (s32)((s8)*srcreg);
  1335. } else {
  1336. u16 *destreg;
  1337. u8 *srcreg;
  1338. destreg = DECODE_RM_WORD_REGISTER(rh);
  1339. DECODE_PRINTF(",");
  1340. srcreg = DECODE_RM_BYTE_REGISTER(rl);
  1341. DECODE_PRINTF("\n");
  1342. TRACE_AND_STEP();
  1343. *destreg = (s16)((s8)*srcreg);
  1344. }
  1345. }
  1346. DECODE_CLEAR_SEGOVR();
  1347. END_OF_INSTR();
  1348. }
  1349. /****************************************************************************
  1350. REMARKS:
  1351. Handles opcode 0x0f,0xbf
  1352. ****************************************************************************/
  1353. void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
  1354. {
  1355. int mod, rl, rh;
  1356. uint srcoffset;
  1357. u32 *destreg;
  1358. u32 srcval;
  1359. u16 *srcreg;
  1360. START_OF_INSTR();
  1361. DECODE_PRINTF("MOVSX\t");
  1362. FETCH_DECODE_MODRM(mod, rh, rl);
  1363. if (mod < 3) {
  1364. destreg = DECODE_RM_LONG_REGISTER(rh);
  1365. DECODE_PRINTF(",");
  1366. srcoffset = decode_rmXX_address(mod, rl);
  1367. srcval = (s32)((s16)fetch_data_word(srcoffset));
  1368. DECODE_PRINTF("\n");
  1369. TRACE_AND_STEP();
  1370. *destreg = srcval;
  1371. } else { /* register to register */
  1372. destreg = DECODE_RM_LONG_REGISTER(rh);
  1373. DECODE_PRINTF(",");
  1374. srcreg = DECODE_RM_WORD_REGISTER(rl);
  1375. DECODE_PRINTF("\n");
  1376. TRACE_AND_STEP();
  1377. *destreg = (s32)((s16)*srcreg);
  1378. }
  1379. DECODE_CLEAR_SEGOVR();
  1380. END_OF_INSTR();
  1381. }
  1382. /***************************************************************************
  1383. * Double byte operation code table:
  1384. **************************************************************************/
  1385. void (*x86emu_optab2[256])(u8) =
  1386. {
  1387. /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
  1388. /* 0x01 */ x86emuOp2_illegal_op, /* Group G (ring 0 PM) */
  1389. /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
  1390. /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
  1391. /* 0x04 */ x86emuOp2_illegal_op,
  1392. /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
  1393. /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
  1394. /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
  1395. /* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */
  1396. /* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */
  1397. /* 0x0a */ x86emuOp2_illegal_op,
  1398. /* 0x0b */ x86emuOp2_illegal_op,
  1399. /* 0x0c */ x86emuOp2_illegal_op,
  1400. /* 0x0d */ x86emuOp2_illegal_op,
  1401. /* 0x0e */ x86emuOp2_illegal_op,
  1402. /* 0x0f */ x86emuOp2_illegal_op,
  1403. /* 0x10 */ x86emuOp2_illegal_op,
  1404. /* 0x11 */ x86emuOp2_illegal_op,
  1405. /* 0x12 */ x86emuOp2_illegal_op,
  1406. /* 0x13 */ x86emuOp2_illegal_op,
  1407. /* 0x14 */ x86emuOp2_illegal_op,
  1408. /* 0x15 */ x86emuOp2_illegal_op,
  1409. /* 0x16 */ x86emuOp2_illegal_op,
  1410. /* 0x17 */ x86emuOp2_illegal_op,
  1411. /* 0x18 */ x86emuOp2_illegal_op,
  1412. /* 0x19 */ x86emuOp2_illegal_op,
  1413. /* 0x1a */ x86emuOp2_illegal_op,
  1414. /* 0x1b */ x86emuOp2_illegal_op,
  1415. /* 0x1c */ x86emuOp2_illegal_op,
  1416. /* 0x1d */ x86emuOp2_illegal_op,
  1417. /* 0x1e */ x86emuOp2_illegal_op,
  1418. /* 0x1f */ x86emuOp2_illegal_op,
  1419. /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
  1420. /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
  1421. /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
  1422. /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
  1423. /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
  1424. /* 0x25 */ x86emuOp2_illegal_op,
  1425. /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
  1426. /* 0x27 */ x86emuOp2_illegal_op,
  1427. /* 0x28 */ x86emuOp2_illegal_op,
  1428. /* 0x29 */ x86emuOp2_illegal_op,
  1429. /* 0x2a */ x86emuOp2_illegal_op,
  1430. /* 0x2b */ x86emuOp2_illegal_op,
  1431. /* 0x2c */ x86emuOp2_illegal_op,
  1432. /* 0x2d */ x86emuOp2_illegal_op,
  1433. /* 0x2e */ x86emuOp2_illegal_op,
  1434. /* 0x2f */ x86emuOp2_illegal_op,
  1435. /* 0x30 */ x86emuOp2_illegal_op,
  1436. /* 0x31 */ x86emuOp2_illegal_op,
  1437. /* 0x32 */ x86emuOp2_illegal_op,
  1438. /* 0x33 */ x86emuOp2_illegal_op,
  1439. /* 0x34 */ x86emuOp2_illegal_op,
  1440. /* 0x35 */ x86emuOp2_illegal_op,
  1441. /* 0x36 */ x86emuOp2_illegal_op,
  1442. /* 0x37 */ x86emuOp2_illegal_op,
  1443. /* 0x38 */ x86emuOp2_illegal_op,
  1444. /* 0x39 */ x86emuOp2_illegal_op,
  1445. /* 0x3a */ x86emuOp2_illegal_op,
  1446. /* 0x3b */ x86emuOp2_illegal_op,
  1447. /* 0x3c */ x86emuOp2_illegal_op,
  1448. /* 0x3d */ x86emuOp2_illegal_op,
  1449. /* 0x3e */ x86emuOp2_illegal_op,
  1450. /* 0x3f */ x86emuOp2_illegal_op,
  1451. /* 0x40 */ x86emuOp2_illegal_op,
  1452. /* 0x41 */ x86emuOp2_illegal_op,
  1453. /* 0x42 */ x86emuOp2_illegal_op,
  1454. /* 0x43 */ x86emuOp2_illegal_op,
  1455. /* 0x44 */ x86emuOp2_illegal_op,
  1456. /* 0x45 */ x86emuOp2_illegal_op,
  1457. /* 0x46 */ x86emuOp2_illegal_op,
  1458. /* 0x47 */ x86emuOp2_illegal_op,
  1459. /* 0x48 */ x86emuOp2_illegal_op,
  1460. /* 0x49 */ x86emuOp2_illegal_op,
  1461. /* 0x4a */ x86emuOp2_illegal_op,
  1462. /* 0x4b */ x86emuOp2_illegal_op,
  1463. /* 0x4c */ x86emuOp2_illegal_op,
  1464. /* 0x4d */ x86emuOp2_illegal_op,
  1465. /* 0x4e */ x86emuOp2_illegal_op,
  1466. /* 0x4f */ x86emuOp2_illegal_op,
  1467. /* 0x50 */ x86emuOp2_illegal_op,
  1468. /* 0x51 */ x86emuOp2_illegal_op,
  1469. /* 0x52 */ x86emuOp2_illegal_op,
  1470. /* 0x53 */ x86emuOp2_illegal_op,
  1471. /* 0x54 */ x86emuOp2_illegal_op,
  1472. /* 0x55 */ x86emuOp2_illegal_op,
  1473. /* 0x56 */ x86emuOp2_illegal_op,
  1474. /* 0x57 */ x86emuOp2_illegal_op,
  1475. /* 0x58 */ x86emuOp2_illegal_op,
  1476. /* 0x59 */ x86emuOp2_illegal_op,
  1477. /* 0x5a */ x86emuOp2_illegal_op,
  1478. /* 0x5b */ x86emuOp2_illegal_op,
  1479. /* 0x5c */ x86emuOp2_illegal_op,
  1480. /* 0x5d */ x86emuOp2_illegal_op,
  1481. /* 0x5e */ x86emuOp2_illegal_op,
  1482. /* 0x5f */ x86emuOp2_illegal_op,
  1483. /* 0x60 */ x86emuOp2_illegal_op,
  1484. /* 0x61 */ x86emuOp2_illegal_op,
  1485. /* 0x62 */ x86emuOp2_illegal_op,
  1486. /* 0x63 */ x86emuOp2_illegal_op,
  1487. /* 0x64 */ x86emuOp2_illegal_op,
  1488. /* 0x65 */ x86emuOp2_illegal_op,
  1489. /* 0x66 */ x86emuOp2_illegal_op,
  1490. /* 0x67 */ x86emuOp2_illegal_op,
  1491. /* 0x68 */ x86emuOp2_illegal_op,
  1492. /* 0x69 */ x86emuOp2_illegal_op,
  1493. /* 0x6a */ x86emuOp2_illegal_op,
  1494. /* 0x6b */ x86emuOp2_illegal_op,
  1495. /* 0x6c */ x86emuOp2_illegal_op,
  1496. /* 0x6d */ x86emuOp2_illegal_op,
  1497. /* 0x6e */ x86emuOp2_illegal_op,
  1498. /* 0x6f */ x86emuOp2_illegal_op,
  1499. /* 0x70 */ x86emuOp2_illegal_op,
  1500. /* 0x71 */ x86emuOp2_illegal_op,
  1501. /* 0x72 */ x86emuOp2_illegal_op,
  1502. /* 0x73 */ x86emuOp2_illegal_op,
  1503. /* 0x74 */ x86emuOp2_illegal_op,
  1504. /* 0x75 */ x86emuOp2_illegal_op,
  1505. /* 0x76 */ x86emuOp2_illegal_op,
  1506. /* 0x77 */ x86emuOp2_illegal_op,
  1507. /* 0x78 */ x86emuOp2_illegal_op,
  1508. /* 0x79 */ x86emuOp2_illegal_op,
  1509. /* 0x7a */ x86emuOp2_illegal_op,
  1510. /* 0x7b */ x86emuOp2_illegal_op,
  1511. /* 0x7c */ x86emuOp2_illegal_op,
  1512. /* 0x7d */ x86emuOp2_illegal_op,
  1513. /* 0x7e */ x86emuOp2_illegal_op,
  1514. /* 0x7f */ x86emuOp2_illegal_op,
  1515. /* 0x80 */ x86emuOp2_long_jump,
  1516. /* 0x81 */ x86emuOp2_long_jump,
  1517. /* 0x82 */ x86emuOp2_long_jump,
  1518. /* 0x83 */ x86emuOp2_long_jump,
  1519. /* 0x84 */ x86emuOp2_long_jump,
  1520. /* 0x85 */ x86emuOp2_long_jump,
  1521. /* 0x86 */ x86emuOp2_long_jump,
  1522. /* 0x87 */ x86emuOp2_long_jump,
  1523. /* 0x88 */ x86emuOp2_long_jump,
  1524. /* 0x89 */ x86emuOp2_long_jump,
  1525. /* 0x8a */ x86emuOp2_long_jump,
  1526. /* 0x8b */ x86emuOp2_long_jump,
  1527. /* 0x8c */ x86emuOp2_long_jump,
  1528. /* 0x8d */ x86emuOp2_long_jump,
  1529. /* 0x8e */ x86emuOp2_long_jump,
  1530. /* 0x8f */ x86emuOp2_long_jump,
  1531. /* 0x90 */ x86emuOp2_set_byte,
  1532. /* 0x91 */ x86emuOp2_set_byte,
  1533. /* 0x92 */ x86emuOp2_set_byte,
  1534. /* 0x93 */ x86emuOp2_set_byte,
  1535. /* 0x94 */ x86emuOp2_set_byte,
  1536. /* 0x95 */ x86emuOp2_set_byte,
  1537. /* 0x96 */ x86emuOp2_set_byte,
  1538. /* 0x97 */ x86emuOp2_set_byte,
  1539. /* 0x98 */ x86emuOp2_set_byte,
  1540. /* 0x99 */ x86emuOp2_set_byte,
  1541. /* 0x9a */ x86emuOp2_set_byte,
  1542. /* 0x9b */ x86emuOp2_set_byte,
  1543. /* 0x9c */ x86emuOp2_set_byte,
  1544. /* 0x9d */ x86emuOp2_set_byte,
  1545. /* 0x9e */ x86emuOp2_set_byte,
  1546. /* 0x9f */ x86emuOp2_set_byte,
  1547. /* 0xa0 */ x86emuOp2_push_FS,
  1548. /* 0xa1 */ x86emuOp2_pop_FS,
  1549. /* 0xa2 */ x86emuOp2_illegal_op,
  1550. /* 0xa3 */ x86emuOp2_bt_R,
  1551. /* 0xa4 */ x86emuOp2_shld_IMM,
  1552. /* 0xa5 */ x86emuOp2_shld_CL,
  1553. /* 0xa6 */ x86emuOp2_illegal_op,
  1554. /* 0xa7 */ x86emuOp2_illegal_op,
  1555. /* 0xa8 */ x86emuOp2_push_GS,
  1556. /* 0xa9 */ x86emuOp2_pop_GS,
  1557. /* 0xaa */ x86emuOp2_illegal_op,
  1558. /* 0xab */ x86emuOp2_bt_R,
  1559. /* 0xac */ x86emuOp2_shrd_IMM,
  1560. /* 0xad */ x86emuOp2_shrd_CL,
  1561. /* 0xae */ x86emuOp2_illegal_op,
  1562. /* 0xaf */ x86emuOp2_imul_R_RM,
  1563. /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
  1564. /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
  1565. /* 0xb2 */ x86emuOp2_lss_R_IMM,
  1566. /* 0xb3 */ x86emuOp2_btr_R,
  1567. /* 0xb4 */ x86emuOp2_lfs_R_IMM,
  1568. /* 0xb5 */ x86emuOp2_lgs_R_IMM,
  1569. /* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
  1570. /* 0xb7 */ x86emuOp2_movzx_word_R_RM,
  1571. /* 0xb8 */ x86emuOp2_illegal_op,
  1572. /* 0xb9 */ x86emuOp2_illegal_op,
  1573. /* 0xba */ x86emuOp2_btX_I,
  1574. /* 0xbb */ x86emuOp2_btc_R,
  1575. /* 0xbc */ x86emuOp2_bsf,
  1576. /* 0xbd */ x86emuOp2_bsr,
  1577. /* 0xbe */ x86emuOp2_movsx_byte_R_RM,
  1578. /* 0xbf */ x86emuOp2_movsx_word_R_RM,
  1579. /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
  1580. /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
  1581. /* 0xc2 */ x86emuOp2_illegal_op,
  1582. /* 0xc3 */ x86emuOp2_illegal_op,
  1583. /* 0xc4 */ x86emuOp2_illegal_op,
  1584. /* 0xc5 */ x86emuOp2_illegal_op,
  1585. /* 0xc6 */ x86emuOp2_illegal_op,
  1586. /* 0xc7 */ x86emuOp2_illegal_op,
  1587. /* 0xc8 */ x86emuOp2_illegal_op, /* TODO: bswap */
  1588. /* 0xc9 */ x86emuOp2_illegal_op, /* TODO: bswap */
  1589. /* 0xca */ x86emuOp2_illegal_op, /* TODO: bswap */
  1590. /* 0xcb */ x86emuOp2_illegal_op, /* TODO: bswap */
  1591. /* 0xcc */ x86emuOp2_illegal_op, /* TODO: bswap */
  1592. /* 0xcd */ x86emuOp2_illegal_op, /* TODO: bswap */
  1593. /* 0xce */ x86emuOp2_illegal_op, /* TODO: bswap */
  1594. /* 0xcf */ x86emuOp2_illegal_op, /* TODO: bswap */
  1595. /* 0xd0 */ x86emuOp2_illegal_op,
  1596. /* 0xd1 */ x86emuOp2_illegal_op,
  1597. /* 0xd2 */ x86emuOp2_illegal_op,
  1598. /* 0xd3 */ x86emuOp2_illegal_op,
  1599. /* 0xd4 */ x86emuOp2_illegal_op,
  1600. /* 0xd5 */ x86emuOp2_illegal_op,
  1601. /* 0xd6 */ x86emuOp2_illegal_op,
  1602. /* 0xd7 */ x86emuOp2_illegal_op,
  1603. /* 0xd8 */ x86emuOp2_illegal_op,
  1604. /* 0xd9 */ x86emuOp2_illegal_op,
  1605. /* 0xda */ x86emuOp2_illegal_op,
  1606. /* 0xdb */ x86emuOp2_illegal_op,
  1607. /* 0xdc */ x86emuOp2_illegal_op,
  1608. /* 0xdd */ x86emuOp2_illegal_op,
  1609. /* 0xde */ x86emuOp2_illegal_op,
  1610. /* 0xdf */ x86emuOp2_illegal_op,
  1611. /* 0xe0 */ x86emuOp2_illegal_op,
  1612. /* 0xe1 */ x86emuOp2_illegal_op,
  1613. /* 0xe2 */ x86emuOp2_illegal_op,
  1614. /* 0xe3 */ x86emuOp2_illegal_op,
  1615. /* 0xe4 */ x86emuOp2_illegal_op,
  1616. /* 0xe5 */ x86emuOp2_illegal_op,
  1617. /* 0xe6 */ x86emuOp2_illegal_op,
  1618. /* 0xe7 */ x86emuOp2_illegal_op,
  1619. /* 0xe8 */ x86emuOp2_illegal_op,
  1620. /* 0xe9 */ x86emuOp2_illegal_op,
  1621. /* 0xea */ x86emuOp2_illegal_op,
  1622. /* 0xeb */ x86emuOp2_illegal_op,
  1623. /* 0xec */ x86emuOp2_illegal_op,
  1624. /* 0xed */ x86emuOp2_illegal_op,
  1625. /* 0xee */ x86emuOp2_illegal_op,
  1626. /* 0xef */ x86emuOp2_illegal_op,
  1627. /* 0xf0 */ x86emuOp2_illegal_op,
  1628. /* 0xf1 */ x86emuOp2_illegal_op,
  1629. /* 0xf2 */ x86emuOp2_illegal_op,
  1630. /* 0xf3 */ x86emuOp2_illegal_op,
  1631. /* 0xf4 */ x86emuOp2_illegal_op,
  1632. /* 0xf5 */ x86emuOp2_illegal_op,
  1633. /* 0xf6 */ x86emuOp2_illegal_op,
  1634. /* 0xf7 */ x86emuOp2_illegal_op,
  1635. /* 0xf8 */ x86emuOp2_illegal_op,
  1636. /* 0xf9 */ x86emuOp2_illegal_op,
  1637. /* 0xfa */ x86emuOp2_illegal_op,
  1638. /* 0xfb */ x86emuOp2_illegal_op,
  1639. /* 0xfc */ x86emuOp2_illegal_op,
  1640. /* 0xfd */ x86emuOp2_illegal_op,
  1641. /* 0xfe */ x86emuOp2_illegal_op,
  1642. /* 0xff */ x86emuOp2_illegal_op,
  1643. };