ops2.c 48 KB

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