ops2.c 55 KB

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