instructions.rs 106 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072
  1. #![allow(non_snake_case, unused_variables)]
  2. extern "C" {
  3. #[no_mangle]
  4. fn hlt_op();
  5. }
  6. use cpu::arith::*;
  7. use cpu::cpu::*;
  8. use cpu::fpu::*;
  9. use cpu::fpu::{fpu_load_m32, fpu_load_m64, fpu_write_st};
  10. use cpu::global_pointers::*;
  11. use cpu::misc_instr::*;
  12. use cpu::misc_instr::{pop16, pop32s, push16, push32};
  13. use cpu::string::*;
  14. pub unsafe fn instr_00_mem(addr: i32, r: i32) {
  15. SAFE_READ_WRITE8!(___, addr, add8(___, read_reg8(r)));
  16. }
  17. pub unsafe fn instr_00_reg(r1: i32, r: i32) { write_reg8(r1, add8(read_reg8(r1), read_reg8(r))); }
  18. pub unsafe fn instr16_01_mem(addr: i32, r: i32) {
  19. SAFE_READ_WRITE16!(___, addr, add16(___, read_reg16(r)));
  20. }
  21. pub unsafe fn instr16_01_reg(r1: i32, r: i32) {
  22. write_reg16(r1, add16(read_reg16(r1), read_reg16(r)));
  23. }
  24. pub unsafe fn instr32_01_mem(addr: i32, r: i32) {
  25. SAFE_READ_WRITE32!(___, addr, add32(___, read_reg32(r)));
  26. }
  27. pub unsafe fn instr32_01_reg(r1: i32, r: i32) {
  28. write_reg32(r1, add32(read_reg32(r1), read_reg32(r)));
  29. }
  30. pub unsafe fn instr_02_mem(addr: i32, r: i32) {
  31. write_reg8(
  32. r,
  33. add8(read_reg8(r), return_on_pagefault!(safe_read8(addr))),
  34. );
  35. }
  36. pub unsafe fn instr_02_reg(r1: i32, r: i32) { write_reg8(r, add8(read_reg8(r), read_reg8(r1))); }
  37. pub unsafe fn instr16_03_mem(addr: i32, r: i32) {
  38. write_reg16(
  39. r,
  40. add16(read_reg16(r), return_on_pagefault!(safe_read16(addr))),
  41. );
  42. }
  43. pub unsafe fn instr16_03_reg(r1: i32, r: i32) {
  44. write_reg16(r, add16(read_reg16(r), read_reg16(r1)));
  45. }
  46. pub unsafe fn instr32_03_mem(addr: i32, r: i32) {
  47. write_reg32(
  48. r,
  49. add32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))),
  50. );
  51. }
  52. pub unsafe fn instr32_03_reg(r1: i32, r: i32) {
  53. write_reg32(r, add32(read_reg32(r), read_reg32(r1)));
  54. }
  55. pub unsafe fn instr_04(imm8: i32) { write_reg8(AL, add8(read_reg8(AL), imm8)); }
  56. pub unsafe fn instr16_05(imm16: i32) { write_reg16(AX, add16(read_reg16(AX), imm16)); }
  57. pub unsafe fn instr32_05(imm32: i32) { write_reg32(EAX, add32(read_reg32(EAX), imm32)); }
  58. pub unsafe fn instr16_06() {
  59. return_on_pagefault!(push16(*sreg.offset(ES as isize) as i32));
  60. }
  61. pub unsafe fn instr32_06() {
  62. return_on_pagefault!(push32(*sreg.offset(ES as isize) as i32));
  63. }
  64. #[no_mangle]
  65. pub unsafe fn instr16_07() {
  66. if !switch_seg(ES, return_on_pagefault!(safe_read16(get_stack_pointer(0)))) {
  67. return;
  68. }
  69. adjust_stack_reg(2);
  70. }
  71. #[no_mangle]
  72. pub unsafe fn instr32_07() {
  73. if !switch_seg(
  74. ES,
  75. return_on_pagefault!(safe_read32s(get_stack_pointer(0))) & 0xFFFF,
  76. ) {
  77. return;
  78. }
  79. adjust_stack_reg(4);
  80. }
  81. pub unsafe fn instr_08_mem(addr: i32, r: i32) {
  82. SAFE_READ_WRITE8!(___, addr, or8(___, read_reg8(r)));
  83. }
  84. pub unsafe fn instr_08_reg(r1: i32, r: i32) { write_reg8(r1, or8(read_reg8(r1), read_reg8(r))); }
  85. pub unsafe fn instr16_09_mem(addr: i32, r: i32) {
  86. SAFE_READ_WRITE16!(___, addr, or16(___, read_reg16(r)));
  87. }
  88. pub unsafe fn instr16_09_reg(r1: i32, r: i32) {
  89. write_reg16(r1, or16(read_reg16(r1), read_reg16(r)));
  90. }
  91. pub unsafe fn instr32_09_mem(addr: i32, r: i32) {
  92. SAFE_READ_WRITE32!(___, addr, or32(___, read_reg32(r)));
  93. }
  94. pub unsafe fn instr32_09_reg(r1: i32, r: i32) {
  95. write_reg32(r1, or32(read_reg32(r1), read_reg32(r)));
  96. }
  97. pub unsafe fn instr_0A_mem(addr: i32, r: i32) {
  98. write_reg8(r, or8(read_reg8(r), return_on_pagefault!(safe_read8(addr))));
  99. }
  100. pub unsafe fn instr_0A_reg(r1: i32, r: i32) { write_reg8(r, or8(read_reg8(r), read_reg8(r1))); }
  101. pub unsafe fn instr16_0B_mem(addr: i32, r: i32) {
  102. write_reg16(
  103. r,
  104. or16(read_reg16(r), return_on_pagefault!(safe_read16(addr))),
  105. );
  106. }
  107. pub unsafe fn instr16_0B_reg(r1: i32, r: i32) {
  108. write_reg16(r, or16(read_reg16(r), read_reg16(r1)));
  109. }
  110. pub unsafe fn instr32_0B_mem(addr: i32, r: i32) {
  111. write_reg32(
  112. r,
  113. or32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))),
  114. );
  115. }
  116. pub unsafe fn instr32_0B_reg(r1: i32, r: i32) {
  117. write_reg32(r, or32(read_reg32(r), read_reg32(r1)));
  118. }
  119. pub unsafe fn instr_0C(imm8: i32) { write_reg8(AL, or8(read_reg8(AL), imm8)); }
  120. pub unsafe fn instr16_0D(imm16: i32) { write_reg16(AX, or16(read_reg16(AX), imm16)); }
  121. pub unsafe fn instr32_0D(imm32: i32) { write_reg32(EAX, or32(read_reg32(EAX), imm32)); }
  122. pub unsafe fn instr16_0E() {
  123. return_on_pagefault!(push16(*sreg.offset(CS as isize) as i32));
  124. }
  125. pub unsafe fn instr32_0E() {
  126. return_on_pagefault!(push32(*sreg.offset(CS as isize) as i32));
  127. }
  128. pub unsafe fn instr16_0F() { run_instruction0f_16(return_on_pagefault!(read_imm8())); }
  129. pub unsafe fn instr32_0F() { run_instruction0f_32(return_on_pagefault!(read_imm8())); }
  130. pub unsafe fn instr_10_mem(addr: i32, r: i32) {
  131. SAFE_READ_WRITE8!(___, addr, adc8(___, read_reg8(r)));
  132. }
  133. pub unsafe fn instr_10_reg(r1: i32, r: i32) { write_reg8(r1, adc8(read_reg8(r1), read_reg8(r))); }
  134. pub unsafe fn instr16_11_mem(addr: i32, r: i32) {
  135. SAFE_READ_WRITE16!(___, addr, adc16(___, read_reg16(r)));
  136. }
  137. pub unsafe fn instr16_11_reg(r1: i32, r: i32) {
  138. write_reg16(r1, adc16(read_reg16(r1), read_reg16(r)));
  139. }
  140. pub unsafe fn instr32_11_mem(addr: i32, r: i32) {
  141. SAFE_READ_WRITE32!(___, addr, adc32(___, read_reg32(r)));
  142. }
  143. pub unsafe fn instr32_11_reg(r1: i32, r: i32) {
  144. write_reg32(r1, adc32(read_reg32(r1), read_reg32(r)));
  145. }
  146. pub unsafe fn instr_12_mem(addr: i32, r: i32) {
  147. write_reg8(
  148. r,
  149. adc8(read_reg8(r), return_on_pagefault!(safe_read8(addr))),
  150. );
  151. }
  152. pub unsafe fn instr_12_reg(r1: i32, r: i32) { write_reg8(r, adc8(read_reg8(r), read_reg8(r1))); }
  153. pub unsafe fn instr16_13_mem(addr: i32, r: i32) {
  154. write_reg16(
  155. r,
  156. adc16(read_reg16(r), return_on_pagefault!(safe_read16(addr))),
  157. );
  158. }
  159. pub unsafe fn instr16_13_reg(r1: i32, r: i32) {
  160. write_reg16(r, adc16(read_reg16(r), read_reg16(r1)));
  161. }
  162. pub unsafe fn instr32_13_mem(addr: i32, r: i32) {
  163. write_reg32(
  164. r,
  165. adc32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))),
  166. );
  167. }
  168. pub unsafe fn instr32_13_reg(r1: i32, r: i32) {
  169. write_reg32(r, adc32(read_reg32(r), read_reg32(r1)));
  170. }
  171. pub unsafe fn instr_14(imm8: i32) { write_reg8(AL, adc8(read_reg8(AL), imm8)); }
  172. pub unsafe fn instr16_15(imm16: i32) { write_reg16(AX, adc16(read_reg16(AX), imm16)); }
  173. pub unsafe fn instr32_15(imm32: i32) { write_reg32(EAX, adc32(read_reg32(EAX), imm32)); }
  174. pub unsafe fn instr16_16() {
  175. return_on_pagefault!(push16(*sreg.offset(SS as isize) as i32));
  176. }
  177. pub unsafe fn instr32_16() {
  178. return_on_pagefault!(push32(*sreg.offset(SS as isize) as i32));
  179. }
  180. #[no_mangle]
  181. pub unsafe fn instr16_17() {
  182. if !switch_seg(SS, return_on_pagefault!(safe_read16(get_stack_pointer(0)))) {
  183. return;
  184. }
  185. adjust_stack_reg(2);
  186. }
  187. #[no_mangle]
  188. pub unsafe fn instr32_17() {
  189. if !switch_seg(
  190. SS,
  191. return_on_pagefault!(safe_read32s(get_stack_pointer(0))) & 0xFFFF,
  192. ) {
  193. return;
  194. }
  195. adjust_stack_reg(4);
  196. }
  197. pub unsafe fn instr_18_mem(addr: i32, r: i32) {
  198. SAFE_READ_WRITE8!(___, addr, sbb8(___, read_reg8(r)));
  199. }
  200. pub unsafe fn instr_18_reg(r1: i32, r: i32) { write_reg8(r1, sbb8(read_reg8(r1), read_reg8(r))); }
  201. pub unsafe fn instr16_19_mem(addr: i32, r: i32) {
  202. SAFE_READ_WRITE16!(___, addr, sbb16(___, read_reg16(r)));
  203. }
  204. pub unsafe fn instr16_19_reg(r1: i32, r: i32) {
  205. write_reg16(r1, sbb16(read_reg16(r1), read_reg16(r)));
  206. }
  207. pub unsafe fn instr32_19_mem(addr: i32, r: i32) {
  208. SAFE_READ_WRITE32!(___, addr, sbb32(___, read_reg32(r)));
  209. }
  210. pub unsafe fn instr32_19_reg(r1: i32, r: i32) {
  211. write_reg32(r1, sbb32(read_reg32(r1), read_reg32(r)));
  212. }
  213. pub unsafe fn instr_1A_mem(addr: i32, r: i32) {
  214. write_reg8(
  215. r,
  216. sbb8(read_reg8(r), return_on_pagefault!(safe_read8(addr))),
  217. );
  218. }
  219. pub unsafe fn instr_1A_reg(r1: i32, r: i32) { write_reg8(r, sbb8(read_reg8(r), read_reg8(r1))); }
  220. pub unsafe fn instr16_1B_mem(addr: i32, r: i32) {
  221. write_reg16(
  222. r,
  223. sbb16(read_reg16(r), return_on_pagefault!(safe_read16(addr))),
  224. );
  225. }
  226. pub unsafe fn instr16_1B_reg(r1: i32, r: i32) {
  227. write_reg16(r, sbb16(read_reg16(r), read_reg16(r1)));
  228. }
  229. pub unsafe fn instr32_1B_mem(addr: i32, r: i32) {
  230. write_reg32(
  231. r,
  232. sbb32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))),
  233. );
  234. }
  235. pub unsafe fn instr32_1B_reg(r1: i32, r: i32) {
  236. write_reg32(r, sbb32(read_reg32(r), read_reg32(r1)));
  237. }
  238. pub unsafe fn instr_1C(imm8: i32) { write_reg8(AL, sbb8(read_reg8(AL), imm8)); }
  239. pub unsafe fn instr16_1D(imm16: i32) { write_reg16(AX, sbb16(read_reg16(AX), imm16)); }
  240. pub unsafe fn instr32_1D(imm32: i32) { write_reg32(EAX, sbb32(read_reg32(EAX), imm32)); }
  241. pub unsafe fn instr16_1E() {
  242. return_on_pagefault!(push16(*sreg.offset(DS as isize) as i32));
  243. }
  244. pub unsafe fn instr32_1E() {
  245. return_on_pagefault!(push32(*sreg.offset(DS as isize) as i32));
  246. }
  247. #[no_mangle]
  248. pub unsafe fn instr16_1F() {
  249. if !switch_seg(DS, return_on_pagefault!(safe_read16(get_stack_pointer(0)))) {
  250. return;
  251. }
  252. adjust_stack_reg(2);
  253. }
  254. #[no_mangle]
  255. pub unsafe fn instr32_1F() {
  256. if !switch_seg(
  257. DS,
  258. return_on_pagefault!(safe_read32s(get_stack_pointer(0))) & 0xFFFF,
  259. ) {
  260. return;
  261. }
  262. adjust_stack_reg(4);
  263. }
  264. pub unsafe fn instr_20_mem(addr: i32, r: i32) {
  265. SAFE_READ_WRITE8!(___, addr, and8(___, read_reg8(r)));
  266. }
  267. pub unsafe fn instr_20_reg(r1: i32, r: i32) { write_reg8(r1, and8(read_reg8(r1), read_reg8(r))); }
  268. pub unsafe fn instr16_21_mem(addr: i32, r: i32) {
  269. SAFE_READ_WRITE16!(___, addr, and16(___, read_reg16(r)));
  270. }
  271. pub unsafe fn instr16_21_reg(r1: i32, r: i32) {
  272. write_reg16(r1, and16(read_reg16(r1), read_reg16(r)));
  273. }
  274. pub unsafe fn instr32_21_mem(addr: i32, r: i32) {
  275. SAFE_READ_WRITE32!(___, addr, and32(___, read_reg32(r)));
  276. }
  277. pub unsafe fn instr32_21_reg(r1: i32, r: i32) {
  278. write_reg32(r1, and32(read_reg32(r1), read_reg32(r)));
  279. }
  280. pub unsafe fn instr_22_mem(addr: i32, r: i32) {
  281. write_reg8(
  282. r,
  283. and8(read_reg8(r), return_on_pagefault!(safe_read8(addr))),
  284. );
  285. }
  286. pub unsafe fn instr_22_reg(r1: i32, r: i32) { write_reg8(r, and8(read_reg8(r), read_reg8(r1))); }
  287. pub unsafe fn instr16_23_mem(addr: i32, r: i32) {
  288. write_reg16(
  289. r,
  290. and16(read_reg16(r), return_on_pagefault!(safe_read16(addr))),
  291. );
  292. }
  293. pub unsafe fn instr16_23_reg(r1: i32, r: i32) {
  294. write_reg16(r, and16(read_reg16(r), read_reg16(r1)));
  295. }
  296. pub unsafe fn instr32_23_mem(addr: i32, r: i32) {
  297. write_reg32(
  298. r,
  299. and32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))),
  300. );
  301. }
  302. pub unsafe fn instr32_23_reg(r1: i32, r: i32) {
  303. write_reg32(r, and32(read_reg32(r), read_reg32(r1)));
  304. }
  305. pub unsafe fn instr_24(imm8: i32) { write_reg8(AL, and8(read_reg8(AL), imm8)); }
  306. pub unsafe fn instr16_25(imm16: i32) { write_reg16(AX, and16(read_reg16(AX), imm16)); }
  307. pub unsafe fn instr32_25(imm32: i32) { write_reg32(EAX, and32(read_reg32(EAX), imm32)); }
  308. pub unsafe fn instr_26() { segment_prefix_op(ES); }
  309. #[no_mangle]
  310. pub unsafe fn instr_27() { bcd_daa(); }
  311. pub unsafe fn instr_28_mem(addr: i32, r: i32) {
  312. SAFE_READ_WRITE8!(___, addr, sub8(___, read_reg8(r)));
  313. }
  314. pub unsafe fn instr_28_reg(r1: i32, r: i32) { write_reg8(r1, sub8(read_reg8(r1), read_reg8(r))); }
  315. pub unsafe fn instr16_29_mem(addr: i32, r: i32) {
  316. SAFE_READ_WRITE16!(___, addr, sub16(___, read_reg16(r)));
  317. }
  318. pub unsafe fn instr16_29_reg(r1: i32, r: i32) {
  319. write_reg16(r1, sub16(read_reg16(r1), read_reg16(r)));
  320. }
  321. pub unsafe fn instr32_29_mem(addr: i32, r: i32) {
  322. SAFE_READ_WRITE32!(___, addr, sub32(___, read_reg32(r)));
  323. }
  324. pub unsafe fn instr32_29_reg(r1: i32, r: i32) {
  325. write_reg32(r1, sub32(read_reg32(r1), read_reg32(r)));
  326. }
  327. pub unsafe fn instr_2A_mem(addr: i32, r: i32) {
  328. write_reg8(
  329. r,
  330. sub8(read_reg8(r), return_on_pagefault!(safe_read8(addr))),
  331. );
  332. }
  333. pub unsafe fn instr_2A_reg(r1: i32, r: i32) { write_reg8(r, sub8(read_reg8(r), read_reg8(r1))); }
  334. pub unsafe fn instr16_2B_mem(addr: i32, r: i32) {
  335. write_reg16(
  336. r,
  337. sub16(read_reg16(r), return_on_pagefault!(safe_read16(addr))),
  338. );
  339. }
  340. pub unsafe fn instr16_2B_reg(r1: i32, r: i32) {
  341. write_reg16(r, sub16(read_reg16(r), read_reg16(r1)));
  342. }
  343. pub unsafe fn instr32_2B_mem(addr: i32, r: i32) {
  344. write_reg32(
  345. r,
  346. sub32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))),
  347. );
  348. }
  349. pub unsafe fn instr32_2B_reg(r1: i32, r: i32) {
  350. write_reg32(r, sub32(read_reg32(r), read_reg32(r1)));
  351. }
  352. pub unsafe fn instr_2C(imm8: i32) { write_reg8(AL, sub8(read_reg8(AL), imm8)); }
  353. pub unsafe fn instr16_2D(imm16: i32) { write_reg16(AX, sub16(read_reg16(AX), imm16)); }
  354. pub unsafe fn instr32_2D(imm32: i32) { write_reg32(EAX, sub32(read_reg32(EAX), imm32)); }
  355. pub unsafe fn instr_2E() { segment_prefix_op(CS); }
  356. #[no_mangle]
  357. pub unsafe fn instr_2F() { bcd_das(); }
  358. pub unsafe fn instr_30_mem(addr: i32, r: i32) {
  359. SAFE_READ_WRITE8!(___, addr, xor8(___, read_reg8(r)));
  360. }
  361. pub unsafe fn instr_30_reg(r1: i32, r: i32) { write_reg8(r1, xor8(read_reg8(r1), read_reg8(r))); }
  362. pub unsafe fn instr16_31_mem(addr: i32, r: i32) {
  363. SAFE_READ_WRITE16!(___, addr, xor16(___, read_reg16(r)));
  364. }
  365. pub unsafe fn instr16_31_reg(r1: i32, r: i32) {
  366. write_reg16(r1, xor16(read_reg16(r1), read_reg16(r)));
  367. }
  368. pub unsafe fn instr32_31_mem(addr: i32, r: i32) {
  369. SAFE_READ_WRITE32!(___, addr, xor32(___, read_reg32(r)));
  370. }
  371. pub unsafe fn instr32_31_reg(r1: i32, r: i32) {
  372. write_reg32(r1, xor32(read_reg32(r1), read_reg32(r)));
  373. }
  374. pub unsafe fn instr_32_mem(addr: i32, r: i32) {
  375. write_reg8(
  376. r,
  377. xor8(read_reg8(r), return_on_pagefault!(safe_read8(addr))),
  378. );
  379. }
  380. pub unsafe fn instr_32_reg(r1: i32, r: i32) { write_reg8(r, xor8(read_reg8(r), read_reg8(r1))); }
  381. pub unsafe fn instr16_33_mem(addr: i32, r: i32) {
  382. write_reg16(
  383. r,
  384. xor16(read_reg16(r), return_on_pagefault!(safe_read16(addr))),
  385. );
  386. }
  387. pub unsafe fn instr16_33_reg(r1: i32, r: i32) {
  388. write_reg16(r, xor16(read_reg16(r), read_reg16(r1)));
  389. }
  390. pub unsafe fn instr32_33_mem(addr: i32, r: i32) {
  391. write_reg32(
  392. r,
  393. xor32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))),
  394. );
  395. }
  396. pub unsafe fn instr32_33_reg(r1: i32, r: i32) {
  397. write_reg32(r, xor32(read_reg32(r), read_reg32(r1)));
  398. }
  399. pub unsafe fn instr_34(imm8: i32) { write_reg8(AL, xor8(read_reg8(AL), imm8)); }
  400. pub unsafe fn instr16_35(imm16: i32) { write_reg16(AX, xor16(read_reg16(AX), imm16)); }
  401. pub unsafe fn instr32_35(imm32: i32) { write_reg32(EAX, xor32(read_reg32(EAX), imm32)); }
  402. pub unsafe fn instr_36() { segment_prefix_op(SS); }
  403. #[no_mangle]
  404. pub unsafe fn instr_37() { bcd_aaa(); }
  405. pub unsafe fn instr_38_mem(addr: i32, r: i32) {
  406. cmp8(return_on_pagefault!(safe_read8(addr)), read_reg8(r));
  407. }
  408. pub unsafe fn instr_38_reg(r1: i32, r: i32) { cmp8(read_reg8(r1), read_reg8(r)); }
  409. pub unsafe fn instr16_39_mem(addr: i32, r: i32) {
  410. cmp16(return_on_pagefault!(safe_read16(addr)), read_reg16(r));
  411. }
  412. pub unsafe fn instr16_39_reg(r1: i32, r: i32) { cmp16(read_reg16(r1), read_reg16(r)); }
  413. pub unsafe fn instr32_39_mem(addr: i32, r: i32) {
  414. cmp32(return_on_pagefault!(safe_read32s(addr)), read_reg32(r));
  415. }
  416. pub unsafe fn instr32_39_reg(r1: i32, r: i32) { cmp32(read_reg32(r1), read_reg32(r)); }
  417. pub unsafe fn instr_3A_mem(addr: i32, r: i32) {
  418. cmp8(read_reg8(r), return_on_pagefault!(safe_read8(addr)));
  419. }
  420. pub unsafe fn instr_3A_reg(r1: i32, r: i32) { cmp8(read_reg8(r), read_reg8(r1)); }
  421. pub unsafe fn instr16_3B_mem(addr: i32, r: i32) {
  422. cmp16(read_reg16(r), return_on_pagefault!(safe_read16(addr)));
  423. }
  424. pub unsafe fn instr16_3B_reg(r1: i32, r: i32) { cmp16(read_reg16(r), read_reg16(r1)); }
  425. pub unsafe fn instr32_3B_mem(addr: i32, r: i32) {
  426. cmp32(read_reg32(r), return_on_pagefault!(safe_read32s(addr)));
  427. }
  428. pub unsafe fn instr32_3B_reg(r1: i32, r: i32) { cmp32(read_reg32(r), read_reg32(r1)); }
  429. pub unsafe fn instr_3C(imm8: i32) { cmp8(read_reg8(AL), imm8); }
  430. pub unsafe fn instr16_3D(imm16: i32) { cmp16(read_reg16(AX), imm16); }
  431. pub unsafe fn instr32_3D(imm32: i32) { cmp32(read_reg32(EAX), imm32); }
  432. pub unsafe fn instr_3E() { segment_prefix_op(DS); }
  433. #[no_mangle]
  434. pub unsafe fn instr_3F() { bcd_aas(); }
  435. pub unsafe fn instr16_40() { write_reg16(AX, inc16(read_reg16(AX))); }
  436. pub unsafe fn instr32_40() { write_reg32(EAX, inc32(read_reg32(EAX))); }
  437. pub unsafe fn instr16_41() { write_reg16(CX, inc16(read_reg16(CX))); }
  438. pub unsafe fn instr32_41() { write_reg32(ECX, inc32(read_reg32(ECX))); }
  439. pub unsafe fn instr16_42() { write_reg16(DX, inc16(read_reg16(DX))); }
  440. pub unsafe fn instr32_42() { write_reg32(EDX, inc32(read_reg32(EDX))); }
  441. pub unsafe fn instr16_43() { write_reg16(BX, inc16(read_reg16(BX))); }
  442. pub unsafe fn instr32_43() { write_reg32(EBX, inc32(read_reg32(EBX))); }
  443. pub unsafe fn instr16_44() { write_reg16(SP, inc16(read_reg16(SP))); }
  444. pub unsafe fn instr32_44() { write_reg32(ESP, inc32(read_reg32(ESP))); }
  445. pub unsafe fn instr16_45() { write_reg16(BP, inc16(read_reg16(BP))); }
  446. pub unsafe fn instr32_45() { write_reg32(EBP, inc32(read_reg32(EBP))); }
  447. pub unsafe fn instr16_46() { write_reg16(SI, inc16(read_reg16(SI))); }
  448. pub unsafe fn instr32_46() { write_reg32(ESI, inc32(read_reg32(ESI))); }
  449. pub unsafe fn instr16_47() { write_reg16(DI, inc16(read_reg16(DI))); }
  450. pub unsafe fn instr32_47() { write_reg32(EDI, inc32(read_reg32(EDI))); }
  451. pub unsafe fn instr16_48() { write_reg16(AX, dec16(read_reg16(AX))); }
  452. pub unsafe fn instr32_48() { write_reg32(EAX, dec32(read_reg32(EAX))); }
  453. pub unsafe fn instr16_49() { write_reg16(CX, dec16(read_reg16(CX))); }
  454. pub unsafe fn instr32_49() { write_reg32(ECX, dec32(read_reg32(ECX))); }
  455. pub unsafe fn instr16_4A() { write_reg16(DX, dec16(read_reg16(DX))); }
  456. pub unsafe fn instr32_4A() { write_reg32(EDX, dec32(read_reg32(EDX))); }
  457. pub unsafe fn instr16_4B() { write_reg16(BX, dec16(read_reg16(BX))); }
  458. pub unsafe fn instr32_4B() { write_reg32(EBX, dec32(read_reg32(EBX))); }
  459. pub unsafe fn instr16_4C() { write_reg16(SP, dec16(read_reg16(SP))); }
  460. pub unsafe fn instr32_4C() { write_reg32(ESP, dec32(read_reg32(ESP))); }
  461. pub unsafe fn instr16_4D() { write_reg16(BP, dec16(read_reg16(BP))); }
  462. pub unsafe fn instr32_4D() { write_reg32(EBP, dec32(read_reg32(EBP))); }
  463. pub unsafe fn instr16_4E() { write_reg16(SI, dec16(read_reg16(SI))); }
  464. pub unsafe fn instr32_4E() { write_reg32(ESI, dec32(read_reg32(ESI))); }
  465. pub unsafe fn instr16_4F() { write_reg16(DI, dec16(read_reg16(DI))); }
  466. pub unsafe fn instr32_4F() { write_reg32(EDI, dec32(read_reg32(EDI))); }
  467. pub unsafe fn push16_reg(r: i32) {
  468. return_on_pagefault!(push16(read_reg16(r)));
  469. }
  470. pub unsafe fn push32_reg(r: i32) {
  471. return_on_pagefault!(push32(read_reg32(r)));
  472. }
  473. pub unsafe fn instr16_50() { push16_reg(AX) }
  474. pub unsafe fn instr32_50() { push32_reg(EAX) }
  475. pub unsafe fn instr16_51() { push16_reg(CX) }
  476. pub unsafe fn instr32_51() { push32_reg(ECX) }
  477. pub unsafe fn instr16_52() { push16_reg(DX) }
  478. pub unsafe fn instr32_52() { push32_reg(EDX) }
  479. pub unsafe fn instr16_53() { push16_reg(BX) }
  480. pub unsafe fn instr32_53() { push32_reg(EBX) }
  481. pub unsafe fn instr16_54() { push16_reg(SP) }
  482. pub unsafe fn instr32_54() { push32_reg(ESP) }
  483. pub unsafe fn instr16_55() { push16_reg(BP) }
  484. pub unsafe fn instr32_55() { push32_reg(EBP) }
  485. pub unsafe fn instr16_56() { push16_reg(SI) }
  486. pub unsafe fn instr32_56() { push32_reg(ESI) }
  487. pub unsafe fn instr16_57() { push16_reg(DI) }
  488. pub unsafe fn instr32_57() { push32_reg(EDI) }
  489. pub unsafe fn instr16_58() { write_reg16(AX, return_on_pagefault!(pop16())); }
  490. pub unsafe fn instr32_58() { write_reg32(EAX, return_on_pagefault!(pop32s())); }
  491. pub unsafe fn instr16_59() { write_reg16(CX, return_on_pagefault!(pop16())); }
  492. pub unsafe fn instr32_59() { write_reg32(ECX, return_on_pagefault!(pop32s())); }
  493. pub unsafe fn instr16_5A() { write_reg16(DX, return_on_pagefault!(pop16())); }
  494. pub unsafe fn instr32_5A() { write_reg32(EDX, return_on_pagefault!(pop32s())); }
  495. pub unsafe fn instr16_5B() { write_reg16(BX, return_on_pagefault!(pop16())); }
  496. pub unsafe fn instr32_5B() { write_reg32(EBX, return_on_pagefault!(pop32s())); }
  497. pub unsafe fn instr16_5C() {
  498. write_reg16(SP, return_on_pagefault!(safe_read16(get_stack_pointer(0))));
  499. }
  500. pub unsafe fn instr32_5C() {
  501. write_reg32(
  502. ESP,
  503. return_on_pagefault!(safe_read32s(get_stack_pointer(0))),
  504. );
  505. }
  506. pub unsafe fn instr16_5D() { write_reg16(BP, return_on_pagefault!(pop16())); }
  507. pub unsafe fn instr32_5D() { write_reg32(EBP, return_on_pagefault!(pop32s())); }
  508. pub unsafe fn instr16_5E() { write_reg16(SI, return_on_pagefault!(pop16())); }
  509. pub unsafe fn instr32_5E() { write_reg32(ESI, return_on_pagefault!(pop32s())); }
  510. pub unsafe fn instr16_5F() { write_reg16(DI, return_on_pagefault!(pop16())); }
  511. pub unsafe fn instr32_5F() { write_reg32(EDI, return_on_pagefault!(pop32s())); }
  512. #[no_mangle]
  513. pub unsafe fn instr16_60() { pusha16(); }
  514. #[no_mangle]
  515. pub unsafe fn instr32_60() { pusha32(); }
  516. #[no_mangle]
  517. pub unsafe fn instr16_61() { popa16(); }
  518. #[no_mangle]
  519. pub unsafe fn instr32_61() { popa32(); }
  520. #[no_mangle]
  521. pub unsafe fn instr_62_reg(r2: i32, r: i32) {
  522. // bound
  523. dbg_log!("Unimplemented BOUND instruction");
  524. dbg_assert!(false);
  525. }
  526. #[no_mangle]
  527. pub unsafe fn instr_62_mem(addr: i32, r: i32) {
  528. dbg_log!("Unimplemented BOUND instruction");
  529. dbg_assert!(false);
  530. }
  531. pub unsafe fn arpl(seg: i32, r16: i32) -> i32 {
  532. *flags_changed &= !FLAG_ZERO;
  533. if (seg & 3) < (r16 & 3) {
  534. *flags |= FLAG_ZERO;
  535. seg & !3 | r16 & 3
  536. }
  537. else {
  538. *flags &= !FLAG_ZERO;
  539. seg
  540. }
  541. }
  542. #[no_mangle]
  543. pub unsafe fn instr_63_mem(addr: i32, r: i32) {
  544. if !*protected_mode || vm86_mode() {
  545. dbg_log!("arpl #ud");
  546. trigger_ud();
  547. return;
  548. }
  549. SAFE_READ_WRITE16!(___, addr, arpl(___, read_reg16(r)));
  550. }
  551. #[no_mangle]
  552. pub unsafe fn instr_63_reg(r1: i32, r: i32) {
  553. if !*protected_mode || vm86_mode() {
  554. dbg_log!("arpl #ud");
  555. trigger_ud();
  556. return;
  557. }
  558. write_reg16(r1, arpl(read_reg16(r1), read_reg16(r)));
  559. }
  560. pub unsafe fn instr_64() { segment_prefix_op(FS); }
  561. pub unsafe fn instr_65() { segment_prefix_op(GS); }
  562. pub unsafe fn instr_66() {
  563. // Operand-size override prefix
  564. *prefixes = (*prefixes as i32 | PREFIX_MASK_OPSIZE) as u8;
  565. run_prefix_instruction();
  566. *prefixes = 0;
  567. }
  568. pub unsafe fn instr_67() {
  569. // Address-size override prefix
  570. dbg_assert!(is_asize_32() == *is_32);
  571. *prefixes = (*prefixes as i32 | PREFIX_MASK_ADDRSIZE) as u8;
  572. run_prefix_instruction();
  573. *prefixes = 0;
  574. }
  575. pub unsafe fn instr16_68(imm16: i32) {
  576. return_on_pagefault!(push16(imm16));
  577. }
  578. pub unsafe fn instr32_68(imm32: i32) {
  579. return_on_pagefault!(push32(imm32));
  580. }
  581. pub unsafe fn instr16_69_mem(addr: i32, r: i32, imm: i32) {
  582. write_reg16(r, imul_reg16(return_on_pagefault!(safe_read16(addr)), imm));
  583. }
  584. pub unsafe fn instr16_69_reg(r1: i32, r: i32, imm: i32) {
  585. write_reg16(r, imul_reg16(read_reg16(r1), imm));
  586. }
  587. pub unsafe fn instr32_69_mem(addr: i32, r: i32, imm: i32) {
  588. write_reg32(r, imul_reg32(return_on_pagefault!(safe_read32s(addr)), imm));
  589. }
  590. pub unsafe fn instr32_69_reg(r1: i32, r: i32, imm: i32) {
  591. write_reg32(r, imul_reg32(read_reg32(r1), imm));
  592. }
  593. pub unsafe fn instr16_6A(imm8: i32) {
  594. return_on_pagefault!(push16(imm8));
  595. }
  596. pub unsafe fn instr32_6A(imm8: i32) {
  597. return_on_pagefault!(push32(imm8));
  598. }
  599. pub unsafe fn instr16_6B_mem(addr: i32, r: i32, imm: i32) {
  600. write_reg16(r, imul_reg16(return_on_pagefault!(safe_read16(addr)), imm));
  601. }
  602. pub unsafe fn instr16_6B_reg(r1: i32, r: i32, imm: i32) {
  603. write_reg16(r, imul_reg16(read_reg16(r1), imm));
  604. }
  605. pub unsafe fn instr32_6B_mem(addr: i32, r: i32, imm: i32) {
  606. write_reg32(r, imul_reg32(return_on_pagefault!(safe_read32s(addr)), imm));
  607. }
  608. pub unsafe fn instr32_6B_reg(r1: i32, r: i32, imm: i32) {
  609. write_reg32(r, imul_reg32(read_reg32(r1), imm));
  610. }
  611. pub unsafe fn instr_6C() { insb_no_rep(is_asize_32()); }
  612. pub unsafe fn instr16_6D() { insw_no_rep(is_asize_32()); }
  613. pub unsafe fn instr32_6D() { insd_no_rep(is_asize_32()); }
  614. pub unsafe fn instr_6E() { outsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  615. pub unsafe fn instr16_6F() {
  616. outsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  617. }
  618. pub unsafe fn instr32_6F() {
  619. outsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  620. }
  621. pub unsafe fn instr_80_0_mem(addr: i32, imm: i32) {
  622. SAFE_READ_WRITE8!(___, addr, add8(___, imm));
  623. }
  624. pub unsafe fn instr_80_0_reg(r1: i32, imm: i32) { write_reg8(r1, add8(read_reg8(r1), imm)); }
  625. pub unsafe fn instr_80_1_mem(addr: i32, imm: i32) {
  626. SAFE_READ_WRITE8!(___, addr, or8(___, imm));
  627. }
  628. pub unsafe fn instr_80_1_reg(r1: i32, imm: i32) { write_reg8(r1, or8(read_reg8(r1), imm)); }
  629. pub unsafe fn instr_80_2_mem(addr: i32, imm: i32) {
  630. SAFE_READ_WRITE8!(___, addr, adc8(___, imm));
  631. }
  632. pub unsafe fn instr_80_2_reg(r1: i32, imm: i32) { write_reg8(r1, adc8(read_reg8(r1), imm)); }
  633. pub unsafe fn instr_80_3_mem(addr: i32, imm: i32) {
  634. SAFE_READ_WRITE8!(___, addr, sbb8(___, imm));
  635. }
  636. pub unsafe fn instr_80_3_reg(r1: i32, imm: i32) { write_reg8(r1, sbb8(read_reg8(r1), imm)); }
  637. pub unsafe fn instr_80_4_mem(addr: i32, imm: i32) {
  638. SAFE_READ_WRITE8!(___, addr, and8(___, imm));
  639. }
  640. pub unsafe fn instr_80_4_reg(r1: i32, imm: i32) { write_reg8(r1, and8(read_reg8(r1), imm)); }
  641. pub unsafe fn instr_80_5_mem(addr: i32, imm: i32) {
  642. SAFE_READ_WRITE8!(___, addr, sub8(___, imm));
  643. }
  644. pub unsafe fn instr_80_5_reg(r1: i32, imm: i32) { write_reg8(r1, sub8(read_reg8(r1), imm)); }
  645. pub unsafe fn instr_80_6_mem(addr: i32, imm: i32) {
  646. SAFE_READ_WRITE8!(___, addr, xor8(___, imm));
  647. }
  648. pub unsafe fn instr_80_6_reg(r1: i32, imm: i32) { write_reg8(r1, xor8(read_reg8(r1), imm)); }
  649. pub unsafe fn instr_80_7_reg(r: i32, imm: i32) { cmp8(read_reg8(r), imm); }
  650. pub unsafe fn instr_80_7_mem(addr: i32, imm: i32) {
  651. cmp8(return_on_pagefault!(safe_read8(addr)), imm);
  652. }
  653. pub unsafe fn instr16_81_0_mem(addr: i32, imm: i32) {
  654. SAFE_READ_WRITE16!(___, addr, add16(___, imm));
  655. }
  656. pub unsafe fn instr16_81_0_reg(r1: i32, imm: i32) { write_reg16(r1, add16(read_reg16(r1), imm)); }
  657. pub unsafe fn instr16_81_1_mem(addr: i32, imm: i32) {
  658. SAFE_READ_WRITE16!(___, addr, or16(___, imm));
  659. }
  660. pub unsafe fn instr16_81_1_reg(r1: i32, imm: i32) { write_reg16(r1, or16(read_reg16(r1), imm)); }
  661. pub unsafe fn instr16_81_2_mem(addr: i32, imm: i32) {
  662. SAFE_READ_WRITE16!(___, addr, adc16(___, imm));
  663. }
  664. pub unsafe fn instr16_81_2_reg(r1: i32, imm: i32) { write_reg16(r1, adc16(read_reg16(r1), imm)); }
  665. pub unsafe fn instr16_81_3_mem(addr: i32, imm: i32) {
  666. SAFE_READ_WRITE16!(___, addr, sbb16(___, imm));
  667. }
  668. pub unsafe fn instr16_81_3_reg(r1: i32, imm: i32) { write_reg16(r1, sbb16(read_reg16(r1), imm)); }
  669. pub unsafe fn instr16_81_4_mem(addr: i32, imm: i32) {
  670. SAFE_READ_WRITE16!(___, addr, and16(___, imm));
  671. }
  672. pub unsafe fn instr16_81_4_reg(r1: i32, imm: i32) { write_reg16(r1, and16(read_reg16(r1), imm)); }
  673. pub unsafe fn instr16_81_5_mem(addr: i32, imm: i32) {
  674. SAFE_READ_WRITE16!(___, addr, sub16(___, imm));
  675. }
  676. pub unsafe fn instr16_81_5_reg(r1: i32, imm: i32) { write_reg16(r1, sub16(read_reg16(r1), imm)); }
  677. pub unsafe fn instr16_81_6_mem(addr: i32, imm: i32) {
  678. SAFE_READ_WRITE16!(___, addr, xor16(___, imm));
  679. }
  680. pub unsafe fn instr16_81_6_reg(r1: i32, imm: i32) { write_reg16(r1, xor16(read_reg16(r1), imm)); }
  681. pub unsafe fn instr16_81_7_reg(r: i32, imm: i32) { cmp16(read_reg16(r), imm); }
  682. pub unsafe fn instr16_81_7_mem(addr: i32, imm: i32) {
  683. cmp16(return_on_pagefault!(safe_read16(addr)), imm);
  684. }
  685. pub unsafe fn instr32_81_0_mem(addr: i32, imm: i32) {
  686. SAFE_READ_WRITE32!(___, addr, add32(___, imm));
  687. }
  688. pub unsafe fn instr32_81_0_reg(r1: i32, imm: i32) { write_reg32(r1, add32(read_reg32(r1), imm)); }
  689. pub unsafe fn instr32_81_1_mem(addr: i32, imm: i32) {
  690. SAFE_READ_WRITE32!(___, addr, or32(___, imm));
  691. }
  692. pub unsafe fn instr32_81_1_reg(r1: i32, imm: i32) { write_reg32(r1, or32(read_reg32(r1), imm)); }
  693. pub unsafe fn instr32_81_2_mem(addr: i32, imm: i32) {
  694. SAFE_READ_WRITE32!(___, addr, adc32(___, imm));
  695. }
  696. pub unsafe fn instr32_81_2_reg(r1: i32, imm: i32) { write_reg32(r1, adc32(read_reg32(r1), imm)); }
  697. pub unsafe fn instr32_81_3_mem(addr: i32, imm: i32) {
  698. SAFE_READ_WRITE32!(___, addr, sbb32(___, imm));
  699. }
  700. pub unsafe fn instr32_81_3_reg(r1: i32, imm: i32) { write_reg32(r1, sbb32(read_reg32(r1), imm)); }
  701. pub unsafe fn instr32_81_4_mem(addr: i32, imm: i32) {
  702. SAFE_READ_WRITE32!(___, addr, and32(___, imm));
  703. }
  704. pub unsafe fn instr32_81_4_reg(r1: i32, imm: i32) { write_reg32(r1, and32(read_reg32(r1), imm)); }
  705. pub unsafe fn instr32_81_5_mem(addr: i32, imm: i32) {
  706. SAFE_READ_WRITE32!(___, addr, sub32(___, imm));
  707. }
  708. pub unsafe fn instr32_81_5_reg(r1: i32, imm: i32) { write_reg32(r1, sub32(read_reg32(r1), imm)); }
  709. pub unsafe fn instr32_81_6_mem(addr: i32, imm: i32) {
  710. SAFE_READ_WRITE32!(___, addr, xor32(___, imm));
  711. }
  712. pub unsafe fn instr32_81_6_reg(r1: i32, imm: i32) { write_reg32(r1, xor32(read_reg32(r1), imm)); }
  713. pub unsafe fn instr32_81_7_reg(r: i32, imm: i32) { cmp32(read_reg32(r), imm); }
  714. pub unsafe fn instr32_81_7_mem(addr: i32, imm: i32) {
  715. cmp32(return_on_pagefault!(safe_read32s(addr)), imm);
  716. }
  717. pub unsafe fn instr_82_0_mem(addr: i32, imm: i32) {
  718. SAFE_READ_WRITE8!(___, addr, add8(___, imm));
  719. }
  720. pub unsafe fn instr_82_0_reg(r1: i32, imm: i32) { write_reg8(r1, add8(read_reg8(r1), imm)); }
  721. pub unsafe fn instr_82_1_mem(addr: i32, imm: i32) {
  722. SAFE_READ_WRITE8!(___, addr, or8(___, imm));
  723. }
  724. pub unsafe fn instr_82_1_reg(r1: i32, imm: i32) { write_reg8(r1, or8(read_reg8(r1), imm)); }
  725. pub unsafe fn instr_82_2_mem(addr: i32, imm: i32) {
  726. SAFE_READ_WRITE8!(___, addr, adc8(___, imm));
  727. }
  728. pub unsafe fn instr_82_2_reg(r1: i32, imm: i32) { write_reg8(r1, adc8(read_reg8(r1), imm)); }
  729. pub unsafe fn instr_82_3_mem(addr: i32, imm: i32) {
  730. SAFE_READ_WRITE8!(___, addr, sbb8(___, imm));
  731. }
  732. pub unsafe fn instr_82_3_reg(r1: i32, imm: i32) { write_reg8(r1, sbb8(read_reg8(r1), imm)); }
  733. pub unsafe fn instr_82_4_mem(addr: i32, imm: i32) {
  734. SAFE_READ_WRITE8!(___, addr, and8(___, imm));
  735. }
  736. pub unsafe fn instr_82_4_reg(r1: i32, imm: i32) { write_reg8(r1, and8(read_reg8(r1), imm)); }
  737. pub unsafe fn instr_82_5_mem(addr: i32, imm: i32) {
  738. SAFE_READ_WRITE8!(___, addr, sub8(___, imm));
  739. }
  740. pub unsafe fn instr_82_5_reg(r1: i32, imm: i32) { write_reg8(r1, sub8(read_reg8(r1), imm)); }
  741. pub unsafe fn instr_82_6_mem(addr: i32, imm: i32) {
  742. SAFE_READ_WRITE8!(___, addr, xor8(___, imm));
  743. }
  744. pub unsafe fn instr_82_6_reg(r1: i32, imm: i32) { write_reg8(r1, xor8(read_reg8(r1), imm)); }
  745. pub unsafe fn instr_82_7_reg(r: i32, imm: i32) { cmp8(read_reg8(r), imm); }
  746. pub unsafe fn instr_82_7_mem(addr: i32, imm: i32) {
  747. cmp8(return_on_pagefault!(safe_read8(addr)), imm);
  748. }
  749. pub unsafe fn instr16_83_0_mem(addr: i32, imm: i32) {
  750. SAFE_READ_WRITE16!(___, addr, add16(___, imm));
  751. }
  752. pub unsafe fn instr16_83_0_reg(r1: i32, imm: i32) { write_reg16(r1, add16(read_reg16(r1), imm)); }
  753. pub unsafe fn instr16_83_1_mem(addr: i32, imm: i32) {
  754. SAFE_READ_WRITE16!(___, addr, or16(___, imm));
  755. }
  756. pub unsafe fn instr16_83_1_reg(r1: i32, imm: i32) { write_reg16(r1, or16(read_reg16(r1), imm)); }
  757. pub unsafe fn instr16_83_2_mem(addr: i32, imm: i32) {
  758. SAFE_READ_WRITE16!(___, addr, adc16(___, imm));
  759. }
  760. pub unsafe fn instr16_83_2_reg(r1: i32, imm: i32) { write_reg16(r1, adc16(read_reg16(r1), imm)); }
  761. pub unsafe fn instr16_83_3_mem(addr: i32, imm: i32) {
  762. SAFE_READ_WRITE16!(___, addr, sbb16(___, imm));
  763. }
  764. pub unsafe fn instr16_83_3_reg(r1: i32, imm: i32) { write_reg16(r1, sbb16(read_reg16(r1), imm)); }
  765. pub unsafe fn instr16_83_4_mem(addr: i32, imm: i32) {
  766. SAFE_READ_WRITE16!(___, addr, and16(___, imm));
  767. }
  768. pub unsafe fn instr16_83_4_reg(r1: i32, imm: i32) { write_reg16(r1, and16(read_reg16(r1), imm)); }
  769. pub unsafe fn instr16_83_5_mem(addr: i32, imm: i32) {
  770. SAFE_READ_WRITE16!(___, addr, sub16(___, imm));
  771. }
  772. pub unsafe fn instr16_83_5_reg(r1: i32, imm: i32) { write_reg16(r1, sub16(read_reg16(r1), imm)); }
  773. pub unsafe fn instr16_83_6_mem(addr: i32, imm: i32) {
  774. SAFE_READ_WRITE16!(___, addr, xor16(___, imm));
  775. }
  776. pub unsafe fn instr16_83_6_reg(r1: i32, imm: i32) { write_reg16(r1, xor16(read_reg16(r1), imm)); }
  777. pub unsafe fn instr16_83_7_reg(r: i32, imm: i32) { cmp16(read_reg16(r), imm); }
  778. pub unsafe fn instr16_83_7_mem(addr: i32, imm: i32) {
  779. cmp16(return_on_pagefault!(safe_read16(addr)), imm);
  780. }
  781. pub unsafe fn instr32_83_0_mem(addr: i32, imm: i32) {
  782. SAFE_READ_WRITE32!(___, addr, add32(___, imm));
  783. }
  784. pub unsafe fn instr32_83_0_reg(r1: i32, imm: i32) { write_reg32(r1, add32(read_reg32(r1), imm)); }
  785. pub unsafe fn instr32_83_1_mem(addr: i32, imm: i32) {
  786. SAFE_READ_WRITE32!(___, addr, or32(___, imm));
  787. }
  788. pub unsafe fn instr32_83_1_reg(r1: i32, imm: i32) { write_reg32(r1, or32(read_reg32(r1), imm)); }
  789. pub unsafe fn instr32_83_2_mem(addr: i32, imm: i32) {
  790. SAFE_READ_WRITE32!(___, addr, adc32(___, imm));
  791. }
  792. pub unsafe fn instr32_83_2_reg(r1: i32, imm: i32) { write_reg32(r1, adc32(read_reg32(r1), imm)); }
  793. pub unsafe fn instr32_83_3_mem(addr: i32, imm: i32) {
  794. SAFE_READ_WRITE32!(___, addr, sbb32(___, imm));
  795. }
  796. pub unsafe fn instr32_83_3_reg(r1: i32, imm: i32) { write_reg32(r1, sbb32(read_reg32(r1), imm)); }
  797. pub unsafe fn instr32_83_4_mem(addr: i32, imm: i32) {
  798. SAFE_READ_WRITE32!(___, addr, and32(___, imm));
  799. }
  800. pub unsafe fn instr32_83_4_reg(r1: i32, imm: i32) { write_reg32(r1, and32(read_reg32(r1), imm)); }
  801. pub unsafe fn instr32_83_5_mem(addr: i32, imm: i32) {
  802. SAFE_READ_WRITE32!(___, addr, sub32(___, imm));
  803. }
  804. pub unsafe fn instr32_83_5_reg(r1: i32, imm: i32) { write_reg32(r1, sub32(read_reg32(r1), imm)); }
  805. pub unsafe fn instr32_83_6_mem(addr: i32, imm: i32) {
  806. SAFE_READ_WRITE32!(___, addr, xor32(___, imm));
  807. }
  808. pub unsafe fn instr32_83_6_reg(r1: i32, imm: i32) { write_reg32(r1, xor32(read_reg32(r1), imm)); }
  809. pub unsafe fn instr32_83_7_reg(r: i32, imm: i32) { cmp32(read_reg32(r), imm); }
  810. pub unsafe fn instr32_83_7_mem(addr: i32, imm: i32) {
  811. cmp32(return_on_pagefault!(safe_read32s(addr)), imm);
  812. }
  813. pub unsafe fn instr_84_mem(addr: i32, r: i32) {
  814. test8(return_on_pagefault!(safe_read8(addr)), read_reg8(r));
  815. }
  816. pub unsafe fn instr_84_reg(r1: i32, r: i32) { test8(read_reg8(r1), read_reg8(r)); }
  817. pub unsafe fn instr16_85_mem(addr: i32, r: i32) {
  818. test16(return_on_pagefault!(safe_read16(addr)), read_reg16(r));
  819. }
  820. pub unsafe fn instr16_85_reg(r1: i32, r: i32) { test16(read_reg16(r1), read_reg16(r)); }
  821. pub unsafe fn instr32_85_mem(addr: i32, r: i32) {
  822. test32(return_on_pagefault!(safe_read32s(addr)), read_reg32(r));
  823. }
  824. pub unsafe fn instr32_85_reg(r1: i32, r: i32) { test32(read_reg32(r1), read_reg32(r)); }
  825. pub unsafe fn instr_86_mem(addr: i32, r: i32) {
  826. SAFE_READ_WRITE8!(___, addr, xchg8(___, r));
  827. }
  828. pub unsafe fn instr_86_reg(r1: i32, r: i32) { write_reg8(r1, xchg8(read_reg8(r1), r)); }
  829. pub unsafe fn instr16_87_mem(addr: i32, r: i32) {
  830. SAFE_READ_WRITE16!(___, addr, xchg16(___, r));
  831. }
  832. pub unsafe fn instr16_87_reg(r1: i32, r: i32) { write_reg16(r1, xchg16(read_reg16(r1), r)); }
  833. pub unsafe fn instr32_87_mem(addr: i32, r: i32) {
  834. SAFE_READ_WRITE32!(___, addr, xchg32(___, r));
  835. }
  836. pub unsafe fn instr32_87_reg(r1: i32, r: i32) { write_reg32(r1, xchg32(read_reg32(r1), r)); }
  837. pub unsafe fn instr_88_reg(r2: i32, r: i32) { write_reg8(r2, read_reg8(r)); }
  838. pub unsafe fn instr_88_mem(addr: i32, r: i32) {
  839. return_on_pagefault!(safe_write8(addr, read_reg8(r)));
  840. }
  841. pub unsafe fn instr16_89_reg(r2: i32, r: i32) { write_reg16(r2, read_reg16(r)); }
  842. pub unsafe fn instr16_89_mem(addr: i32, r: i32) {
  843. return_on_pagefault!(safe_write16(addr, read_reg16(r)));
  844. }
  845. pub unsafe fn instr32_89_reg(r2: i32, r: i32) { write_reg32(r2, read_reg32(r)); }
  846. pub unsafe fn instr32_89_mem(addr: i32, r: i32) {
  847. return_on_pagefault!(safe_write32(addr, read_reg32(r)));
  848. }
  849. pub unsafe fn instr_8A_mem(addr: i32, r: i32) {
  850. write_reg8(r, return_on_pagefault!(safe_read8(addr)));
  851. }
  852. pub unsafe fn instr_8A_reg(r1: i32, r: i32) { write_reg8(r, read_reg8(r1)); }
  853. pub unsafe fn instr16_8B_mem(addr: i32, r: i32) {
  854. write_reg16(r, return_on_pagefault!(safe_read16(addr)));
  855. }
  856. pub unsafe fn instr16_8B_reg(r1: i32, r: i32) { write_reg16(r, read_reg16(r1)); }
  857. pub unsafe fn instr32_8B_mem(addr: i32, r: i32) {
  858. write_reg32(r, return_on_pagefault!(safe_read32s(addr)));
  859. }
  860. pub unsafe fn instr32_8B_reg(r1: i32, r: i32) { write_reg32(r, read_reg32(r1)); }
  861. pub unsafe fn instr_8C_check_sreg(seg: i32) -> bool {
  862. if seg >= 6 {
  863. dbg_log!("mov sreg #ud");
  864. trigger_ud();
  865. return false;
  866. }
  867. else {
  868. return true;
  869. };
  870. }
  871. pub unsafe fn instr16_8C_reg(r: i32, seg: i32) {
  872. if instr_8C_check_sreg(seg) {
  873. write_reg16(r, *sreg.offset(seg as isize) as i32);
  874. };
  875. }
  876. pub unsafe fn instr16_8C_mem(addr: i32, seg: i32) {
  877. if instr_8C_check_sreg(seg) {
  878. return_on_pagefault!(safe_write16(addr, *sreg.offset(seg as isize) as i32));
  879. };
  880. }
  881. pub unsafe fn instr32_8C_reg(r: i32, seg: i32) {
  882. if instr_8C_check_sreg(seg) {
  883. write_reg32(r, *sreg.offset(seg as isize) as i32);
  884. };
  885. }
  886. pub unsafe fn instr32_8C_mem(addr: i32, seg: i32) {
  887. if instr_8C_check_sreg(seg) {
  888. return_on_pagefault!(safe_write16(addr, *sreg.offset(seg as isize) as i32));
  889. };
  890. }
  891. pub unsafe fn instr16_8D_reg(r: i32, r2: i32) {
  892. dbg_log!("lea #ud");
  893. trigger_ud();
  894. }
  895. pub unsafe fn instr16_8D_mem(modrm_byte: i32, r: i32) {
  896. // lea
  897. *prefixes = (*prefixes as i32 | SEG_PREFIX_ZERO) as u8;
  898. if let Ok(addr) = modrm_resolve(modrm_byte) {
  899. write_reg16(r, addr);
  900. }
  901. *prefixes = 0;
  902. }
  903. pub unsafe fn instr32_8D_reg(r: i32, r2: i32) {
  904. dbg_log!("lea #ud");
  905. trigger_ud();
  906. }
  907. pub unsafe fn instr32_8D_mem(modrm_byte: i32, r: i32) {
  908. // lea
  909. // override prefix, so modrm_resolve does not return the segment part
  910. *prefixes = (*prefixes as i32 | SEG_PREFIX_ZERO) as u8;
  911. if let Ok(addr) = modrm_resolve(modrm_byte) {
  912. write_reg32(r, addr);
  913. }
  914. *prefixes = 0;
  915. }
  916. #[no_mangle]
  917. pub unsafe fn instr_8E_helper(data: i32, mod_0: i32) {
  918. if mod_0 == ES || mod_0 == SS || mod_0 == DS || mod_0 == FS || mod_0 == GS {
  919. if !switch_seg(mod_0, data) {
  920. return;
  921. }
  922. }
  923. else {
  924. dbg_log!("mov sreg #ud");
  925. trigger_ud();
  926. };
  927. }
  928. #[no_mangle]
  929. pub unsafe fn instr_8E_mem(addr: i32, r: i32) {
  930. instr_8E_helper(return_on_pagefault!(safe_read16(addr)), r);
  931. }
  932. #[no_mangle]
  933. pub unsafe fn instr_8E_reg(r1: i32, r: i32) { instr_8E_helper(read_reg16(r1), r); }
  934. pub unsafe fn instr16_8F_0_mem(modrm_byte: i32) {
  935. // pop
  936. // Update esp *before* resolving the address
  937. adjust_stack_reg(2);
  938. match modrm_resolve(modrm_byte) {
  939. Err(()) => {
  940. // a pagefault happened, reset esp
  941. adjust_stack_reg(-2);
  942. },
  943. Ok(addr) => {
  944. adjust_stack_reg(-2);
  945. let stack_value = return_on_pagefault!(safe_read16(get_stack_pointer(0)));
  946. return_on_pagefault!(safe_write16(addr, stack_value));
  947. adjust_stack_reg(2);
  948. },
  949. }
  950. }
  951. pub unsafe fn instr16_8F_0_reg(r: i32) { write_reg16(r, return_on_pagefault!(pop16())); }
  952. pub unsafe fn instr32_8F_0_mem(modrm_byte: i32) {
  953. // Update esp *before* resolving the address
  954. adjust_stack_reg(4);
  955. match modrm_resolve(modrm_byte) {
  956. Err(()) => {
  957. // a pagefault happened, reset esp
  958. adjust_stack_reg(-4);
  959. },
  960. Ok(addr) => {
  961. adjust_stack_reg(-4);
  962. let stack_value = return_on_pagefault!(safe_read32s(get_stack_pointer(0)));
  963. return_on_pagefault!(safe_write32(addr, stack_value));
  964. adjust_stack_reg(4);
  965. },
  966. }
  967. }
  968. pub unsafe fn instr32_8F_0_reg(r: i32) { write_reg32(r, return_on_pagefault!(pop32s())); }
  969. pub unsafe fn instr_90() {}
  970. pub unsafe fn instr16_91() { xchg16r(CX); }
  971. pub unsafe fn instr32_91() { xchg32r(ECX); }
  972. pub unsafe fn instr16_92() { xchg16r(DX); }
  973. pub unsafe fn instr32_92() { xchg32r(EDX); }
  974. pub unsafe fn instr16_93() { xchg16r(BX); }
  975. pub unsafe fn instr32_93() { xchg32r(EBX); }
  976. pub unsafe fn instr16_94() { xchg16r(SP); }
  977. pub unsafe fn instr32_94() { xchg32r(ESP); }
  978. pub unsafe fn instr16_95() { xchg16r(BP); }
  979. pub unsafe fn instr32_95() { xchg32r(EBP); }
  980. pub unsafe fn instr16_96() { xchg16r(SI); }
  981. pub unsafe fn instr32_96() { xchg32r(ESI); }
  982. pub unsafe fn instr16_97() { xchg16r(DI); }
  983. pub unsafe fn instr32_97() { xchg32r(EDI); }
  984. pub unsafe fn instr16_98() { write_reg16(AX, read_reg8(AL) << 24 >> 24); }
  985. pub unsafe fn instr32_98() { write_reg32(EAX, read_reg16(AX) as i16 as i32); }
  986. pub unsafe fn instr16_99() { write_reg16(DX, read_reg16(AX) as i16 as i32 >> 15); }
  987. pub unsafe fn instr32_99() { write_reg32(EDX, read_reg32(EAX) >> 31); }
  988. #[no_mangle]
  989. pub unsafe fn instr16_9A(new_ip: i32, new_cs: i32) {
  990. // callf
  991. far_jump(new_ip, new_cs, true, false);
  992. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  993. }
  994. #[no_mangle]
  995. pub unsafe fn instr32_9A(new_ip: i32, new_cs: i32) {
  996. if !*protected_mode || vm86_mode() {
  997. if 0 != new_ip as u32 & 0xFFFF0000 {
  998. dbg_assert!(false);
  999. }
  1000. }
  1001. far_jump(new_ip, new_cs, true, true);
  1002. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  1003. }
  1004. #[no_mangle]
  1005. pub unsafe fn instr_9B() {
  1006. // fwait: check for pending fpu exceptions
  1007. if *cr & (CR0_MP | CR0_TS) == CR0_MP | CR0_TS {
  1008. // Note: Different from task_switch_test
  1009. // Triggers when TS and MP bits are set (EM bit is ignored)
  1010. trigger_nm();
  1011. }
  1012. else {
  1013. fwait();
  1014. };
  1015. }
  1016. #[no_mangle]
  1017. pub unsafe fn instr_9C_check() -> bool { 0 != *flags & FLAG_VM && getiopl() < 3 }
  1018. #[no_mangle]
  1019. pub unsafe fn instr16_9C() {
  1020. // pushf
  1021. if instr_9C_check() {
  1022. dbg_assert!(*protected_mode);
  1023. dbg_log!("pushf #gp");
  1024. trigger_gp(0);
  1025. }
  1026. else {
  1027. return_on_pagefault!(push16(get_eflags()));
  1028. };
  1029. }
  1030. #[no_mangle]
  1031. pub unsafe fn instr32_9C() {
  1032. // pushf
  1033. if instr_9C_check() {
  1034. // trap to virtual 8086 monitor
  1035. dbg_assert!(*protected_mode);
  1036. dbg_log!("pushf #gp");
  1037. trigger_gp(0);
  1038. }
  1039. else {
  1040. // vm and rf flag are cleared in image stored on the stack
  1041. return_on_pagefault!(push32(get_eflags() & 0xFCFFFF));
  1042. };
  1043. }
  1044. pub unsafe fn instr16_9D() {
  1045. // popf
  1046. if 0 != *flags & FLAG_VM && getiopl() < 3 {
  1047. dbg_log!("popf #gp");
  1048. trigger_gp(0);
  1049. return;
  1050. }
  1051. let old_eflags = *flags;
  1052. update_eflags(*flags & !0xFFFF | return_on_pagefault!(pop16()));
  1053. if old_eflags & FLAG_INTERRUPT == 0 && *flags & FLAG_INTERRUPT != 0 {
  1054. handle_irqs();
  1055. }
  1056. }
  1057. pub unsafe fn instr32_9D() {
  1058. // popf
  1059. if 0 != *flags & FLAG_VM && getiopl() < 3 {
  1060. dbg_log!("popf #gp");
  1061. trigger_gp(0);
  1062. return;
  1063. }
  1064. let old_eflags = *flags;
  1065. update_eflags(return_on_pagefault!(pop32s()));
  1066. if old_eflags & FLAG_INTERRUPT == 0 && *flags & FLAG_INTERRUPT != 0 {
  1067. handle_irqs();
  1068. }
  1069. }
  1070. pub unsafe fn instr_9E() {
  1071. // sahf
  1072. *flags = *flags & !255 | read_reg8(AH);
  1073. *flags = *flags & FLAGS_MASK | FLAGS_DEFAULT;
  1074. *flags_changed &= !255;
  1075. }
  1076. pub unsafe fn instr_9F() {
  1077. // lahf
  1078. write_reg8(AH, get_eflags());
  1079. }
  1080. pub unsafe fn instr_A0(moffs: i32) {
  1081. // mov
  1082. let data = return_on_pagefault!(safe_read8(return_on_pagefault!(get_seg_prefix_ds(moffs))));
  1083. write_reg8(AL, data);
  1084. }
  1085. pub unsafe fn instr16_A1(moffs: i32) {
  1086. // mov
  1087. let data = return_on_pagefault!(safe_read16(return_on_pagefault!(get_seg_prefix_ds(moffs))));
  1088. write_reg16(AX, data);
  1089. }
  1090. pub unsafe fn instr32_A1(moffs: i32) {
  1091. let data = return_on_pagefault!(safe_read32s(return_on_pagefault!(get_seg_prefix_ds(moffs))));
  1092. write_reg32(EAX, data);
  1093. }
  1094. pub unsafe fn instr_A2(moffs: i32) {
  1095. // mov
  1096. return_on_pagefault!(safe_write8(
  1097. return_on_pagefault!(get_seg_prefix_ds(moffs)),
  1098. read_reg8(AL)
  1099. ));
  1100. }
  1101. pub unsafe fn instr16_A3(moffs: i32) {
  1102. // mov
  1103. return_on_pagefault!(safe_write16(
  1104. return_on_pagefault!(get_seg_prefix_ds(moffs)),
  1105. read_reg16(AX)
  1106. ));
  1107. }
  1108. pub unsafe fn instr32_A3(moffs: i32) {
  1109. return_on_pagefault!(safe_write32(
  1110. return_on_pagefault!(get_seg_prefix_ds(moffs)),
  1111. read_reg32(EAX)
  1112. ));
  1113. }
  1114. pub unsafe fn instr_A4() { movsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  1115. pub unsafe fn instr16_A5() {
  1116. movsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  1117. }
  1118. pub unsafe fn instr32_A5() {
  1119. movsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  1120. }
  1121. pub unsafe fn instr_A6() { cmpsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  1122. pub unsafe fn instr16_A7() {
  1123. cmpsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  1124. }
  1125. pub unsafe fn instr32_A7() {
  1126. cmpsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  1127. }
  1128. pub unsafe fn instr_A8(imm8: i32) { test8(read_reg8(AL), imm8); }
  1129. pub unsafe fn instr16_A9(imm16: i32) { test16(read_reg16(AX), imm16); }
  1130. pub unsafe fn instr32_A9(imm32: i32) { test32(read_reg32(EAX), imm32); }
  1131. pub unsafe fn instr_AA() { stosb_no_rep(is_asize_32()); }
  1132. pub unsafe fn instr16_AB() { stosw_no_rep(is_asize_32()); }
  1133. pub unsafe fn instr32_AB() { stosd_no_rep(is_asize_32()); }
  1134. pub unsafe fn instr_AC() { lodsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  1135. pub unsafe fn instr16_AD() {
  1136. lodsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  1137. }
  1138. pub unsafe fn instr32_AD() {
  1139. lodsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  1140. }
  1141. pub unsafe fn instr_AE() { scasb_no_rep(is_asize_32()); }
  1142. pub unsafe fn instr16_AF() { scasw_no_rep(is_asize_32()); }
  1143. pub unsafe fn instr32_AF() { scasd_no_rep(is_asize_32()); }
  1144. pub unsafe fn instr_B0(imm8: i32) { write_reg8(AL, imm8); }
  1145. pub unsafe fn instr_B1(imm8: i32) { write_reg8(CL, imm8); }
  1146. pub unsafe fn instr_B2(imm8: i32) { write_reg8(DL, imm8); }
  1147. pub unsafe fn instr_B3(imm8: i32) { write_reg8(BL, imm8); }
  1148. pub unsafe fn instr_B4(imm8: i32) { write_reg8(AH, imm8); }
  1149. pub unsafe fn instr_B5(imm8: i32) { write_reg8(CH, imm8); }
  1150. pub unsafe fn instr_B6(imm8: i32) { write_reg8(DH, imm8); }
  1151. pub unsafe fn instr_B7(imm8: i32) { write_reg8(BH, imm8); }
  1152. pub unsafe fn instr16_B8(imm: i32) { write_reg16(AX, imm); }
  1153. pub unsafe fn instr32_B8(imm: i32) { write_reg32(EAX, imm); }
  1154. pub unsafe fn instr16_B9(imm: i32) { write_reg16(CX, imm); }
  1155. pub unsafe fn instr32_B9(imm: i32) { write_reg32(ECX, imm); }
  1156. pub unsafe fn instr16_BA(imm: i32) { write_reg16(DX, imm); }
  1157. pub unsafe fn instr32_BA(imm: i32) { write_reg32(EDX, imm); }
  1158. pub unsafe fn instr16_BB(imm: i32) { write_reg16(BX, imm); }
  1159. pub unsafe fn instr32_BB(imm: i32) { write_reg32(EBX, imm); }
  1160. pub unsafe fn instr16_BC(imm: i32) { write_reg16(SP, imm); }
  1161. pub unsafe fn instr32_BC(imm: i32) { write_reg32(ESP, imm); }
  1162. pub unsafe fn instr16_BD(imm: i32) { write_reg16(BP, imm); }
  1163. pub unsafe fn instr32_BD(imm: i32) { write_reg32(EBP, imm); }
  1164. pub unsafe fn instr16_BE(imm: i32) { write_reg16(SI, imm); }
  1165. pub unsafe fn instr32_BE(imm: i32) { write_reg32(ESI, imm); }
  1166. pub unsafe fn instr16_BF(imm: i32) { write_reg16(DI, imm); }
  1167. pub unsafe fn instr32_BF(imm: i32) { write_reg32(EDI, imm); }
  1168. pub unsafe fn instr_C0_0_mem(addr: i32, imm: i32) {
  1169. SAFE_READ_WRITE8!(___, addr, rol8(___, imm & 31));
  1170. }
  1171. pub unsafe fn instr_C0_0_reg(r1: i32, imm: i32) { write_reg8(r1, rol8(read_reg8(r1), imm & 31)); }
  1172. pub unsafe fn instr_C0_1_mem(addr: i32, imm: i32) {
  1173. SAFE_READ_WRITE8!(___, addr, ror8(___, imm & 31));
  1174. }
  1175. pub unsafe fn instr_C0_1_reg(r1: i32, imm: i32) { write_reg8(r1, ror8(read_reg8(r1), imm & 31)); }
  1176. pub unsafe fn instr_C0_2_mem(addr: i32, imm: i32) {
  1177. SAFE_READ_WRITE8!(___, addr, rcl8(___, imm & 31));
  1178. }
  1179. pub unsafe fn instr_C0_2_reg(r1: i32, imm: i32) { write_reg8(r1, rcl8(read_reg8(r1), imm & 31)); }
  1180. pub unsafe fn instr_C0_3_mem(addr: i32, imm: i32) {
  1181. SAFE_READ_WRITE8!(___, addr, rcr8(___, imm & 31));
  1182. }
  1183. pub unsafe fn instr_C0_3_reg(r1: i32, imm: i32) { write_reg8(r1, rcr8(read_reg8(r1), imm & 31)); }
  1184. pub unsafe fn instr_C0_4_mem(addr: i32, imm: i32) {
  1185. SAFE_READ_WRITE8!(___, addr, shl8(___, imm & 31));
  1186. }
  1187. pub unsafe fn instr_C0_4_reg(r1: i32, imm: i32) { write_reg8(r1, shl8(read_reg8(r1), imm & 31)); }
  1188. pub unsafe fn instr_C0_5_mem(addr: i32, imm: i32) {
  1189. SAFE_READ_WRITE8!(___, addr, shr8(___, imm & 31));
  1190. }
  1191. pub unsafe fn instr_C0_5_reg(r1: i32, imm: i32) { write_reg8(r1, shr8(read_reg8(r1), imm & 31)); }
  1192. pub unsafe fn instr_C0_6_mem(addr: i32, imm: i32) {
  1193. SAFE_READ_WRITE8!(___, addr, shl8(___, imm & 31));
  1194. }
  1195. pub unsafe fn instr_C0_6_reg(r1: i32, imm: i32) { write_reg8(r1, shl8(read_reg8(r1), imm & 31)); }
  1196. pub unsafe fn instr_C0_7_mem(addr: i32, imm: i32) {
  1197. SAFE_READ_WRITE8!(___, addr, sar8(___, imm & 31));
  1198. }
  1199. pub unsafe fn instr_C0_7_reg(r1: i32, imm: i32) { write_reg8(r1, sar8(read_reg8(r1), imm & 31)); }
  1200. pub unsafe fn instr16_C1_0_mem(addr: i32, imm: i32) {
  1201. SAFE_READ_WRITE16!(___, addr, rol16(___, imm & 31));
  1202. }
  1203. pub unsafe fn instr16_C1_0_reg(r1: i32, imm: i32) {
  1204. write_reg16(r1, rol16(read_reg16(r1), imm & 31));
  1205. }
  1206. pub unsafe fn instr16_C1_1_mem(addr: i32, imm: i32) {
  1207. SAFE_READ_WRITE16!(___, addr, ror16(___, imm & 31));
  1208. }
  1209. pub unsafe fn instr16_C1_1_reg(r1: i32, imm: i32) {
  1210. write_reg16(r1, ror16(read_reg16(r1), imm & 31));
  1211. }
  1212. pub unsafe fn instr16_C1_2_mem(addr: i32, imm: i32) {
  1213. SAFE_READ_WRITE16!(___, addr, rcl16(___, imm & 31));
  1214. }
  1215. pub unsafe fn instr16_C1_2_reg(r1: i32, imm: i32) {
  1216. write_reg16(r1, rcl16(read_reg16(r1), imm & 31));
  1217. }
  1218. pub unsafe fn instr16_C1_3_mem(addr: i32, imm: i32) {
  1219. SAFE_READ_WRITE16!(___, addr, rcr16(___, imm & 31));
  1220. }
  1221. pub unsafe fn instr16_C1_3_reg(r1: i32, imm: i32) {
  1222. write_reg16(r1, rcr16(read_reg16(r1), imm & 31));
  1223. }
  1224. pub unsafe fn instr16_C1_4_mem(addr: i32, imm: i32) {
  1225. SAFE_READ_WRITE16!(___, addr, shl16(___, imm & 31));
  1226. }
  1227. pub unsafe fn instr16_C1_4_reg(r1: i32, imm: i32) {
  1228. write_reg16(r1, shl16(read_reg16(r1), imm & 31));
  1229. }
  1230. pub unsafe fn instr16_C1_5_mem(addr: i32, imm: i32) {
  1231. SAFE_READ_WRITE16!(___, addr, shr16(___, imm & 31));
  1232. }
  1233. pub unsafe fn instr16_C1_5_reg(r1: i32, imm: i32) {
  1234. write_reg16(r1, shr16(read_reg16(r1), imm & 31));
  1235. }
  1236. pub unsafe fn instr16_C1_6_mem(addr: i32, imm: i32) {
  1237. SAFE_READ_WRITE16!(___, addr, shl16(___, imm & 31));
  1238. }
  1239. pub unsafe fn instr16_C1_6_reg(r1: i32, imm: i32) {
  1240. write_reg16(r1, shl16(read_reg16(r1), imm & 31));
  1241. }
  1242. pub unsafe fn instr16_C1_7_mem(addr: i32, imm: i32) {
  1243. SAFE_READ_WRITE16!(___, addr, sar16(___, imm & 31));
  1244. }
  1245. pub unsafe fn instr16_C1_7_reg(r1: i32, imm: i32) {
  1246. write_reg16(r1, sar16(read_reg16(r1), imm & 31));
  1247. }
  1248. pub unsafe fn instr32_C1_0_mem(addr: i32, imm: i32) {
  1249. SAFE_READ_WRITE32!(___, addr, rol32(___, imm & 31));
  1250. }
  1251. pub unsafe fn instr32_C1_0_reg(r1: i32, imm: i32) {
  1252. write_reg32(r1, rol32(read_reg32(r1), imm & 31));
  1253. }
  1254. pub unsafe fn instr32_C1_1_mem(addr: i32, imm: i32) {
  1255. SAFE_READ_WRITE32!(___, addr, ror32(___, imm & 31));
  1256. }
  1257. pub unsafe fn instr32_C1_1_reg(r1: i32, imm: i32) {
  1258. write_reg32(r1, ror32(read_reg32(r1), imm & 31));
  1259. }
  1260. pub unsafe fn instr32_C1_2_mem(addr: i32, imm: i32) {
  1261. SAFE_READ_WRITE32!(___, addr, rcl32(___, imm & 31));
  1262. }
  1263. pub unsafe fn instr32_C1_2_reg(r1: i32, imm: i32) {
  1264. write_reg32(r1, rcl32(read_reg32(r1), imm & 31));
  1265. }
  1266. pub unsafe fn instr32_C1_3_mem(addr: i32, imm: i32) {
  1267. SAFE_READ_WRITE32!(___, addr, rcr32(___, imm & 31));
  1268. }
  1269. pub unsafe fn instr32_C1_3_reg(r1: i32, imm: i32) {
  1270. write_reg32(r1, rcr32(read_reg32(r1), imm & 31));
  1271. }
  1272. pub unsafe fn instr32_C1_4_mem(addr: i32, imm: i32) {
  1273. SAFE_READ_WRITE32!(___, addr, shl32(___, imm & 31));
  1274. }
  1275. pub unsafe fn instr32_C1_4_reg(r1: i32, imm: i32) {
  1276. write_reg32(r1, shl32(read_reg32(r1), imm & 31));
  1277. }
  1278. pub unsafe fn instr32_C1_5_mem(addr: i32, imm: i32) {
  1279. SAFE_READ_WRITE32!(___, addr, shr32(___, imm & 31));
  1280. }
  1281. pub unsafe fn instr32_C1_5_reg(r1: i32, imm: i32) {
  1282. write_reg32(r1, shr32(read_reg32(r1), imm & 31));
  1283. }
  1284. pub unsafe fn instr32_C1_6_mem(addr: i32, imm: i32) {
  1285. SAFE_READ_WRITE32!(___, addr, shl32(___, imm & 31));
  1286. }
  1287. pub unsafe fn instr32_C1_6_reg(r1: i32, imm: i32) {
  1288. write_reg32(r1, shl32(read_reg32(r1), imm & 31));
  1289. }
  1290. pub unsafe fn instr32_C1_7_mem(addr: i32, imm: i32) {
  1291. SAFE_READ_WRITE32!(___, addr, sar32(___, imm & 31));
  1292. }
  1293. pub unsafe fn instr32_C1_7_reg(r1: i32, imm: i32) {
  1294. write_reg32(r1, sar32(read_reg32(r1), imm & 31));
  1295. }
  1296. pub unsafe fn instr16_C2(imm16: i32) {
  1297. // retn
  1298. let cs = get_seg_cs();
  1299. *instruction_pointer = cs + return_on_pagefault!(pop16());
  1300. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  1301. adjust_stack_reg(imm16);
  1302. }
  1303. pub unsafe fn instr32_C2(imm16: i32) {
  1304. // retn
  1305. let cs = get_seg_cs();
  1306. let ip = return_on_pagefault!(pop32s());
  1307. dbg_assert!(*is_32 || ip < 0x10000);
  1308. *instruction_pointer = cs + ip;
  1309. adjust_stack_reg(imm16);
  1310. }
  1311. pub unsafe fn instr16_C3() {
  1312. // retn
  1313. let cs = get_seg_cs();
  1314. *instruction_pointer = cs + return_on_pagefault!(pop16());
  1315. }
  1316. pub unsafe fn instr32_C3() {
  1317. // retn
  1318. let cs = get_seg_cs();
  1319. let ip = return_on_pagefault!(pop32s());
  1320. dbg_assert!(*is_32 || ip < 0x10000);
  1321. *instruction_pointer = cs + ip;
  1322. }
  1323. #[no_mangle]
  1324. pub unsafe fn instr16_C4_reg(_unused1: i32, _unused2: i32) { trigger_ud(); }
  1325. #[no_mangle]
  1326. pub unsafe fn instr16_C4_mem(addr: i32, r: i32) { lss16(addr, r, ES); }
  1327. #[no_mangle]
  1328. pub unsafe fn instr32_C4_reg(_unused1: i32, _unused2: i32) { trigger_ud(); }
  1329. #[no_mangle]
  1330. pub unsafe fn instr32_C4_mem(addr: i32, r: i32) { lss32(addr, r, ES); }
  1331. #[no_mangle]
  1332. pub unsafe fn instr16_C5_reg(_unused1: i32, _unused2: i32) { trigger_ud(); }
  1333. #[no_mangle]
  1334. pub unsafe fn instr16_C5_mem(addr: i32, r: i32) { lss16(addr, r, DS); }
  1335. #[no_mangle]
  1336. pub unsafe fn instr32_C5_reg(_unused1: i32, _unused2: i32) { trigger_ud(); }
  1337. #[no_mangle]
  1338. pub unsafe fn instr32_C5_mem(addr: i32, r: i32) { lss32(addr, r, DS); }
  1339. #[no_mangle]
  1340. pub unsafe fn instr_C6_0_reg(r: i32, imm: i32) { write_reg8(r, imm); }
  1341. #[no_mangle]
  1342. pub unsafe fn instr_C6_0_mem(addr: i32, imm: i32) {
  1343. return_on_pagefault!(safe_write8(addr, imm));
  1344. }
  1345. #[no_mangle]
  1346. pub unsafe fn instr16_C7_0_reg(r: i32, imm: i32) { write_reg16(r, imm); }
  1347. #[no_mangle]
  1348. pub unsafe fn instr16_C7_0_mem(addr: i32, imm: i32) {
  1349. return_on_pagefault!(safe_write16(addr, imm));
  1350. }
  1351. #[no_mangle]
  1352. pub unsafe fn instr32_C7_0_reg(r: i32, imm: i32) { write_reg32(r, imm); }
  1353. #[no_mangle]
  1354. pub unsafe fn instr32_C7_0_mem(addr: i32, imm: i32) {
  1355. return_on_pagefault!(safe_write32(addr, imm));
  1356. }
  1357. #[no_mangle]
  1358. pub unsafe fn instr16_C8(size: i32, nesting: i32) { enter16(size, nesting); }
  1359. #[no_mangle]
  1360. pub unsafe fn instr32_C8(size: i32, nesting: i32) { enter32(size, nesting); }
  1361. #[no_mangle]
  1362. pub unsafe fn instr16_C9() {
  1363. // leave
  1364. let old_vbp = if *stack_size_32 { read_reg32(EBP) } else { read_reg16(BP) };
  1365. let new_bp = return_on_pagefault!(safe_read16(get_seg_ss() + old_vbp));
  1366. set_stack_reg(old_vbp + 2);
  1367. write_reg16(BP, new_bp);
  1368. }
  1369. #[no_mangle]
  1370. pub unsafe fn instr32_C9() {
  1371. let old_vbp = if *stack_size_32 { read_reg32(EBP) } else { read_reg16(BP) };
  1372. let new_ebp = return_on_pagefault!(safe_read32s(get_seg_ss() + old_vbp));
  1373. set_stack_reg(old_vbp + 4);
  1374. write_reg32(EBP, new_ebp);
  1375. }
  1376. #[no_mangle]
  1377. pub unsafe fn instr16_CA(imm16: i32) {
  1378. // retf
  1379. let ip = return_on_pagefault!(safe_read16(get_stack_pointer(0)));
  1380. let cs = return_on_pagefault!(safe_read16(get_stack_pointer(2)));
  1381. far_return(ip, cs, imm16, false);
  1382. }
  1383. #[no_mangle]
  1384. pub unsafe fn instr32_CA(imm16: i32) {
  1385. // retf
  1386. let ip = return_on_pagefault!(safe_read32s(get_stack_pointer(0)));
  1387. let cs = return_on_pagefault!(safe_read32s(get_stack_pointer(4))) & 0xFFFF;
  1388. far_return(ip, cs, imm16, true);
  1389. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  1390. }
  1391. #[no_mangle]
  1392. pub unsafe fn instr16_CB() {
  1393. // retf
  1394. let ip = return_on_pagefault!(safe_read16(get_stack_pointer(0)));
  1395. let cs = return_on_pagefault!(safe_read16(get_stack_pointer(2)));
  1396. far_return(ip, cs, 0, false);
  1397. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  1398. }
  1399. #[no_mangle]
  1400. pub unsafe fn instr32_CB() {
  1401. // retf
  1402. let ip = return_on_pagefault!(safe_read32s(get_stack_pointer(0)));
  1403. let cs = return_on_pagefault!(safe_read32s(get_stack_pointer(4))) & 0xFFFF;
  1404. far_return(ip, cs, 0, true);
  1405. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  1406. }
  1407. #[no_mangle]
  1408. pub unsafe fn instr_CC() {
  1409. // INT3
  1410. // TODO: inhibit iopl checks
  1411. dbg_log!("INT3");
  1412. call_interrupt_vector(3, true, None);
  1413. }
  1414. #[no_mangle]
  1415. pub unsafe fn instr_CD(imm8: i32) {
  1416. // INT
  1417. call_interrupt_vector(imm8, true, None);
  1418. }
  1419. #[no_mangle]
  1420. pub unsafe fn instr_CE() {
  1421. // INTO
  1422. dbg_log!("INTO");
  1423. if getof() {
  1424. // TODO: inhibit iopl checks
  1425. call_interrupt_vector(CPU_EXCEPTION_OF, true, None);
  1426. };
  1427. }
  1428. #[no_mangle]
  1429. pub unsafe fn instr16_CF() {
  1430. // iret
  1431. iret16();
  1432. }
  1433. #[no_mangle]
  1434. pub unsafe fn instr32_CF() { iret32(); }
  1435. pub unsafe fn instr_D0_0_mem(addr: i32) {
  1436. SAFE_READ_WRITE8!(___, addr, rol8(___, 1));
  1437. }
  1438. pub unsafe fn instr_D0_0_reg(r1: i32) { write_reg8(r1, rol8(read_reg8(r1), 1)); }
  1439. pub unsafe fn instr_D0_1_mem(addr: i32) {
  1440. SAFE_READ_WRITE8!(___, addr, ror8(___, 1));
  1441. }
  1442. pub unsafe fn instr_D0_1_reg(r1: i32) { write_reg8(r1, ror8(read_reg8(r1), 1)); }
  1443. pub unsafe fn instr_D0_2_mem(addr: i32) {
  1444. SAFE_READ_WRITE8!(___, addr, rcl8(___, 1));
  1445. }
  1446. pub unsafe fn instr_D0_2_reg(r1: i32) { write_reg8(r1, rcl8(read_reg8(r1), 1)); }
  1447. pub unsafe fn instr_D0_3_mem(addr: i32) {
  1448. SAFE_READ_WRITE8!(___, addr, rcr8(___, 1));
  1449. }
  1450. pub unsafe fn instr_D0_3_reg(r1: i32) { write_reg8(r1, rcr8(read_reg8(r1), 1)); }
  1451. pub unsafe fn instr_D0_4_mem(addr: i32) {
  1452. SAFE_READ_WRITE8!(___, addr, shl8(___, 1));
  1453. }
  1454. pub unsafe fn instr_D0_4_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), 1)); }
  1455. pub unsafe fn instr_D0_5_mem(addr: i32) {
  1456. SAFE_READ_WRITE8!(___, addr, shr8(___, 1));
  1457. }
  1458. pub unsafe fn instr_D0_5_reg(r1: i32) { write_reg8(r1, shr8(read_reg8(r1), 1)); }
  1459. pub unsafe fn instr_D0_6_mem(addr: i32) {
  1460. SAFE_READ_WRITE8!(___, addr, shl8(___, 1));
  1461. }
  1462. pub unsafe fn instr_D0_6_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), 1)); }
  1463. pub unsafe fn instr_D0_7_mem(addr: i32) {
  1464. SAFE_READ_WRITE8!(___, addr, sar8(___, 1));
  1465. }
  1466. pub unsafe fn instr_D0_7_reg(r1: i32) { write_reg8(r1, sar8(read_reg8(r1), 1)); }
  1467. pub unsafe fn instr16_D1_0_mem(addr: i32) {
  1468. SAFE_READ_WRITE16!(___, addr, rol16(___, 1));
  1469. }
  1470. pub unsafe fn instr16_D1_0_reg(r1: i32) { write_reg16(r1, rol16(read_reg16(r1), 1)); }
  1471. pub unsafe fn instr16_D1_1_mem(addr: i32) {
  1472. SAFE_READ_WRITE16!(___, addr, ror16(___, 1));
  1473. }
  1474. pub unsafe fn instr16_D1_1_reg(r1: i32) { write_reg16(r1, ror16(read_reg16(r1), 1)); }
  1475. pub unsafe fn instr16_D1_2_mem(addr: i32) {
  1476. SAFE_READ_WRITE16!(___, addr, rcl16(___, 1));
  1477. }
  1478. pub unsafe fn instr16_D1_2_reg(r1: i32) { write_reg16(r1, rcl16(read_reg16(r1), 1)); }
  1479. pub unsafe fn instr16_D1_3_mem(addr: i32) {
  1480. SAFE_READ_WRITE16!(___, addr, rcr16(___, 1));
  1481. }
  1482. pub unsafe fn instr16_D1_3_reg(r1: i32) { write_reg16(r1, rcr16(read_reg16(r1), 1)); }
  1483. pub unsafe fn instr16_D1_4_mem(addr: i32) {
  1484. SAFE_READ_WRITE16!(___, addr, shl16(___, 1));
  1485. }
  1486. pub unsafe fn instr16_D1_4_reg(r1: i32) { write_reg16(r1, shl16(read_reg16(r1), 1)); }
  1487. pub unsafe fn instr16_D1_5_mem(addr: i32) {
  1488. SAFE_READ_WRITE16!(___, addr, shr16(___, 1));
  1489. }
  1490. pub unsafe fn instr16_D1_5_reg(r1: i32) { write_reg16(r1, shr16(read_reg16(r1), 1)); }
  1491. pub unsafe fn instr16_D1_6_mem(addr: i32) {
  1492. SAFE_READ_WRITE16!(___, addr, shl16(___, 1));
  1493. }
  1494. pub unsafe fn instr16_D1_6_reg(r1: i32) { write_reg16(r1, shl16(read_reg16(r1), 1)); }
  1495. pub unsafe fn instr16_D1_7_mem(addr: i32) {
  1496. SAFE_READ_WRITE16!(___, addr, sar16(___, 1));
  1497. }
  1498. pub unsafe fn instr16_D1_7_reg(r1: i32) { write_reg16(r1, sar16(read_reg16(r1), 1)); }
  1499. pub unsafe fn instr32_D1_0_mem(addr: i32) {
  1500. SAFE_READ_WRITE32!(___, addr, rol32(___, 1));
  1501. }
  1502. pub unsafe fn instr32_D1_0_reg(r1: i32) { write_reg32(r1, rol32(read_reg32(r1), 1)); }
  1503. pub unsafe fn instr32_D1_1_mem(addr: i32) {
  1504. SAFE_READ_WRITE32!(___, addr, ror32(___, 1));
  1505. }
  1506. pub unsafe fn instr32_D1_1_reg(r1: i32) { write_reg32(r1, ror32(read_reg32(r1), 1)); }
  1507. pub unsafe fn instr32_D1_2_mem(addr: i32) {
  1508. SAFE_READ_WRITE32!(___, addr, rcl32(___, 1));
  1509. }
  1510. pub unsafe fn instr32_D1_2_reg(r1: i32) { write_reg32(r1, rcl32(read_reg32(r1), 1)); }
  1511. pub unsafe fn instr32_D1_3_mem(addr: i32) {
  1512. SAFE_READ_WRITE32!(___, addr, rcr32(___, 1));
  1513. }
  1514. pub unsafe fn instr32_D1_3_reg(r1: i32) { write_reg32(r1, rcr32(read_reg32(r1), 1)); }
  1515. pub unsafe fn instr32_D1_4_mem(addr: i32) {
  1516. SAFE_READ_WRITE32!(___, addr, shl32(___, 1));
  1517. }
  1518. pub unsafe fn instr32_D1_4_reg(r1: i32) { write_reg32(r1, shl32(read_reg32(r1), 1)); }
  1519. pub unsafe fn instr32_D1_5_mem(addr: i32) {
  1520. SAFE_READ_WRITE32!(___, addr, shr32(___, 1));
  1521. }
  1522. pub unsafe fn instr32_D1_5_reg(r1: i32) { write_reg32(r1, shr32(read_reg32(r1), 1)); }
  1523. pub unsafe fn instr32_D1_6_mem(addr: i32) {
  1524. SAFE_READ_WRITE32!(___, addr, shl32(___, 1));
  1525. }
  1526. pub unsafe fn instr32_D1_6_reg(r1: i32) { write_reg32(r1, shl32(read_reg32(r1), 1)); }
  1527. pub unsafe fn instr32_D1_7_mem(addr: i32) {
  1528. SAFE_READ_WRITE32!(___, addr, sar32(___, 1));
  1529. }
  1530. pub unsafe fn instr32_D1_7_reg(r1: i32) { write_reg32(r1, sar32(read_reg32(r1), 1)); }
  1531. pub unsafe fn instr_D2_0_mem(addr: i32) {
  1532. SAFE_READ_WRITE8!(___, addr, rol8(___, read_reg8(CL) & 31));
  1533. }
  1534. pub unsafe fn instr_D2_0_reg(r1: i32) { write_reg8(r1, rol8(read_reg8(r1), read_reg8(CL) & 31)); }
  1535. pub unsafe fn instr_D2_1_mem(addr: i32) {
  1536. SAFE_READ_WRITE8!(___, addr, ror8(___, read_reg8(CL) & 31));
  1537. }
  1538. pub unsafe fn instr_D2_1_reg(r1: i32) { write_reg8(r1, ror8(read_reg8(r1), read_reg8(CL) & 31)); }
  1539. pub unsafe fn instr_D2_2_mem(addr: i32) {
  1540. SAFE_READ_WRITE8!(___, addr, rcl8(___, read_reg8(CL) & 31));
  1541. }
  1542. pub unsafe fn instr_D2_2_reg(r1: i32) { write_reg8(r1, rcl8(read_reg8(r1), read_reg8(CL) & 31)); }
  1543. pub unsafe fn instr_D2_3_mem(addr: i32) {
  1544. SAFE_READ_WRITE8!(___, addr, rcr8(___, read_reg8(CL) & 31));
  1545. }
  1546. pub unsafe fn instr_D2_3_reg(r1: i32) { write_reg8(r1, rcr8(read_reg8(r1), read_reg8(CL) & 31)); }
  1547. pub unsafe fn instr_D2_4_mem(addr: i32) {
  1548. SAFE_READ_WRITE8!(___, addr, shl8(___, read_reg8(CL) & 31));
  1549. }
  1550. pub unsafe fn instr_D2_4_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), read_reg8(CL) & 31)); }
  1551. pub unsafe fn instr_D2_5_mem(addr: i32) {
  1552. SAFE_READ_WRITE8!(___, addr, shr8(___, read_reg8(CL) & 31));
  1553. }
  1554. pub unsafe fn instr_D2_5_reg(r1: i32) { write_reg8(r1, shr8(read_reg8(r1), read_reg8(CL) & 31)); }
  1555. pub unsafe fn instr_D2_6_mem(addr: i32) {
  1556. SAFE_READ_WRITE8!(___, addr, shl8(___, read_reg8(CL) & 31));
  1557. }
  1558. pub unsafe fn instr_D2_6_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), read_reg8(CL) & 31)); }
  1559. pub unsafe fn instr_D2_7_mem(addr: i32) {
  1560. SAFE_READ_WRITE8!(___, addr, sar8(___, read_reg8(CL) & 31));
  1561. }
  1562. pub unsafe fn instr_D2_7_reg(r1: i32) { write_reg8(r1, sar8(read_reg8(r1), read_reg8(CL) & 31)); }
  1563. pub unsafe fn instr16_D3_0_mem(addr: i32) {
  1564. SAFE_READ_WRITE16!(___, addr, rol16(___, read_reg8(CL) & 31));
  1565. }
  1566. pub unsafe fn instr16_D3_0_reg(r1: i32) {
  1567. write_reg16(r1, rol16(read_reg16(r1), read_reg8(CL) & 31));
  1568. }
  1569. pub unsafe fn instr16_D3_1_mem(addr: i32) {
  1570. SAFE_READ_WRITE16!(___, addr, ror16(___, read_reg8(CL) & 31));
  1571. }
  1572. pub unsafe fn instr16_D3_1_reg(r1: i32) {
  1573. write_reg16(r1, ror16(read_reg16(r1), read_reg8(CL) & 31));
  1574. }
  1575. pub unsafe fn instr16_D3_2_mem(addr: i32) {
  1576. SAFE_READ_WRITE16!(___, addr, rcl16(___, read_reg8(CL) & 31));
  1577. }
  1578. pub unsafe fn instr16_D3_2_reg(r1: i32) {
  1579. write_reg16(r1, rcl16(read_reg16(r1), read_reg8(CL) & 31));
  1580. }
  1581. pub unsafe fn instr16_D3_3_mem(addr: i32) {
  1582. SAFE_READ_WRITE16!(___, addr, rcr16(___, read_reg8(CL) & 31));
  1583. }
  1584. pub unsafe fn instr16_D3_3_reg(r1: i32) {
  1585. write_reg16(r1, rcr16(read_reg16(r1), read_reg8(CL) & 31));
  1586. }
  1587. pub unsafe fn instr16_D3_4_mem(addr: i32) {
  1588. SAFE_READ_WRITE16!(___, addr, shl16(___, read_reg8(CL) & 31));
  1589. }
  1590. pub unsafe fn instr16_D3_4_reg(r1: i32) {
  1591. write_reg16(r1, shl16(read_reg16(r1), read_reg8(CL) & 31));
  1592. }
  1593. pub unsafe fn instr16_D3_5_mem(addr: i32) {
  1594. SAFE_READ_WRITE16!(___, addr, shr16(___, read_reg8(CL) & 31));
  1595. }
  1596. pub unsafe fn instr16_D3_5_reg(r1: i32) {
  1597. write_reg16(r1, shr16(read_reg16(r1), read_reg8(CL) & 31));
  1598. }
  1599. pub unsafe fn instr16_D3_6_mem(addr: i32) {
  1600. SAFE_READ_WRITE16!(___, addr, shl16(___, read_reg8(CL) & 31));
  1601. }
  1602. pub unsafe fn instr16_D3_6_reg(r1: i32) {
  1603. write_reg16(r1, shl16(read_reg16(r1), read_reg8(CL) & 31));
  1604. }
  1605. pub unsafe fn instr16_D3_7_mem(addr: i32) {
  1606. SAFE_READ_WRITE16!(___, addr, sar16(___, read_reg8(CL) & 31));
  1607. }
  1608. pub unsafe fn instr16_D3_7_reg(r1: i32) {
  1609. write_reg16(r1, sar16(read_reg16(r1), read_reg8(CL) & 31));
  1610. }
  1611. pub unsafe fn instr32_D3_0_mem(addr: i32) {
  1612. SAFE_READ_WRITE32!(___, addr, rol32(___, read_reg8(CL) & 31));
  1613. }
  1614. pub unsafe fn instr32_D3_0_reg(r1: i32) {
  1615. write_reg32(r1, rol32(read_reg32(r1), read_reg8(CL) & 31));
  1616. }
  1617. pub unsafe fn instr32_D3_1_mem(addr: i32) {
  1618. SAFE_READ_WRITE32!(___, addr, ror32(___, read_reg8(CL) & 31));
  1619. }
  1620. pub unsafe fn instr32_D3_1_reg(r1: i32) {
  1621. write_reg32(r1, ror32(read_reg32(r1), read_reg8(CL) & 31));
  1622. }
  1623. pub unsafe fn instr32_D3_2_mem(addr: i32) {
  1624. SAFE_READ_WRITE32!(___, addr, rcl32(___, read_reg8(CL) & 31));
  1625. }
  1626. pub unsafe fn instr32_D3_2_reg(r1: i32) {
  1627. write_reg32(r1, rcl32(read_reg32(r1), read_reg8(CL) & 31));
  1628. }
  1629. pub unsafe fn instr32_D3_3_mem(addr: i32) {
  1630. SAFE_READ_WRITE32!(___, addr, rcr32(___, read_reg8(CL) & 31));
  1631. }
  1632. pub unsafe fn instr32_D3_3_reg(r1: i32) {
  1633. write_reg32(r1, rcr32(read_reg32(r1), read_reg8(CL) & 31));
  1634. }
  1635. pub unsafe fn instr32_D3_4_mem(addr: i32) {
  1636. SAFE_READ_WRITE32!(___, addr, shl32(___, read_reg8(CL) & 31));
  1637. }
  1638. pub unsafe fn instr32_D3_4_reg(r1: i32) {
  1639. write_reg32(r1, shl32(read_reg32(r1), read_reg8(CL) & 31));
  1640. }
  1641. pub unsafe fn instr32_D3_5_mem(addr: i32) {
  1642. SAFE_READ_WRITE32!(___, addr, shr32(___, read_reg8(CL) & 31));
  1643. }
  1644. pub unsafe fn instr32_D3_5_reg(r1: i32) {
  1645. write_reg32(r1, shr32(read_reg32(r1), read_reg8(CL) & 31));
  1646. }
  1647. pub unsafe fn instr32_D3_6_mem(addr: i32) {
  1648. SAFE_READ_WRITE32!(___, addr, shl32(___, read_reg8(CL) & 31));
  1649. }
  1650. pub unsafe fn instr32_D3_6_reg(r1: i32) {
  1651. write_reg32(r1, shl32(read_reg32(r1), read_reg8(CL) & 31));
  1652. }
  1653. pub unsafe fn instr32_D3_7_mem(addr: i32) {
  1654. SAFE_READ_WRITE32!(___, addr, sar32(___, read_reg8(CL) & 31));
  1655. }
  1656. pub unsafe fn instr32_D3_7_reg(r1: i32) {
  1657. write_reg32(r1, sar32(read_reg32(r1), read_reg8(CL) & 31));
  1658. }
  1659. #[no_mangle]
  1660. pub unsafe fn instr_D4(arg: i32) { bcd_aam(arg); }
  1661. #[no_mangle]
  1662. pub unsafe fn instr_D5(arg: i32) { bcd_aad(arg); }
  1663. #[no_mangle]
  1664. pub unsafe fn instr_D6() {
  1665. // salc
  1666. write_reg8(AL, -(getcf() as i32));
  1667. }
  1668. #[no_mangle]
  1669. pub unsafe fn instr_D7() {
  1670. // xlat
  1671. dbg_assert!(!in_jit);
  1672. if is_asize_32() {
  1673. write_reg8(
  1674. AL,
  1675. return_on_pagefault!(safe_read8(
  1676. return_on_pagefault!(get_seg_prefix(DS)) + read_reg32(EBX) + read_reg8(AL),
  1677. )),
  1678. )
  1679. }
  1680. else {
  1681. write_reg8(
  1682. AL,
  1683. return_on_pagefault!(safe_read8(
  1684. return_on_pagefault!(get_seg_prefix(DS))
  1685. + (read_reg16(BX) + read_reg8(AL) & 0xFFFF),
  1686. )),
  1687. )
  1688. };
  1689. }
  1690. #[no_mangle]
  1691. pub unsafe fn instr_E4(port: i32) {
  1692. if !test_privileges_for_io(port, 1) {
  1693. return;
  1694. }
  1695. else {
  1696. write_reg8(AL, io_port_read8(port));
  1697. return;
  1698. };
  1699. }
  1700. #[no_mangle]
  1701. pub unsafe fn instr16_E5(port: i32) {
  1702. if !test_privileges_for_io(port, 2) {
  1703. return;
  1704. }
  1705. else {
  1706. write_reg16(AX, io_port_read16(port));
  1707. return;
  1708. };
  1709. }
  1710. #[no_mangle]
  1711. pub unsafe fn instr32_E5(port: i32) {
  1712. if !test_privileges_for_io(port, 4) {
  1713. return;
  1714. }
  1715. else {
  1716. write_reg32(EAX, io_port_read32(port));
  1717. return;
  1718. };
  1719. }
  1720. #[no_mangle]
  1721. pub unsafe fn instr_E6(port: i32) {
  1722. if !test_privileges_for_io(port, 1) {
  1723. return;
  1724. }
  1725. else {
  1726. io_port_write8(port, read_reg8(AL));
  1727. return;
  1728. };
  1729. }
  1730. #[no_mangle]
  1731. pub unsafe fn instr16_E7(port: i32) {
  1732. if !test_privileges_for_io(port, 2) {
  1733. return;
  1734. }
  1735. else {
  1736. io_port_write16(port, read_reg16(AX));
  1737. return;
  1738. };
  1739. }
  1740. #[no_mangle]
  1741. pub unsafe fn instr32_E7(port: i32) {
  1742. if !test_privileges_for_io(port, 4) {
  1743. return;
  1744. }
  1745. else {
  1746. io_port_write32(port, read_reg32(EAX));
  1747. return;
  1748. };
  1749. }
  1750. pub unsafe fn instr16_E8(imm16: i32) {
  1751. // call
  1752. return_on_pagefault!(push16(get_real_eip()));
  1753. jmp_rel16(imm16);
  1754. }
  1755. pub unsafe fn instr32_E8(imm32s: i32) {
  1756. // call
  1757. return_on_pagefault!(push32(get_real_eip()));
  1758. *instruction_pointer = *instruction_pointer + imm32s;
  1759. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  1760. }
  1761. pub unsafe fn instr16_E9(imm16: i32) {
  1762. // jmp
  1763. jmp_rel16(imm16);
  1764. }
  1765. pub unsafe fn instr32_E9(imm32s: i32) {
  1766. // jmp
  1767. *instruction_pointer = *instruction_pointer + imm32s;
  1768. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  1769. }
  1770. #[no_mangle]
  1771. pub unsafe fn instr16_EA(new_ip: i32, cs: i32) {
  1772. // jmpf
  1773. far_jump(new_ip, cs, false, false);
  1774. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  1775. }
  1776. #[no_mangle]
  1777. pub unsafe fn instr32_EA(new_ip: i32, cs: i32) {
  1778. // jmpf
  1779. far_jump(new_ip, cs, false, true);
  1780. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  1781. }
  1782. #[no_mangle]
  1783. pub unsafe fn instr_EC() {
  1784. let port = read_reg16(DX);
  1785. if !test_privileges_for_io(port, 1) {
  1786. return;
  1787. }
  1788. else {
  1789. write_reg8(AL, io_port_read8(port));
  1790. return;
  1791. };
  1792. }
  1793. #[no_mangle]
  1794. pub unsafe fn instr16_ED() {
  1795. let port = read_reg16(DX);
  1796. if !test_privileges_for_io(port, 2) {
  1797. return;
  1798. }
  1799. else {
  1800. write_reg16(AX, io_port_read16(port));
  1801. return;
  1802. };
  1803. }
  1804. #[no_mangle]
  1805. pub unsafe fn instr32_ED() {
  1806. let port = read_reg16(DX);
  1807. if !test_privileges_for_io(port, 4) {
  1808. return;
  1809. }
  1810. else {
  1811. write_reg32(EAX, io_port_read32(port));
  1812. return;
  1813. };
  1814. }
  1815. #[no_mangle]
  1816. pub unsafe fn instr_EE() {
  1817. let port = read_reg16(DX);
  1818. if !test_privileges_for_io(port, 1) {
  1819. return;
  1820. }
  1821. else {
  1822. io_port_write8(port, read_reg8(AL));
  1823. return;
  1824. };
  1825. }
  1826. #[no_mangle]
  1827. pub unsafe fn instr16_EF() {
  1828. let port = read_reg16(DX);
  1829. if !test_privileges_for_io(port, 2) {
  1830. return;
  1831. }
  1832. else {
  1833. io_port_write16(port, read_reg16(AX));
  1834. return;
  1835. };
  1836. }
  1837. #[no_mangle]
  1838. pub unsafe fn instr32_EF() {
  1839. let port = read_reg16(DX);
  1840. if !test_privileges_for_io(port, 4) {
  1841. return;
  1842. }
  1843. else {
  1844. io_port_write32(port, read_reg32(EAX));
  1845. return;
  1846. };
  1847. }
  1848. pub unsafe fn instr_F0() {
  1849. // lock
  1850. if false {
  1851. dbg_log!("lock");
  1852. }
  1853. // TODO
  1854. // This triggers UD when used with
  1855. // some instructions that don't write to memory
  1856. run_prefix_instruction();
  1857. }
  1858. #[no_mangle]
  1859. pub unsafe fn instr_F1() {
  1860. // INT1
  1861. // https://code.google.com/p/corkami/wiki/x86oddities#IceBP
  1862. dbg_assert!(false);
  1863. }
  1864. pub unsafe fn instr_F2() {
  1865. // repnz
  1866. dbg_assert!(*prefixes as i32 & PREFIX_MASK_REP == 0);
  1867. *prefixes = (*prefixes as i32 | PREFIX_REPNZ) as u8;
  1868. run_prefix_instruction();
  1869. *prefixes = 0;
  1870. }
  1871. pub unsafe fn instr_F3() {
  1872. // repz
  1873. dbg_assert!(*prefixes as i32 & PREFIX_MASK_REP == 0);
  1874. *prefixes = (*prefixes as i32 | PREFIX_REPZ) as u8;
  1875. run_prefix_instruction();
  1876. *prefixes = 0;
  1877. }
  1878. #[no_mangle]
  1879. pub unsafe fn instr_F4() { hlt_op(); }
  1880. #[no_mangle]
  1881. pub unsafe fn instr_F5() {
  1882. // cmc
  1883. *flags = (*flags | 1) ^ getcf() as i32;
  1884. *flags_changed &= !1;
  1885. }
  1886. #[no_mangle]
  1887. pub unsafe fn instr_F6_0_mem(addr: i32, imm: i32) {
  1888. test8(return_on_pagefault!(safe_read8(addr)), imm);
  1889. }
  1890. #[no_mangle]
  1891. pub unsafe fn instr_F6_0_reg(r1: i32, imm: i32) { test8(read_reg8(r1), imm); }
  1892. #[no_mangle]
  1893. pub unsafe fn instr_F6_1_mem(addr: i32, imm: i32) {
  1894. test8(return_on_pagefault!(safe_read8(addr)), imm);
  1895. }
  1896. #[no_mangle]
  1897. pub unsafe fn instr_F6_1_reg(r1: i32, imm: i32) { test8(read_reg8(r1), imm); }
  1898. #[no_mangle]
  1899. pub unsafe fn instr_F6_2_mem(addr: i32) {
  1900. SAFE_READ_WRITE8!(___, addr, !___);
  1901. }
  1902. #[no_mangle]
  1903. pub unsafe fn instr_F6_2_reg(r1: i32) { write_reg8(r1, !read_reg8(r1)); }
  1904. #[no_mangle]
  1905. pub unsafe fn instr_F6_3_mem(addr: i32) {
  1906. SAFE_READ_WRITE8!(___, addr, neg8(___));
  1907. }
  1908. #[no_mangle]
  1909. pub unsafe fn instr_F6_3_reg(r1: i32) { write_reg8(r1, neg8(read_reg8(r1))); }
  1910. #[no_mangle]
  1911. pub unsafe fn instr_F6_4_mem(addr: i32) { mul8(return_on_pagefault!(safe_read8(addr))); }
  1912. #[no_mangle]
  1913. pub unsafe fn instr_F6_4_reg(r1: i32) { mul8(read_reg8(r1)); }
  1914. #[no_mangle]
  1915. pub unsafe fn instr_F6_5_mem(addr: i32) {
  1916. imul8(return_on_pagefault!(safe_read8(addr)) << 24 >> 24);
  1917. }
  1918. #[no_mangle]
  1919. pub unsafe fn instr_F6_5_reg(r1: i32) { imul8(read_reg8(r1) << 24 >> 24); }
  1920. #[no_mangle]
  1921. pub unsafe fn instr_F6_6_mem(addr: i32) { div8(return_on_pagefault!(safe_read8(addr)) as u32); }
  1922. #[no_mangle]
  1923. pub unsafe fn instr_F6_6_reg(r1: i32) { div8(read_reg8(r1) as u32); }
  1924. #[no_mangle]
  1925. pub unsafe fn instr_F6_7_mem(addr: i32) {
  1926. idiv8(return_on_pagefault!(safe_read8(addr)) << 24 >> 24);
  1927. }
  1928. #[no_mangle]
  1929. pub unsafe fn instr_F6_7_reg(r1: i32) { idiv8(read_reg8(r1) << 24 >> 24); }
  1930. #[no_mangle]
  1931. pub unsafe fn instr16_F7_0_mem(addr: i32, imm: i32) {
  1932. test16(return_on_pagefault!(safe_read16(addr)), imm);
  1933. }
  1934. #[no_mangle]
  1935. pub unsafe fn instr16_F7_0_reg(r1: i32, imm: i32) { test16(read_reg16(r1), imm); }
  1936. #[no_mangle]
  1937. pub unsafe fn instr16_F7_1_mem(addr: i32, imm: i32) {
  1938. test16(return_on_pagefault!(safe_read16(addr)), imm);
  1939. }
  1940. #[no_mangle]
  1941. pub unsafe fn instr16_F7_1_reg(r1: i32, imm: i32) { test16(read_reg16(r1), imm); }
  1942. #[no_mangle]
  1943. pub unsafe fn instr16_F7_2_mem(addr: i32) {
  1944. SAFE_READ_WRITE16!(___, addr, !___);
  1945. }
  1946. #[no_mangle]
  1947. pub unsafe fn instr16_F7_2_reg(r1: i32) { write_reg16(r1, !read_reg16(r1)); }
  1948. #[no_mangle]
  1949. pub unsafe fn instr16_F7_3_mem(addr: i32) {
  1950. SAFE_READ_WRITE16!(___, addr, neg16(___));
  1951. }
  1952. #[no_mangle]
  1953. pub unsafe fn instr16_F7_3_reg(r1: i32) { write_reg16(r1, neg16(read_reg16(r1))); }
  1954. #[no_mangle]
  1955. pub unsafe fn instr16_F7_4_mem(addr: i32) { mul16(return_on_pagefault!(safe_read16(addr)) as u32); }
  1956. #[no_mangle]
  1957. pub unsafe fn instr16_F7_4_reg(r1: i32) { mul16(read_reg16(r1) as u32); }
  1958. #[no_mangle]
  1959. pub unsafe fn instr16_F7_5_mem(addr: i32) {
  1960. imul16(return_on_pagefault!(safe_read16(addr)) << 16 >> 16);
  1961. }
  1962. #[no_mangle]
  1963. pub unsafe fn instr16_F7_5_reg(r1: i32) { imul16(read_reg16(r1) << 16 >> 16); }
  1964. #[no_mangle]
  1965. pub unsafe fn instr16_F7_6_mem(addr: i32) { div16(return_on_pagefault!(safe_read16(addr)) as u32); }
  1966. #[no_mangle]
  1967. pub unsafe fn instr16_F7_6_reg(r1: i32) { div16(read_reg16(r1) as u32); }
  1968. #[no_mangle]
  1969. pub unsafe fn instr16_F7_7_mem(addr: i32) {
  1970. idiv16(return_on_pagefault!(safe_read16(addr)) << 16 >> 16);
  1971. }
  1972. #[no_mangle]
  1973. pub unsafe fn instr16_F7_7_reg(r1: i32) { idiv16(read_reg16(r1) << 16 >> 16); }
  1974. #[no_mangle]
  1975. pub unsafe fn instr32_F7_0_mem(addr: i32, imm: i32) {
  1976. test32(return_on_pagefault!(safe_read32s(addr)), imm);
  1977. }
  1978. #[no_mangle]
  1979. pub unsafe fn instr32_F7_0_reg(r1: i32, imm: i32) { test32(read_reg32(r1), imm); }
  1980. #[no_mangle]
  1981. pub unsafe fn instr32_F7_1_mem(addr: i32, imm: i32) {
  1982. test32(return_on_pagefault!(safe_read32s(addr)), imm);
  1983. }
  1984. #[no_mangle]
  1985. pub unsafe fn instr32_F7_1_reg(r1: i32, imm: i32) { test32(read_reg32(r1), imm); }
  1986. #[no_mangle]
  1987. pub unsafe fn instr32_F7_2_mem(addr: i32) {
  1988. SAFE_READ_WRITE32!(___, addr, !___);
  1989. }
  1990. #[no_mangle]
  1991. pub unsafe fn instr32_F7_2_reg(r1: i32) { write_reg32(r1, !read_reg32(r1)); }
  1992. #[no_mangle]
  1993. pub unsafe fn instr32_F7_3_mem(addr: i32) {
  1994. SAFE_READ_WRITE32!(___, addr, neg32(___));
  1995. }
  1996. #[no_mangle]
  1997. pub unsafe fn instr32_F7_3_reg(r1: i32) { write_reg32(r1, neg32(read_reg32(r1))); }
  1998. #[no_mangle]
  1999. pub unsafe fn instr32_F7_4_mem(addr: i32) { mul32(return_on_pagefault!(safe_read32s(addr))); }
  2000. #[no_mangle]
  2001. pub unsafe fn instr32_F7_4_reg(r1: i32) { mul32(read_reg32(r1)); }
  2002. #[no_mangle]
  2003. pub unsafe fn instr32_F7_5_mem(addr: i32) { imul32(return_on_pagefault!(safe_read32s(addr))); }
  2004. #[no_mangle]
  2005. pub unsafe fn instr32_F7_5_reg(r1: i32) { imul32(read_reg32(r1)); }
  2006. #[no_mangle]
  2007. pub unsafe fn instr32_F7_6_mem(addr: i32) {
  2008. div32(return_on_pagefault!(safe_read32s(addr)) as u32);
  2009. }
  2010. #[no_mangle]
  2011. pub unsafe fn instr32_F7_6_reg(r1: i32) { div32(read_reg32(r1) as u32); }
  2012. #[no_mangle]
  2013. pub unsafe fn instr32_F7_7_mem(addr: i32) { idiv32(return_on_pagefault!(safe_read32s(addr))); }
  2014. #[no_mangle]
  2015. pub unsafe fn instr32_F7_7_reg(r1: i32) { idiv32(read_reg32(r1)); }
  2016. #[no_mangle]
  2017. pub unsafe fn instr_F8() {
  2018. // clc
  2019. *flags &= !FLAG_CARRY;
  2020. *flags_changed &= !1;
  2021. }
  2022. #[no_mangle]
  2023. pub unsafe fn instr_F9() {
  2024. // stc
  2025. *flags |= FLAG_CARRY;
  2026. *flags_changed &= !1;
  2027. }
  2028. #[no_mangle]
  2029. pub unsafe fn instr_FA_without_fault() -> bool {
  2030. // cli
  2031. if !*protected_mode
  2032. || if 0 != *flags & FLAG_VM { getiopl() == 3 } else { getiopl() >= *cpl as i32 }
  2033. {
  2034. *flags &= !FLAG_INTERRUPT;
  2035. return true;
  2036. }
  2037. else if false
  2038. && getiopl() < 3
  2039. && if 0 != *flags & FLAG_VM {
  2040. 0 != *cr.offset(4) & CR4_VME
  2041. }
  2042. else {
  2043. *cpl == 3 && 0 != *cr.offset(4) & CR4_PVI
  2044. }
  2045. {
  2046. *flags &= !FLAG_VIF;
  2047. return true;
  2048. }
  2049. else {
  2050. dbg_log!("cli #gp");
  2051. return false;
  2052. };
  2053. }
  2054. pub unsafe fn instr_FA() {
  2055. if !instr_FA_without_fault() {
  2056. trigger_gp(0);
  2057. }
  2058. }
  2059. #[no_mangle]
  2060. pub unsafe fn instr_FB_without_fault() -> bool {
  2061. // sti
  2062. let old_if = *flags & FLAG_INTERRUPT;
  2063. if !*protected_mode
  2064. || if 0 != *flags & FLAG_VM { getiopl() == 3 } else { getiopl() >= *cpl as i32 }
  2065. {
  2066. *flags |= FLAG_INTERRUPT;
  2067. return true;
  2068. }
  2069. else if false
  2070. && getiopl() < 3
  2071. && *flags & FLAG_VIP == 0
  2072. && if 0 != *flags & FLAG_VM {
  2073. 0 != *cr.offset(4) & CR4_VME
  2074. }
  2075. else {
  2076. *cpl == 3 && 0 != *cr.offset(4) & CR4_PVI
  2077. }
  2078. {
  2079. *flags |= FLAG_VIF;
  2080. return true;
  2081. }
  2082. else {
  2083. dbg_log!("sti #gp");
  2084. return false;
  2085. };
  2086. }
  2087. pub unsafe fn instr_FB() {
  2088. if !instr_FB_without_fault() {
  2089. trigger_gp(0);
  2090. }
  2091. else {
  2092. *prefixes = 0;
  2093. *previous_ip = *instruction_pointer;
  2094. *timestamp_counter += 1;
  2095. run_instruction(return_on_pagefault!(read_imm8()) | (is_osize_32() as i32) << 8);
  2096. handle_irqs();
  2097. }
  2098. }
  2099. #[no_mangle]
  2100. pub unsafe fn instr_FC() {
  2101. // cld
  2102. *flags &= !FLAG_DIRECTION;
  2103. }
  2104. #[no_mangle]
  2105. pub unsafe fn instr_FD() {
  2106. // std
  2107. *flags |= FLAG_DIRECTION;
  2108. }
  2109. #[no_mangle]
  2110. pub unsafe fn instr_FE_0_mem(addr: i32) {
  2111. SAFE_READ_WRITE8!(___, addr, inc8(___));
  2112. }
  2113. #[no_mangle]
  2114. pub unsafe fn instr_FE_0_reg(r1: i32) { write_reg8(r1, inc8(read_reg8(r1))); }
  2115. #[no_mangle]
  2116. pub unsafe fn instr_FE_1_mem(addr: i32) {
  2117. SAFE_READ_WRITE8!(___, addr, dec8(___));
  2118. }
  2119. #[no_mangle]
  2120. pub unsafe fn instr_FE_1_reg(r1: i32) { write_reg8(r1, dec8(read_reg8(r1))); }
  2121. #[no_mangle]
  2122. pub unsafe fn instr16_FF_0_mem(addr: i32) {
  2123. SAFE_READ_WRITE16!(___, addr, inc16(___));
  2124. }
  2125. #[no_mangle]
  2126. pub unsafe fn instr16_FF_0_reg(r1: i32) { write_reg16(r1, inc16(read_reg16(r1))); }
  2127. #[no_mangle]
  2128. pub unsafe fn instr16_FF_1_mem(addr: i32) {
  2129. SAFE_READ_WRITE16!(___, addr, dec16(___));
  2130. }
  2131. #[no_mangle]
  2132. pub unsafe fn instr16_FF_1_reg(r1: i32) { write_reg16(r1, dec16(read_reg16(r1))); }
  2133. #[no_mangle]
  2134. pub unsafe fn instr16_FF_2_helper(data: i32) {
  2135. // call near
  2136. let cs = get_seg_cs();
  2137. return_on_pagefault!(push16(get_real_eip()));
  2138. *instruction_pointer = cs + data;
  2139. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  2140. }
  2141. #[no_mangle]
  2142. pub unsafe fn instr16_FF_2_mem(addr: i32) {
  2143. instr16_FF_2_helper(return_on_pagefault!(safe_read16(addr)));
  2144. }
  2145. #[no_mangle]
  2146. pub unsafe fn instr16_FF_2_reg(r1: i32) { instr16_FF_2_helper(read_reg16(r1)); }
  2147. #[no_mangle]
  2148. pub unsafe fn instr16_FF_3_reg(r: i32) {
  2149. dbg_log!("callf #ud");
  2150. trigger_ud();
  2151. }
  2152. #[no_mangle]
  2153. pub unsafe fn instr16_FF_3_mem(addr: i32) {
  2154. // callf
  2155. let new_ip = return_on_pagefault!(safe_read16(addr));
  2156. let new_cs = return_on_pagefault!(safe_read16(addr + 2));
  2157. far_jump(new_ip, new_cs, true, false);
  2158. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  2159. }
  2160. #[no_mangle]
  2161. pub unsafe fn instr16_FF_4_helper(data: i32) {
  2162. // jmp near
  2163. *instruction_pointer = get_seg_cs() + data;
  2164. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  2165. }
  2166. #[no_mangle]
  2167. pub unsafe fn instr16_FF_4_mem(addr: i32) {
  2168. instr16_FF_4_helper(return_on_pagefault!(safe_read16(addr)));
  2169. }
  2170. #[no_mangle]
  2171. pub unsafe fn instr16_FF_4_reg(r1: i32) { instr16_FF_4_helper(read_reg16(r1)); }
  2172. #[no_mangle]
  2173. pub unsafe fn instr16_FF_5_reg(r: i32) {
  2174. dbg_log!("jmpf #ud");
  2175. trigger_ud();
  2176. }
  2177. #[no_mangle]
  2178. pub unsafe fn instr16_FF_5_mem(addr: i32) {
  2179. // jmpf
  2180. let new_ip = return_on_pagefault!(safe_read16(addr));
  2181. let new_cs = return_on_pagefault!(safe_read16(addr + 2));
  2182. far_jump(new_ip, new_cs, false, false);
  2183. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  2184. }
  2185. #[no_mangle]
  2186. pub unsafe fn instr16_FF_6_mem(addr: i32) {
  2187. return_on_pagefault!(push16(return_on_pagefault!(safe_read16(addr))));
  2188. }
  2189. #[no_mangle]
  2190. pub unsafe fn instr16_FF_6_reg(r1: i32) {
  2191. return_on_pagefault!(push16(read_reg16(r1)));
  2192. }
  2193. #[no_mangle]
  2194. pub unsafe fn instr32_FF_0_mem(addr: i32) {
  2195. SAFE_READ_WRITE32!(___, addr, inc32(___));
  2196. }
  2197. #[no_mangle]
  2198. pub unsafe fn instr32_FF_0_reg(r1: i32) { write_reg32(r1, inc32(read_reg32(r1))); }
  2199. #[no_mangle]
  2200. pub unsafe fn instr32_FF_1_mem(addr: i32) {
  2201. SAFE_READ_WRITE32!(___, addr, dec32(___));
  2202. }
  2203. #[no_mangle]
  2204. pub unsafe fn instr32_FF_1_reg(r1: i32) { write_reg32(r1, dec32(read_reg32(r1))); }
  2205. #[no_mangle]
  2206. pub unsafe fn instr32_FF_2_helper(data: i32) {
  2207. // call near
  2208. let cs = get_seg_cs();
  2209. return_on_pagefault!(push32(get_real_eip()));
  2210. dbg_assert!(*is_32 || data < 0x10000);
  2211. *instruction_pointer = cs + data;
  2212. }
  2213. #[no_mangle]
  2214. pub unsafe fn instr32_FF_2_mem(addr: i32) {
  2215. instr32_FF_2_helper(return_on_pagefault!(safe_read32s(addr)));
  2216. }
  2217. #[no_mangle]
  2218. pub unsafe fn instr32_FF_2_reg(r1: i32) { instr32_FF_2_helper(read_reg32(r1)); }
  2219. #[no_mangle]
  2220. pub unsafe fn instr32_FF_3_reg(r: i32) {
  2221. dbg_log!("callf #ud");
  2222. trigger_ud();
  2223. }
  2224. #[no_mangle]
  2225. pub unsafe fn instr32_FF_3_mem(addr: i32) {
  2226. // callf
  2227. let new_ip = return_on_pagefault!(safe_read32s(addr));
  2228. let new_cs = return_on_pagefault!(safe_read16(addr + 4));
  2229. if !*protected_mode || vm86_mode() {
  2230. if 0 != new_ip as u32 & 0xFFFF0000 {
  2231. dbg_assert!(false);
  2232. }
  2233. }
  2234. far_jump(new_ip, new_cs, true, true);
  2235. dbg_assert!(*is_32 || new_ip < 0x10000);
  2236. }
  2237. #[no_mangle]
  2238. pub unsafe fn instr32_FF_4_helper(data: i32) {
  2239. // jmp near
  2240. dbg_assert!(*is_32 || data < 0x10000);
  2241. *instruction_pointer = get_seg_cs() + data;
  2242. }
  2243. #[no_mangle]
  2244. pub unsafe fn instr32_FF_4_mem(addr: i32) {
  2245. instr32_FF_4_helper(return_on_pagefault!(safe_read32s(addr)));
  2246. }
  2247. #[no_mangle]
  2248. pub unsafe fn instr32_FF_4_reg(r1: i32) { instr32_FF_4_helper(read_reg32(r1)); }
  2249. #[no_mangle]
  2250. pub unsafe fn instr32_FF_5_reg(r: i32) {
  2251. dbg_log!("jmpf #ud");
  2252. trigger_ud();
  2253. }
  2254. #[no_mangle]
  2255. pub unsafe fn instr32_FF_5_mem(addr: i32) {
  2256. // jmpf
  2257. let new_ip = return_on_pagefault!(safe_read32s(addr));
  2258. let new_cs = return_on_pagefault!(safe_read16(addr + 4));
  2259. if !*protected_mode || vm86_mode() {
  2260. if 0 != new_ip as u32 & 0xFFFF0000 {
  2261. dbg_assert!(false);
  2262. }
  2263. }
  2264. far_jump(new_ip, new_cs, false, true);
  2265. dbg_assert!(*is_32 || new_ip < 0x10000);
  2266. }
  2267. #[no_mangle]
  2268. pub unsafe fn instr32_FF_6_mem(addr: i32) {
  2269. return_on_pagefault!(push32(return_on_pagefault!(safe_read32s(addr))));
  2270. }
  2271. #[no_mangle]
  2272. pub unsafe fn instr32_FF_6_reg(r1: i32) {
  2273. return_on_pagefault!(push32(read_reg32(r1)));
  2274. }
  2275. pub unsafe fn instr_F26C() { insb_rep(is_asize_32()); }
  2276. pub unsafe fn instr_F36C() { insb_rep(is_asize_32()); }
  2277. pub unsafe fn instr16_F26D() { insw_rep(is_asize_32()); }
  2278. pub unsafe fn instr16_F36D() { insw_rep(is_asize_32()); }
  2279. pub unsafe fn instr32_F26D() { insd_rep(is_asize_32()); }
  2280. pub unsafe fn instr32_F36D() { insd_rep(is_asize_32()); }
  2281. pub unsafe fn instr_F26E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2282. pub unsafe fn instr_F36E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2283. pub unsafe fn instr16_F26F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2284. pub unsafe fn instr16_F36F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2285. pub unsafe fn instr32_F26F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2286. pub unsafe fn instr32_F36F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2287. pub unsafe fn instr16_70(imm8: i32) { jmpcc16(test_o(), imm8); }
  2288. pub unsafe fn instr16_71(imm8: i32) { jmpcc16(!test_o(), imm8); }
  2289. pub unsafe fn instr16_72(imm8: i32) { jmpcc16(test_b(), imm8); }
  2290. pub unsafe fn instr16_73(imm8: i32) { jmpcc16(!test_b(), imm8); }
  2291. pub unsafe fn instr16_74(imm8: i32) { jmpcc16(test_z(), imm8); }
  2292. pub unsafe fn instr16_75(imm8: i32) { jmpcc16(!test_z(), imm8); }
  2293. pub unsafe fn instr16_76(imm8: i32) { jmpcc16(test_be(), imm8); }
  2294. pub unsafe fn instr16_77(imm8: i32) { jmpcc16(!test_be(), imm8); }
  2295. pub unsafe fn instr16_78(imm8: i32) { jmpcc16(test_s(), imm8); }
  2296. pub unsafe fn instr16_79(imm8: i32) { jmpcc16(!test_s(), imm8); }
  2297. pub unsafe fn instr16_7A(imm8: i32) { jmpcc16(test_p(), imm8); }
  2298. pub unsafe fn instr16_7B(imm8: i32) { jmpcc16(!test_p(), imm8); }
  2299. pub unsafe fn instr16_7C(imm8: i32) { jmpcc16(test_l(), imm8); }
  2300. pub unsafe fn instr16_7D(imm8: i32) { jmpcc16(!test_l(), imm8); }
  2301. pub unsafe fn instr16_7E(imm8: i32) { jmpcc16(test_le(), imm8); }
  2302. pub unsafe fn instr16_7F(imm8: i32) { jmpcc16(!test_le(), imm8); }
  2303. pub unsafe fn instr32_70(imm8: i32) { jmpcc32(test_o(), imm8); }
  2304. pub unsafe fn instr32_71(imm8: i32) { jmpcc32(!test_o(), imm8); }
  2305. pub unsafe fn instr32_72(imm8: i32) { jmpcc32(test_b(), imm8); }
  2306. pub unsafe fn instr32_73(imm8: i32) { jmpcc32(!test_b(), imm8); }
  2307. pub unsafe fn instr32_74(imm8: i32) { jmpcc32(test_z(), imm8); }
  2308. pub unsafe fn instr32_75(imm8: i32) { jmpcc32(!test_z(), imm8); }
  2309. pub unsafe fn instr32_76(imm8: i32) { jmpcc32(test_be(), imm8); }
  2310. pub unsafe fn instr32_77(imm8: i32) { jmpcc32(!test_be(), imm8); }
  2311. pub unsafe fn instr32_78(imm8: i32) { jmpcc32(test_s(), imm8); }
  2312. pub unsafe fn instr32_79(imm8: i32) { jmpcc32(!test_s(), imm8); }
  2313. pub unsafe fn instr32_7A(imm8: i32) { jmpcc32(test_p(), imm8); }
  2314. pub unsafe fn instr32_7B(imm8: i32) { jmpcc32(!test_p(), imm8); }
  2315. pub unsafe fn instr32_7C(imm8: i32) { jmpcc32(test_l(), imm8); }
  2316. pub unsafe fn instr32_7D(imm8: i32) { jmpcc32(!test_l(), imm8); }
  2317. pub unsafe fn instr32_7E(imm8: i32) { jmpcc32(test_le(), imm8); }
  2318. pub unsafe fn instr32_7F(imm8: i32) { jmpcc32(!test_le(), imm8); }
  2319. pub unsafe fn instr_F2A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2320. pub unsafe fn instr_F3A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2321. pub unsafe fn instr16_F2A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2322. pub unsafe fn instr16_F3A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2323. pub unsafe fn instr32_F2A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2324. pub unsafe fn instr32_F3A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2325. pub unsafe fn instr_F2A6() { cmpsb_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2326. pub unsafe fn instr_F3A6() { cmpsb_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2327. pub unsafe fn instr16_F2A7() {
  2328. cmpsw_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  2329. }
  2330. pub unsafe fn instr16_F3A7() {
  2331. cmpsw_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  2332. }
  2333. pub unsafe fn instr32_F2A7() {
  2334. cmpsd_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  2335. }
  2336. pub unsafe fn instr32_F3A7() {
  2337. cmpsd_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
  2338. }
  2339. pub unsafe fn instr_F2AA() { stosb_rep(is_asize_32()); }
  2340. pub unsafe fn instr_F3AA() { stosb_rep(is_asize_32()); }
  2341. pub unsafe fn instr16_F2AB() { stosw_rep(is_asize_32()); }
  2342. pub unsafe fn instr16_F3AB() { stosw_rep(is_asize_32()); }
  2343. pub unsafe fn instr32_F2AB() { stosd_rep(is_asize_32()); }
  2344. pub unsafe fn instr32_F3AB() { stosd_rep(is_asize_32()); }
  2345. pub unsafe fn instr_F2AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2346. pub unsafe fn instr_F3AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2347. pub unsafe fn instr16_F2AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2348. pub unsafe fn instr16_F3AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2349. pub unsafe fn instr32_F2AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2350. pub unsafe fn instr32_F3AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
  2351. pub unsafe fn instr_F2AE() { scasb_repnz(is_asize_32()); }
  2352. pub unsafe fn instr_F3AE() { scasb_repz(is_asize_32()); }
  2353. pub unsafe fn instr16_F2AF() { scasw_repnz(is_asize_32()); }
  2354. pub unsafe fn instr16_F3AF() { scasw_repz(is_asize_32()); }
  2355. pub unsafe fn instr32_F2AF() { scasd_repnz(is_asize_32()); }
  2356. pub unsafe fn instr32_F3AF() { scasd_repz(is_asize_32()); }
  2357. #[no_mangle]
  2358. pub unsafe fn instr_D8_0_mem(addr: i32) { fpu_fadd(0, return_on_pagefault!(fpu_load_m32(addr))); }
  2359. #[no_mangle]
  2360. pub unsafe fn instr_D8_0_reg(r: i32) { fpu_fadd(0, fpu_get_sti(r)); }
  2361. #[no_mangle]
  2362. pub unsafe fn instr_D8_1_mem(addr: i32) { fpu_fmul(0, return_on_pagefault!(fpu_load_m32(addr))); }
  2363. #[no_mangle]
  2364. pub unsafe fn instr_D8_1_reg(r: i32) { fpu_fmul(0, fpu_get_sti(r)); }
  2365. #[no_mangle]
  2366. pub unsafe fn instr_D8_2_mem(addr: i32) { fpu_fcom(return_on_pagefault!(fpu_load_m32(addr))); }
  2367. #[no_mangle]
  2368. pub unsafe fn instr_D8_2_reg(r: i32) { fpu_fcom(fpu_get_sti(r)); }
  2369. #[no_mangle]
  2370. pub unsafe fn instr_D8_3_mem(addr: i32) { fpu_fcomp(return_on_pagefault!(fpu_load_m32(addr))); }
  2371. #[no_mangle]
  2372. pub unsafe fn instr_D8_3_reg(r: i32) { fpu_fcomp(fpu_get_sti(r)); }
  2373. #[no_mangle]
  2374. pub unsafe fn instr_D8_4_mem(addr: i32) { fpu_fsub(0, return_on_pagefault!(fpu_load_m32(addr))); }
  2375. #[no_mangle]
  2376. pub unsafe fn instr_D8_4_reg(r: i32) { fpu_fsub(0, fpu_get_sti(r)); }
  2377. #[no_mangle]
  2378. pub unsafe fn instr_D8_5_mem(addr: i32) { fpu_fsubr(0, return_on_pagefault!(fpu_load_m32(addr))); }
  2379. #[no_mangle]
  2380. pub unsafe fn instr_D8_5_reg(r: i32) { fpu_fsubr(0, fpu_get_sti(r)); }
  2381. #[no_mangle]
  2382. pub unsafe fn instr_D8_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_load_m32(addr))); }
  2383. #[no_mangle]
  2384. pub unsafe fn instr_D8_6_reg(r: i32) { fpu_fdiv(0, fpu_get_sti(r)); }
  2385. #[no_mangle]
  2386. pub unsafe fn instr_D8_7_mem(addr: i32) { fpu_fdivr(0, return_on_pagefault!(fpu_load_m32(addr))); }
  2387. #[no_mangle]
  2388. pub unsafe fn instr_D8_7_reg(r: i32) { fpu_fdivr(0, fpu_get_sti(r)); }
  2389. #[no_mangle]
  2390. pub unsafe fn instr16_D9_0_mem(addr: i32) { fpu_fldm32(addr); }
  2391. #[no_mangle]
  2392. pub unsafe fn instr16_D9_0_reg(r: i32) { fpu_push(fpu_get_sti(r)); }
  2393. #[no_mangle]
  2394. pub unsafe fn instr16_D9_1_mem(addr: i32) {
  2395. dbg_log!("d9/1");
  2396. trigger_ud();
  2397. }
  2398. #[no_mangle]
  2399. pub unsafe fn instr16_D9_1_reg(r: i32) { fpu_fxch(r); }
  2400. #[no_mangle]
  2401. pub unsafe fn instr16_D9_2_mem(addr: i32) { fpu_fstm32(addr); }
  2402. #[no_mangle]
  2403. pub unsafe fn instr16_D9_2_reg(r: i32) {
  2404. if r != 0 {
  2405. trigger_ud();
  2406. };
  2407. }
  2408. #[no_mangle]
  2409. pub unsafe fn instr16_D9_3_mem(addr: i32) { fpu_fstm32p(addr); }
  2410. #[no_mangle]
  2411. pub unsafe fn instr16_D9_3_reg(r: i32) { fpu_fstp(r) }
  2412. #[no_mangle]
  2413. pub unsafe fn instr16_D9_4_mem(addr: i32) { fpu_fldenv16(addr); }
  2414. #[no_mangle]
  2415. pub unsafe fn instr32_D9_4_mem(addr: i32) { fpu_fldenv32(addr); }
  2416. #[no_mangle]
  2417. pub unsafe fn instr16_D9_4_reg(r: i32) {
  2418. let st0 = fpu_get_st0();
  2419. match r {
  2420. 0 => {
  2421. // fchs
  2422. fpu_write_st(*fpu_stack_ptr as i32, -st0);
  2423. },
  2424. 1 => {
  2425. // fabs
  2426. fpu_write_st(*fpu_stack_ptr as i32, st0.abs());
  2427. },
  2428. 4 => {
  2429. fpu_ftst(st0);
  2430. },
  2431. 5 => {
  2432. fpu_fxam(st0);
  2433. },
  2434. _ => {
  2435. dbg_log!("{:x}", r);
  2436. trigger_ud();
  2437. },
  2438. };
  2439. }
  2440. #[no_mangle]
  2441. pub unsafe fn instr16_D9_5_mem(addr: i32) { fpu_fldcw(addr); }
  2442. #[no_mangle]
  2443. pub unsafe fn instr16_D9_5_reg(r: i32) {
  2444. // fld1/fldl2t/fldl2e/fldpi/fldlg2/fldln2/fldz
  2445. match r {
  2446. 0 => {
  2447. fpu_push(1.0);
  2448. },
  2449. 1 => {
  2450. fpu_push(M_LN10 / M_LN2);
  2451. },
  2452. 2 => {
  2453. fpu_push(M_LOG2E);
  2454. },
  2455. 3 => {
  2456. fpu_push(M_PI);
  2457. },
  2458. 4 => {
  2459. fpu_push(M_LN2 / M_LN10);
  2460. },
  2461. 5 => {
  2462. fpu_push(M_LN2);
  2463. },
  2464. 6 => {
  2465. fpu_push(0.0);
  2466. },
  2467. 7 => {
  2468. dbg_log!("d9/5/7");
  2469. trigger_ud();
  2470. },
  2471. _ => {},
  2472. };
  2473. }
  2474. #[no_mangle]
  2475. pub unsafe fn instr16_D9_6_mem(addr: i32) { fpu_fstenv16(addr); }
  2476. #[no_mangle]
  2477. pub unsafe fn instr32_D9_6_mem(addr: i32) { fpu_fstenv32(addr); }
  2478. #[no_mangle]
  2479. pub unsafe fn instr16_D9_6_reg(r: i32) {
  2480. match r {
  2481. 0 => {
  2482. // f2xm1
  2483. let st0 = fpu_get_st0();
  2484. let mut r = pow(2.0, st0) - 1.0;
  2485. if r == -1.0 {
  2486. // Intel ...
  2487. r = -3.475818901301751e+184
  2488. }
  2489. fpu_write_st(*fpu_stack_ptr as i32, r)
  2490. },
  2491. 1 => {
  2492. // fyl2x
  2493. fpu_fyl2x();
  2494. },
  2495. 2 => {
  2496. // fptan
  2497. let st0 = fpu_get_st0();
  2498. if pow(-2.0, 63.0) < st0 && st0 < pow(2.0, 63.0) {
  2499. fpu_write_st(*fpu_stack_ptr as i32, st0.tan());
  2500. // no bug: push constant 1
  2501. fpu_push(1.0);
  2502. *fpu_status_word &= !FPU_C2;
  2503. }
  2504. else {
  2505. *fpu_status_word |= FPU_C2;
  2506. }
  2507. },
  2508. 3 => {
  2509. // fpatan
  2510. let st0 = fpu_get_st0();
  2511. fpu_write_st(*fpu_stack_ptr as i32 + 1 & 7, fpu_get_sti(1).atan2(st0));
  2512. fpu_pop();
  2513. },
  2514. 4 => {
  2515. fpu_fxtract();
  2516. },
  2517. 5 => {
  2518. // fprem1
  2519. fpu_fprem(true);
  2520. },
  2521. 6 => {
  2522. // fdecstp
  2523. *fpu_stack_ptr = (*fpu_stack_ptr).wrapping_sub(1) & 7;
  2524. *fpu_status_word &= !FPU_C1
  2525. },
  2526. 7 => {
  2527. // fincstp
  2528. *fpu_stack_ptr = (*fpu_stack_ptr).wrapping_add(1) & 7;
  2529. *fpu_status_word &= !FPU_C1
  2530. },
  2531. _ => {
  2532. dbg_assert!(false);
  2533. },
  2534. };
  2535. }
  2536. #[no_mangle]
  2537. pub unsafe fn instr16_D9_7_mem(addr: i32) { fpu_fstcw(addr); }
  2538. #[no_mangle]
  2539. pub unsafe fn instr16_D9_7_reg(r: i32) {
  2540. let st0 = fpu_get_st0();
  2541. match r {
  2542. 0 => {
  2543. // fprem
  2544. fpu_fprem(false);
  2545. },
  2546. 1 => {
  2547. // fyl2xp1: y * log2(x+1) and pop
  2548. let y = fpu_get_sti(1) * (st0 + 1.0).ln() / M_LN2;
  2549. fpu_write_st(*fpu_stack_ptr as i32 + 1 & 7, y);
  2550. fpu_pop();
  2551. },
  2552. 2 => {
  2553. if st0 < 0.0 {
  2554. fpu_invalid_arithmetic();
  2555. }
  2556. fpu_write_st(*fpu_stack_ptr as i32, st0.sqrt())
  2557. },
  2558. 3 => {
  2559. // fsincos
  2560. if pow(-2.0, 63.0) < st0 && st0 < pow(2.0, 63.0) {
  2561. fpu_write_st(*fpu_stack_ptr as i32, st0.sin());
  2562. fpu_push(st0.cos());
  2563. *fpu_status_word &= !FPU_C2;
  2564. }
  2565. else {
  2566. *fpu_status_word |= FPU_C2;
  2567. }
  2568. },
  2569. 4 => {
  2570. // frndint
  2571. fpu_write_st(*fpu_stack_ptr as i32, fpu_integer_round(st0));
  2572. },
  2573. 5 => {
  2574. // fscale
  2575. let y = st0 * pow(2.0, trunc(fpu_get_sti(1)));
  2576. fpu_write_st(*fpu_stack_ptr as i32, y);
  2577. },
  2578. 6 => {
  2579. if pow(-2.0, 63.0) < st0 && st0 < pow(2.0, 63.0) {
  2580. fpu_write_st(*fpu_stack_ptr as i32, st0.sin());
  2581. *fpu_status_word &= !FPU_C2;
  2582. }
  2583. else {
  2584. *fpu_status_word |= FPU_C2;
  2585. }
  2586. },
  2587. 7 => {
  2588. if pow(-2.0, 63.0) < st0 && st0 < pow(2.0, 63.0) {
  2589. fpu_write_st(*fpu_stack_ptr as i32, st0.cos());
  2590. *fpu_status_word &= !FPU_C2;
  2591. }
  2592. else {
  2593. *fpu_status_word |= FPU_C2;
  2594. }
  2595. },
  2596. _ => {
  2597. dbg_assert!(false);
  2598. },
  2599. };
  2600. }
  2601. #[no_mangle]
  2602. pub unsafe fn instr32_D9_0_reg(r: i32) { instr16_D9_0_reg(r) }
  2603. #[no_mangle]
  2604. pub unsafe fn instr32_D9_1_reg(r: i32) { instr16_D9_1_reg(r) }
  2605. #[no_mangle]
  2606. pub unsafe fn instr32_D9_2_reg(r: i32) { instr16_D9_2_reg(r) }
  2607. #[no_mangle]
  2608. pub unsafe fn instr32_D9_3_reg(r: i32) { instr16_D9_3_reg(r) }
  2609. #[no_mangle]
  2610. pub unsafe fn instr32_D9_4_reg(r: i32) { instr16_D9_4_reg(r) }
  2611. #[no_mangle]
  2612. pub unsafe fn instr32_D9_5_reg(r: i32) { instr16_D9_5_reg(r) }
  2613. #[no_mangle]
  2614. pub unsafe fn instr32_D9_6_reg(r: i32) { instr16_D9_6_reg(r) }
  2615. #[no_mangle]
  2616. pub unsafe fn instr32_D9_7_reg(r: i32) { instr16_D9_7_reg(r) }
  2617. #[no_mangle]
  2618. pub unsafe fn instr32_D9_0_mem(r: i32) { instr16_D9_0_mem(r) }
  2619. #[no_mangle]
  2620. pub unsafe fn instr32_D9_1_mem(r: i32) { instr16_D9_1_mem(r) }
  2621. #[no_mangle]
  2622. pub unsafe fn instr32_D9_2_mem(r: i32) { instr16_D9_2_mem(r) }
  2623. #[no_mangle]
  2624. pub unsafe fn instr32_D9_3_mem(r: i32) { instr16_D9_3_mem(r) }
  2625. #[no_mangle]
  2626. pub unsafe fn instr32_D9_5_mem(r: i32) { instr16_D9_5_mem(r) }
  2627. #[no_mangle]
  2628. pub unsafe fn instr32_D9_7_mem(r: i32) { instr16_D9_7_mem(r) }
  2629. #[no_mangle]
  2630. pub unsafe fn instr_DA_0_mem(addr: i32) {
  2631. fpu_fadd(0, return_on_pagefault!(safe_read32s(addr)) as f64);
  2632. }
  2633. #[no_mangle]
  2634. pub unsafe fn instr_DA_1_mem(addr: i32) {
  2635. fpu_fmul(0, return_on_pagefault!(safe_read32s(addr)) as f64);
  2636. }
  2637. #[no_mangle]
  2638. pub unsafe fn instr_DA_2_mem(addr: i32) {
  2639. fpu_fcom(return_on_pagefault!(safe_read32s(addr)) as f64);
  2640. }
  2641. #[no_mangle]
  2642. pub unsafe fn instr_DA_3_mem(addr: i32) {
  2643. fpu_fcomp(return_on_pagefault!(safe_read32s(addr)) as f64);
  2644. }
  2645. #[no_mangle]
  2646. pub unsafe fn instr_DA_4_mem(addr: i32) {
  2647. fpu_fsub(0, return_on_pagefault!(safe_read32s(addr)) as f64);
  2648. }
  2649. #[no_mangle]
  2650. pub unsafe fn instr_DA_5_mem(addr: i32) {
  2651. fpu_fsubr(0, return_on_pagefault!(safe_read32s(addr)) as f64);
  2652. }
  2653. #[no_mangle]
  2654. pub unsafe fn instr_DA_6_mem(addr: i32) {
  2655. fpu_fdiv(0, return_on_pagefault!(safe_read32s(addr)) as f64);
  2656. }
  2657. #[no_mangle]
  2658. pub unsafe fn instr_DA_7_mem(addr: i32) {
  2659. fpu_fdivr(0, return_on_pagefault!(safe_read32s(addr)) as f64);
  2660. }
  2661. #[no_mangle]
  2662. pub unsafe fn instr_DA_0_reg(r: i32) { fpu_fcmovcc(test_b(), r); }
  2663. #[no_mangle]
  2664. pub unsafe fn instr_DA_1_reg(r: i32) { fpu_fcmovcc(test_z(), r); }
  2665. #[no_mangle]
  2666. pub unsafe fn instr_DA_2_reg(r: i32) { fpu_fcmovcc(test_be(), r); }
  2667. #[no_mangle]
  2668. pub unsafe fn instr_DA_3_reg(r: i32) { fpu_fcmovcc(test_p(), r); }
  2669. #[no_mangle]
  2670. pub unsafe fn instr_DA_4_reg(r: i32) { trigger_ud(); }
  2671. #[no_mangle]
  2672. pub unsafe fn instr_DA_5_reg(r: i32) {
  2673. if r == 1 {
  2674. fpu_fucompp();
  2675. }
  2676. else {
  2677. trigger_ud();
  2678. };
  2679. }
  2680. #[no_mangle]
  2681. pub unsafe fn instr_DA_6_reg(r: i32) { trigger_ud(); }
  2682. #[no_mangle]
  2683. pub unsafe fn instr_DA_7_reg(r: i32) { trigger_ud(); }
  2684. #[no_mangle]
  2685. pub unsafe fn instr_DB_0_mem(addr: i32) { fpu_fildm32(addr); }
  2686. #[no_mangle]
  2687. pub unsafe fn instr_DB_1_mem(addr: i32) {
  2688. dbg_log!("fisttp");
  2689. fpu_unimpl();
  2690. }
  2691. #[no_mangle]
  2692. pub unsafe fn instr_DB_2_mem(addr: i32) { fpu_fistm32(addr); }
  2693. #[no_mangle]
  2694. pub unsafe fn instr_DB_3_mem(addr: i32) { fpu_fistm32p(addr); }
  2695. #[no_mangle]
  2696. pub unsafe fn instr_DB_4_mem(addr: i32) { trigger_ud(); }
  2697. #[no_mangle]
  2698. pub unsafe fn instr_DB_5_mem(addr: i32) { fpu_fldm80(addr); }
  2699. #[no_mangle]
  2700. pub unsafe fn instr_DB_6_mem(addr: i32) { trigger_ud(); }
  2701. #[no_mangle]
  2702. pub unsafe fn instr_DB_7_mem(addr: i32) { fpu_fst80p(addr); }
  2703. #[no_mangle]
  2704. pub unsafe fn instr_DB_0_reg(r: i32) { fpu_fcmovcc(!test_b(), r); }
  2705. #[no_mangle]
  2706. pub unsafe fn instr_DB_1_reg(r: i32) { fpu_fcmovcc(!test_z(), r); }
  2707. #[no_mangle]
  2708. pub unsafe fn instr_DB_2_reg(r: i32) { fpu_fcmovcc(!test_be(), r); }
  2709. #[no_mangle]
  2710. pub unsafe fn instr_DB_3_reg(r: i32) { fpu_fcmovcc(!test_p(), r); }
  2711. #[no_mangle]
  2712. pub unsafe fn instr_DB_4_reg(r: i32) {
  2713. if r == 3 {
  2714. fpu_finit();
  2715. }
  2716. else if r == 4 || r == 1 || r == 0 {
  2717. // fsetpm, fdisi, fneni; treated as nop
  2718. }
  2719. else if r == 2 {
  2720. fpu_fclex();
  2721. }
  2722. else {
  2723. trigger_ud();
  2724. };
  2725. }
  2726. #[no_mangle]
  2727. pub unsafe fn instr_DB_5_reg(r: i32) { fpu_fucomi(r); }
  2728. #[no_mangle]
  2729. pub unsafe fn instr_DB_6_reg(r: i32) { fpu_fcomi(r); }
  2730. #[no_mangle]
  2731. pub unsafe fn instr_DB_7_reg(r: i32) { trigger_ud(); }
  2732. #[no_mangle]
  2733. pub unsafe fn instr_DC_0_mem(addr: i32) { fpu_fadd(0, return_on_pagefault!(fpu_load_m64(addr))); }
  2734. #[no_mangle]
  2735. pub unsafe fn instr_DC_1_mem(addr: i32) { fpu_fmul(0, return_on_pagefault!(fpu_load_m64(addr))); }
  2736. #[no_mangle]
  2737. pub unsafe fn instr_DC_2_mem(addr: i32) { fpu_fcom(return_on_pagefault!(fpu_load_m64(addr))); }
  2738. #[no_mangle]
  2739. pub unsafe fn instr_DC_3_mem(addr: i32) { fpu_fcomp(return_on_pagefault!(fpu_load_m64(addr))); }
  2740. #[no_mangle]
  2741. pub unsafe fn instr_DC_4_mem(addr: i32) { fpu_fsub(0, return_on_pagefault!(fpu_load_m64(addr))); }
  2742. #[no_mangle]
  2743. pub unsafe fn instr_DC_5_mem(addr: i32) { fpu_fsubr(0, return_on_pagefault!(fpu_load_m64(addr))); }
  2744. #[no_mangle]
  2745. pub unsafe fn instr_DC_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_load_m64(addr))); }
  2746. #[no_mangle]
  2747. pub unsafe fn instr_DC_7_mem(addr: i32) { fpu_fdivr(0, return_on_pagefault!(fpu_load_m64(addr))); }
  2748. #[no_mangle]
  2749. pub unsafe fn instr_DC_0_reg(r: i32) { fpu_fadd(r, fpu_get_sti(r)); }
  2750. #[no_mangle]
  2751. pub unsafe fn instr_DC_1_reg(r: i32) { fpu_fmul(r, fpu_get_sti(r)); }
  2752. #[no_mangle]
  2753. pub unsafe fn instr_DC_2_reg(r: i32) { fpu_fcom(fpu_get_sti(r)); }
  2754. #[no_mangle]
  2755. pub unsafe fn instr_DC_3_reg(r: i32) { fpu_fcomp(fpu_get_sti(r)); }
  2756. #[no_mangle]
  2757. pub unsafe fn instr_DC_4_reg(r: i32) { fpu_fsub(r, fpu_get_sti(r)); }
  2758. #[no_mangle]
  2759. pub unsafe fn instr_DC_5_reg(r: i32) { fpu_fsubr(r, fpu_get_sti(r)); }
  2760. #[no_mangle]
  2761. pub unsafe fn instr_DC_6_reg(r: i32) { fpu_fdiv(r, fpu_get_sti(r)); }
  2762. #[no_mangle]
  2763. pub unsafe fn instr_DC_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); }
  2764. #[no_mangle]
  2765. pub unsafe fn instr16_DD_0_mem(addr: i32) { fpu_fldm64(addr); }
  2766. #[no_mangle]
  2767. pub unsafe fn instr16_DD_1_mem(addr: i32) {
  2768. dbg_log!("fisttp");
  2769. fpu_unimpl();
  2770. }
  2771. #[no_mangle]
  2772. pub unsafe fn instr16_DD_2_mem(addr: i32) { fpu_fstm64(addr); }
  2773. #[no_mangle]
  2774. pub unsafe fn instr16_DD_3_mem(addr: i32) { fpu_fstm64p(addr); }
  2775. #[no_mangle]
  2776. pub unsafe fn instr16_DD_4_mem(addr: i32) { fpu_frstor16(addr); }
  2777. #[no_mangle]
  2778. pub unsafe fn instr32_DD_4_mem(addr: i32) { fpu_frstor32(addr); }
  2779. #[no_mangle]
  2780. pub unsafe fn instr16_DD_5_mem(addr: i32) {
  2781. dbg_log!("dd/5");
  2782. trigger_ud();
  2783. }
  2784. #[no_mangle]
  2785. pub unsafe fn instr16_DD_6_mem(addr: i32) { fpu_fsave16(addr); }
  2786. #[no_mangle]
  2787. pub unsafe fn instr32_DD_6_mem(addr: i32) { fpu_fsave32(addr); }
  2788. #[no_mangle]
  2789. pub unsafe fn instr16_DD_7_mem(addr: i32) { fpu_fnstsw_mem(addr); }
  2790. #[no_mangle]
  2791. pub unsafe fn instr16_DD_0_reg(r: i32) { fpu_ffree(r); }
  2792. #[no_mangle]
  2793. pub unsafe fn instr16_DD_1_reg(r: i32) { fpu_fxch(r) }
  2794. #[no_mangle]
  2795. pub unsafe fn instr16_DD_2_reg(r: i32) { fpu_fst(r); }
  2796. #[no_mangle]
  2797. pub unsafe fn instr16_DD_3_reg(r: i32) { fpu_fstp(r); }
  2798. #[no_mangle]
  2799. pub unsafe fn instr16_DD_4_reg(r: i32) { fpu_fucom(r); }
  2800. #[no_mangle]
  2801. pub unsafe fn instr16_DD_5_reg(r: i32) { fpu_fucomp(r); }
  2802. #[no_mangle]
  2803. pub unsafe fn instr16_DD_6_reg(r: i32) { trigger_ud(); }
  2804. #[no_mangle]
  2805. pub unsafe fn instr16_DD_7_reg(r: i32) { trigger_ud(); }
  2806. #[no_mangle]
  2807. pub unsafe fn instr32_DD_0_reg(r: i32) { instr16_DD_0_reg(r) }
  2808. #[no_mangle]
  2809. pub unsafe fn instr32_DD_1_reg(r: i32) { instr16_DD_1_reg(r) }
  2810. #[no_mangle]
  2811. pub unsafe fn instr32_DD_2_reg(r: i32) { instr16_DD_2_reg(r) }
  2812. #[no_mangle]
  2813. pub unsafe fn instr32_DD_3_reg(r: i32) { instr16_DD_3_reg(r) }
  2814. #[no_mangle]
  2815. pub unsafe fn instr32_DD_4_reg(r: i32) { instr16_DD_4_reg(r) }
  2816. #[no_mangle]
  2817. pub unsafe fn instr32_DD_5_reg(r: i32) { instr16_DD_5_reg(r) }
  2818. #[no_mangle]
  2819. pub unsafe fn instr32_DD_6_reg(r: i32) { instr16_DD_6_reg(r) }
  2820. #[no_mangle]
  2821. pub unsafe fn instr32_DD_7_reg(r: i32) { instr16_DD_7_reg(r) }
  2822. #[no_mangle]
  2823. pub unsafe fn instr32_DD_0_mem(r: i32) { instr16_DD_0_mem(r) }
  2824. #[no_mangle]
  2825. pub unsafe fn instr32_DD_1_mem(r: i32) { instr16_DD_1_mem(r) }
  2826. #[no_mangle]
  2827. pub unsafe fn instr32_DD_2_mem(r: i32) { instr16_DD_2_mem(r) }
  2828. #[no_mangle]
  2829. pub unsafe fn instr32_DD_3_mem(r: i32) { instr16_DD_3_mem(r) }
  2830. #[no_mangle]
  2831. pub unsafe fn instr32_DD_5_mem(r: i32) { instr16_DD_5_mem(r) }
  2832. #[no_mangle]
  2833. pub unsafe fn instr32_DD_7_mem(r: i32) { instr16_DD_7_mem(r) }
  2834. #[no_mangle]
  2835. pub unsafe fn instr_DE_0_mem(addr: i32) {
  2836. fpu_fadd(0, return_on_pagefault!(safe_read16(addr)) as i16 as f64);
  2837. }
  2838. #[no_mangle]
  2839. pub unsafe fn instr_DE_1_mem(addr: i32) {
  2840. fpu_fmul(0, return_on_pagefault!(safe_read16(addr)) as i16 as f64);
  2841. }
  2842. #[no_mangle]
  2843. pub unsafe fn instr_DE_2_mem(addr: i32) {
  2844. fpu_fcom(return_on_pagefault!(safe_read16(addr)) as i16 as f64);
  2845. }
  2846. #[no_mangle]
  2847. pub unsafe fn instr_DE_3_mem(addr: i32) {
  2848. fpu_fcomp(return_on_pagefault!(safe_read16(addr)) as i16 as f64);
  2849. }
  2850. #[no_mangle]
  2851. pub unsafe fn instr_DE_4_mem(addr: i32) {
  2852. fpu_fsub(0, return_on_pagefault!(safe_read16(addr)) as i16 as f64);
  2853. }
  2854. #[no_mangle]
  2855. pub unsafe fn instr_DE_5_mem(addr: i32) {
  2856. fpu_fsubr(0, return_on_pagefault!(safe_read16(addr)) as i16 as f64);
  2857. }
  2858. #[no_mangle]
  2859. pub unsafe fn instr_DE_6_mem(addr: i32) {
  2860. fpu_fdiv(0, return_on_pagefault!(safe_read16(addr)) as i16 as f64);
  2861. }
  2862. #[no_mangle]
  2863. pub unsafe fn instr_DE_7_mem(addr: i32) {
  2864. fpu_fdivr(0, return_on_pagefault!(safe_read16(addr)) as i16 as f64);
  2865. }
  2866. #[no_mangle]
  2867. pub unsafe fn instr_DE_0_reg(r: i32) {
  2868. fpu_fadd(r, fpu_get_sti(r));
  2869. fpu_pop();
  2870. }
  2871. #[no_mangle]
  2872. pub unsafe fn instr_DE_1_reg(r: i32) {
  2873. fpu_fmul(r, fpu_get_sti(r));
  2874. fpu_pop();
  2875. }
  2876. #[no_mangle]
  2877. pub unsafe fn instr_DE_2_reg(r: i32) {
  2878. fpu_fcom(fpu_get_sti(r));
  2879. fpu_pop();
  2880. }
  2881. #[no_mangle]
  2882. pub unsafe fn instr_DE_3_reg(r: i32) {
  2883. if r == 1 {
  2884. fpu_fcomp(fpu_get_sti(r));
  2885. fpu_pop();
  2886. }
  2887. else {
  2888. trigger_ud();
  2889. }
  2890. }
  2891. #[no_mangle]
  2892. pub unsafe fn instr_DE_4_reg(r: i32) {
  2893. fpu_fsub(r, fpu_get_sti(r));
  2894. fpu_pop();
  2895. }
  2896. #[no_mangle]
  2897. pub unsafe fn instr_DE_5_reg(r: i32) {
  2898. fpu_fsubr(r, fpu_get_sti(r));
  2899. fpu_pop();
  2900. }
  2901. #[no_mangle]
  2902. pub unsafe fn instr_DE_6_reg(r: i32) {
  2903. fpu_fdiv(r, fpu_get_sti(r));
  2904. fpu_pop();
  2905. }
  2906. #[no_mangle]
  2907. pub unsafe fn instr_DE_7_reg(r: i32) {
  2908. fpu_fdivr(r, fpu_get_sti(r));
  2909. fpu_pop();
  2910. }
  2911. #[no_mangle]
  2912. pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) }
  2913. #[no_mangle]
  2914. pub unsafe fn instr_DF_1_mem(addr: i32) {
  2915. dbg_log!("fisttp");
  2916. fpu_unimpl();
  2917. }
  2918. #[no_mangle]
  2919. pub unsafe fn instr_DF_2_mem(addr: i32) { fpu_fistm16(addr); }
  2920. #[no_mangle]
  2921. pub unsafe fn instr_DF_3_mem(addr: i32) { fpu_fistm16p(addr); }
  2922. #[no_mangle]
  2923. pub unsafe fn instr_DF_4_mem(addr: i32) {
  2924. dbg_log!("fbld");
  2925. fpu_unimpl();
  2926. }
  2927. #[no_mangle]
  2928. pub unsafe fn instr_DF_5_mem(addr: i32) { fpu_fildm64(addr); }
  2929. #[no_mangle]
  2930. pub unsafe fn instr_DF_6_mem(addr: i32) {
  2931. dbg_log!("fbstp");
  2932. fpu_unimpl();
  2933. }
  2934. #[no_mangle]
  2935. pub unsafe fn instr_DF_7_mem(addr: i32) { fpu_fistm64p(addr); }
  2936. #[no_mangle]
  2937. pub unsafe fn instr_DF_0_reg(r: i32) {
  2938. fpu_ffree(r);
  2939. fpu_pop();
  2940. }
  2941. #[no_mangle]
  2942. pub unsafe fn instr_DF_1_reg(r: i32) { fpu_fxch(r) }
  2943. #[no_mangle]
  2944. pub unsafe fn instr_DF_2_reg(r: i32) { fpu_fstp(r); }
  2945. #[no_mangle]
  2946. pub unsafe fn instr_DF_3_reg(r: i32) { fpu_fstp(r); }
  2947. #[no_mangle]
  2948. pub unsafe fn instr_DF_4_reg(r: i32) {
  2949. if r == 0 {
  2950. fpu_fnstsw_reg();
  2951. }
  2952. else {
  2953. trigger_ud();
  2954. };
  2955. }
  2956. #[no_mangle]
  2957. pub unsafe fn instr_DF_5_reg(r: i32) { fpu_fucomip(r); }
  2958. #[no_mangle]
  2959. pub unsafe fn instr_DF_6_reg(r: i32) { fpu_fcomip(r); }
  2960. #[no_mangle]
  2961. pub unsafe fn instr_DF_7_reg(r: i32) { trigger_ud(); }
  2962. #[no_mangle]
  2963. pub unsafe fn instr16_E0(imm8s: i32) { loopne16(imm8s); }
  2964. #[no_mangle]
  2965. pub unsafe fn instr16_E1(imm8s: i32) { loope16(imm8s); }
  2966. #[no_mangle]
  2967. pub unsafe fn instr16_E2(imm8s: i32) { loop16(imm8s); }
  2968. #[no_mangle]
  2969. pub unsafe fn instr16_E3(imm8s: i32) { jcxz16(imm8s); }
  2970. #[no_mangle]
  2971. pub unsafe fn instr32_E0(imm8s: i32) { loopne32(imm8s); }
  2972. #[no_mangle]
  2973. pub unsafe fn instr32_E1(imm8s: i32) { loope32(imm8s); }
  2974. #[no_mangle]
  2975. pub unsafe fn instr32_E2(imm8s: i32) { loop32(imm8s); }
  2976. #[no_mangle]
  2977. pub unsafe fn instr32_E3(imm8s: i32) { jcxz32(imm8s); }
  2978. pub unsafe fn instr16_EB(imm8: i32) {
  2979. // jmp near
  2980. jmp_rel16(imm8);
  2981. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  2982. }
  2983. pub unsafe fn instr32_EB(imm8: i32) {
  2984. // jmp near
  2985. *instruction_pointer = *instruction_pointer + imm8;
  2986. dbg_assert!(*is_32 || get_real_eip() < 0x10000);
  2987. }