jit_instructions.rs 295 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791
  1. #![allow(non_snake_case)]
  2. use codegen;
  3. use codegen::{BitSize, ConditionNegate};
  4. use cpu::cpu::{
  5. FLAGS_ALL, FLAGS_DEFAULT, FLAGS_MASK, FLAG_ADJUST, FLAG_CARRY, FLAG_DIRECTION, FLAG_INTERRUPT,
  6. FLAG_IOPL, FLAG_OVERFLOW, FLAG_SUB, FLAG_VM, FLAG_ZERO, OPSIZE_8, OPSIZE_16, OPSIZE_32,
  7. };
  8. use cpu::global_pointers;
  9. use jit::{Instruction, InstructionOperand, InstructionOperandDest, JitContext};
  10. use modrm::{jit_add_seg_offset, jit_add_seg_offset_no_override, ModrmByte};
  11. use prefix::SEG_PREFIX_ZERO;
  12. use prefix::{PREFIX_66, PREFIX_67, PREFIX_F2, PREFIX_F3};
  13. use regs;
  14. use regs::{AX, BP, BX, CX, DI, DX, SI, SP};
  15. use regs::{CS, DS, ES, FS, GS, SS};
  16. use regs::{EAX, EBP, EBX, ECX, EDI, EDX, ESI, ESP};
  17. use wasmgen::wasm_builder::{WasmBuilder, WasmLocal};
  18. enum LocalOrImmediate<'a> {
  19. WasmLocal(&'a WasmLocal),
  20. Immediate(i32),
  21. }
  22. impl<'a> LocalOrImmediate<'a> {
  23. pub fn gen_get(&self, builder: &mut WasmBuilder) {
  24. match self {
  25. LocalOrImmediate::WasmLocal(l) => builder.get_local(l),
  26. LocalOrImmediate::Immediate(i) => builder.const_i32(*i),
  27. }
  28. }
  29. pub fn gen_get_mask255(&self, builder: &mut WasmBuilder) {
  30. match self {
  31. LocalOrImmediate::WasmLocal(l) => {
  32. builder.get_local(l);
  33. builder.const_i32(0xFF);
  34. builder.and_i32()
  35. },
  36. LocalOrImmediate::Immediate(i) => builder.const_i32(*i & 0xFF),
  37. }
  38. }
  39. pub fn eq_local(&self, other_local: &WasmLocal) -> bool {
  40. match self {
  41. &LocalOrImmediate::WasmLocal(local) => local == other_local,
  42. LocalOrImmediate::Immediate(_) => false,
  43. }
  44. }
  45. pub fn is_zero(&self) -> bool {
  46. match self {
  47. LocalOrImmediate::Immediate(0) => true,
  48. _ => false,
  49. }
  50. }
  51. fn to_instruction_operand(&self, ctx: &mut JitContext) -> InstructionOperand {
  52. match self {
  53. &LocalOrImmediate::WasmLocal(source) => {
  54. local_to_instruction_operand(ctx, source).into()
  55. },
  56. &LocalOrImmediate::Immediate(i) => InstructionOperand::Immediate(i),
  57. }
  58. }
  59. }
  60. fn local_to_instruction_operand(ctx: &mut JitContext, local: &WasmLocal) -> InstructionOperandDest {
  61. if ctx.register_locals.iter().any(|l| l == local) {
  62. // safe because register locals are alive for the duration of the entire function
  63. InstructionOperandDest::WasmLocal(local.unsafe_clone())
  64. }
  65. else {
  66. InstructionOperandDest::Other
  67. }
  68. }
  69. pub fn jit_instruction(ctx: &mut JitContext, instr_flags: &mut u32) {
  70. ctx.cpu.prefixes = 0;
  71. ctx.start_of_current_instruction = ctx.cpu.eip;
  72. ::gen::jit::jit(
  73. ctx.cpu.read_imm8() as u32 | (ctx.cpu.osize_32() as u32) << 8,
  74. ctx,
  75. instr_flags,
  76. );
  77. }
  78. pub fn jit_handle_prefix(ctx: &mut JitContext, instr_flags: &mut u32) {
  79. ::gen::jit::jit(
  80. ctx.cpu.read_imm8() as u32 | (ctx.cpu.osize_32() as u32) << 8,
  81. ctx,
  82. instr_flags,
  83. );
  84. }
  85. pub fn jit_handle_segment_prefix(segment: u32, ctx: &mut JitContext, instr_flags: &mut u32) {
  86. dbg_assert!(segment <= 5);
  87. ctx.cpu.prefixes |= segment + 1;
  88. jit_handle_prefix(ctx, instr_flags)
  89. }
  90. pub fn instr16_0F_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  91. ::gen::jit0f::jit(ctx.cpu.read_imm8() as u32, ctx, instr_flags)
  92. }
  93. pub fn instr32_0F_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  94. ::gen::jit0f::jit(ctx.cpu.read_imm8() as u32 | 0x100, ctx, instr_flags)
  95. }
  96. pub fn instr_26_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  97. jit_handle_segment_prefix(ES, ctx, instr_flags)
  98. }
  99. pub fn instr_2E_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  100. jit_handle_segment_prefix(CS, ctx, instr_flags)
  101. }
  102. pub fn instr_36_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  103. jit_handle_segment_prefix(SS, ctx, instr_flags)
  104. }
  105. pub fn instr_3E_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  106. jit_handle_segment_prefix(DS, ctx, instr_flags)
  107. }
  108. pub fn instr_64_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  109. jit_handle_segment_prefix(FS, ctx, instr_flags)
  110. }
  111. pub fn instr_65_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  112. jit_handle_segment_prefix(GS, ctx, instr_flags)
  113. }
  114. pub fn instr_66_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  115. ctx.cpu.prefixes |= PREFIX_66;
  116. jit_handle_prefix(ctx, instr_flags)
  117. }
  118. pub fn instr_67_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  119. ctx.cpu.prefixes |= PREFIX_67;
  120. jit_handle_prefix(ctx, instr_flags)
  121. }
  122. pub fn instr_F0_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  123. // lock: Ignore
  124. jit_handle_prefix(ctx, instr_flags)
  125. }
  126. pub fn instr_F2_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  127. ctx.cpu.prefixes |= PREFIX_F2;
  128. jit_handle_prefix(ctx, instr_flags)
  129. }
  130. pub fn instr_F3_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
  131. ctx.cpu.prefixes |= PREFIX_F3;
  132. jit_handle_prefix(ctx, instr_flags)
  133. }
  134. fn sse_read_f32_xmm_mem(ctx: &mut JitContext, name: &str, modrm_byte: ModrmByte, r: u32) {
  135. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  136. ctx.builder.reinterpret_i32_as_f32();
  137. ctx.builder.const_i32(r as i32);
  138. ctx.builder.call_fn2_f32_i32(name);
  139. }
  140. fn sse_read_f32_xmm_xmm(ctx: &mut JitContext, name: &str, r1: u32, r2: u32) {
  141. ctx.builder
  142. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  143. ctx.builder.load_aligned_f32(0);
  144. ctx.builder.const_i32(r2 as i32);
  145. ctx.builder.call_fn2_f32_i32(name);
  146. }
  147. fn sse_read64_xmm_mem(ctx: &mut JitContext, name: &str, modrm_byte: ModrmByte, r: u32) {
  148. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  149. ctx.builder.const_i32(r as i32);
  150. ctx.builder.call_fn2_i64_i32(name);
  151. }
  152. fn sse_read64_xmm_xmm(ctx: &mut JitContext, name: &str, r1: u32, r2: u32) {
  153. ctx.builder
  154. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  155. ctx.builder.load_aligned_i64(0);
  156. ctx.builder.const_i32(r2 as i32);
  157. ctx.builder.call_fn2_i64_i32(name);
  158. }
  159. fn sse_read128_xmm_mem(ctx: &mut JitContext, name: &str, modrm_byte: ModrmByte, r: u32) {
  160. let dest = global_pointers::sse_scratch_register as u32;
  161. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  162. ctx.builder.const_i32(dest as i32);
  163. ctx.builder.const_i32(r as i32);
  164. ctx.builder.call_fn2(name);
  165. }
  166. fn sse_read128_xmm_mem_imm(
  167. ctx: &mut JitContext,
  168. name: &str,
  169. modrm_byte: ModrmByte,
  170. r: u32,
  171. imm: u32,
  172. ) {
  173. let dest = global_pointers::sse_scratch_register as u32;
  174. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  175. ctx.builder.const_i32(dest as i32);
  176. ctx.builder.const_i32(r as i32);
  177. ctx.builder.const_i32(imm as i32);
  178. ctx.builder.call_fn3(name);
  179. }
  180. fn sse_read128_xmm_xmm(ctx: &mut JitContext, name: &str, r1: u32, r2: u32) {
  181. // Make a copy to avoid aliasing problems: Called function expects a reg128, which must not
  182. // alias with memory
  183. codegen::gen_read_reg_xmm128_into_scratch(ctx, r1);
  184. let dest = global_pointers::sse_scratch_register;
  185. ctx.builder.const_i32(dest as i32);
  186. ctx.builder.const_i32(r2 as i32);
  187. ctx.builder.call_fn2(name);
  188. }
  189. fn sse_read128_xmm_xmm_imm(ctx: &mut JitContext, name: &str, r1: u32, r2: u32, imm: u32) {
  190. // Make a copy to avoid aliasing problems: Called function expects a reg128, which must not
  191. // alias with memory
  192. codegen::gen_read_reg_xmm128_into_scratch(ctx, r1);
  193. let dest = global_pointers::sse_scratch_register;
  194. ctx.builder.const_i32(dest as i32);
  195. ctx.builder.const_i32(r2 as i32);
  196. ctx.builder.const_i32(imm as i32);
  197. ctx.builder.call_fn3(name);
  198. }
  199. fn sse_mov_xmm_xmm(ctx: &mut JitContext, r1: u32, r2: u32) {
  200. ctx.builder
  201. .const_i32(global_pointers::get_reg_xmm_offset(r2) as i32);
  202. ctx.builder
  203. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  204. ctx.builder.load_aligned_i64(0);
  205. ctx.builder.store_aligned_i64(0);
  206. ctx.builder
  207. .const_i32(global_pointers::get_reg_xmm_offset(r2) as i32 + 8);
  208. ctx.builder
  209. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32 + 8);
  210. ctx.builder.load_aligned_i64(0);
  211. ctx.builder.store_aligned_i64(0);
  212. }
  213. fn mmx_read64_mm_mem32(ctx: &mut JitContext, name: &str, modrm_byte: ModrmByte, r: u32) {
  214. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  215. ctx.builder.const_i32(r as i32);
  216. ctx.builder.call_fn2(name)
  217. }
  218. fn mmx_read64_mm_mm32(ctx: &mut JitContext, name: &str, r1: u32, r2: u32) {
  219. ctx.builder
  220. .const_i32(global_pointers::get_reg_mmx_offset(r1) as i32);
  221. ctx.builder.load_aligned_i32(0);
  222. ctx.builder.const_i32(r2 as i32);
  223. ctx.builder.call_fn2(name);
  224. }
  225. fn mmx_read64_mm_mem(ctx: &mut JitContext, name: &str, modrm_byte: ModrmByte, r: u32) {
  226. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  227. ctx.builder.const_i32(r as i32);
  228. ctx.builder.call_fn2_i64_i32(name)
  229. }
  230. fn mmx_read64_mm_mm(ctx: &mut JitContext, name: &str, r1: u32, r2: u32) {
  231. ctx.builder
  232. .const_i32(global_pointers::get_reg_mmx_offset(r1) as i32);
  233. ctx.builder.load_aligned_i64(0);
  234. ctx.builder.const_i32(r2 as i32);
  235. ctx.builder.call_fn2_i64_i32(name);
  236. }
  237. fn push16_reg_jit(ctx: &mut JitContext, r: u32) {
  238. codegen::gen_get_reg16(ctx, r);
  239. let value_local = ctx.builder.set_new_local();
  240. codegen::gen_push16(ctx, &value_local);
  241. ctx.builder.free_local(value_local);
  242. }
  243. fn push32_reg_jit(ctx: &mut JitContext, r: u32) {
  244. let reg = ctx.reg(r);
  245. codegen::gen_push32(ctx, &reg);
  246. }
  247. fn push16_imm_jit(ctx: &mut JitContext, imm: u32) {
  248. ctx.builder.const_i32(imm as i32);
  249. let value_local = ctx.builder.set_new_local();
  250. codegen::gen_push16(ctx, &value_local);
  251. ctx.builder.free_local(value_local);
  252. }
  253. fn push32_imm_jit(ctx: &mut JitContext, imm: u32) {
  254. ctx.builder.const_i32(imm as i32);
  255. let value_local = ctx.builder.set_new_local();
  256. codegen::gen_push32(ctx, &value_local);
  257. ctx.builder.free_local(value_local);
  258. }
  259. fn push16_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  260. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  261. let value_local = ctx.builder.set_new_local();
  262. codegen::gen_push16(ctx, &value_local);
  263. ctx.builder.free_local(value_local);
  264. }
  265. fn push32_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  266. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  267. let value_local = ctx.builder.set_new_local();
  268. codegen::gen_push32(ctx, &value_local);
  269. ctx.builder.free_local(value_local);
  270. }
  271. fn pop16_reg_jit(ctx: &mut JitContext, reg: u32) {
  272. codegen::gen_pop16(ctx);
  273. codegen::gen_set_reg16_unmasked(ctx, reg);
  274. }
  275. fn pop32_reg_jit(ctx: &mut JitContext, reg: u32) {
  276. codegen::gen_pop32s(ctx);
  277. codegen::gen_set_reg32(ctx, reg);
  278. }
  279. fn group_arith_al_imm8(
  280. ctx: &mut JitContext,
  281. op: &dyn Fn(&mut JitContext, &WasmLocal, &LocalOrImmediate),
  282. imm8: u32,
  283. ) {
  284. op(
  285. ctx,
  286. &ctx.reg(regs::EAX),
  287. &LocalOrImmediate::Immediate(imm8 as i32),
  288. );
  289. codegen::gen_set_reg8_unmasked(ctx, regs::EAX);
  290. }
  291. fn group_arith_ax_imm16(ctx: &mut JitContext, op: &str, imm16: u32) {
  292. codegen::gen_get_reg16(ctx, regs::AX);
  293. ctx.builder.const_i32(imm16 as i32);
  294. ctx.builder.call_fn2_ret(op);
  295. codegen::gen_set_reg16(ctx, regs::AX);
  296. }
  297. fn group_arith_eax_imm32(
  298. ctx: &mut JitContext,
  299. op: &dyn Fn(&mut JitContext, &WasmLocal, &LocalOrImmediate),
  300. imm32: u32,
  301. ) {
  302. op(
  303. ctx,
  304. &ctx.reg(regs::EAX),
  305. &LocalOrImmediate::Immediate(imm32 as i32),
  306. );
  307. }
  308. macro_rules! define_instruction_read8(
  309. ($fn:expr, $name_mem:ident, $name_reg:ident) => (
  310. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  311. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
  312. let dest_operand = ctx.builder.set_new_local();
  313. let source_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r);
  314. $fn(ctx, &dest_operand, &LocalOrImmediate::WasmLocal(&source_operand));
  315. ctx.builder.free_local(dest_operand);
  316. codegen::gen_free_reg8_or_alias(ctx, r, source_operand);
  317. }
  318. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  319. let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r1);
  320. let source_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r2);
  321. $fn(ctx, &dest_operand, &LocalOrImmediate::WasmLocal(&source_operand));
  322. codegen::gen_free_reg8_or_alias(ctx, r1, dest_operand);
  323. codegen::gen_free_reg8_or_alias(ctx, r2, source_operand);
  324. }
  325. );
  326. ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
  327. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  328. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
  329. let dest_operand = ctx.builder.set_new_local();
  330. let imm = mask_imm!(imm, $imm);
  331. $fn(ctx, &dest_operand, &LocalOrImmediate::Immediate(imm as i32));
  332. ctx.builder.free_local(dest_operand);
  333. }
  334. pub fn $name_reg(ctx: &mut JitContext, r1: u32, imm: u32) {
  335. let imm = mask_imm!(imm, $imm);
  336. let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r1);
  337. $fn(ctx, &dest_operand, &LocalOrImmediate::Immediate(imm as i32));
  338. codegen::gen_free_reg8_or_alias(ctx, r1, dest_operand);
  339. }
  340. );
  341. );
  342. macro_rules! define_instruction_read16(
  343. ($fn:expr, $name_mem:ident, $name_reg:ident) => (
  344. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  345. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  346. let dest_operand = ctx.builder.set_new_local();
  347. $fn(
  348. ctx,
  349. &dest_operand,
  350. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  351. );
  352. ctx.builder.free_local(dest_operand);
  353. }
  354. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  355. $fn(
  356. ctx,
  357. &ctx.reg(r1),
  358. &LocalOrImmediate::WasmLocal(&ctx.reg(r2))
  359. );
  360. }
  361. );
  362. ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
  363. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  364. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  365. let dest_operand = ctx.builder.set_new_local();
  366. let imm = mask_imm!(imm, $imm);
  367. $fn(
  368. ctx,
  369. &dest_operand,
  370. &LocalOrImmediate::Immediate(imm as i32),
  371. );
  372. ctx.builder.free_local(dest_operand);
  373. }
  374. pub fn $name_reg(ctx: &mut JitContext, r: u32, imm: u32) {
  375. let imm = mask_imm!(imm, $imm);
  376. $fn(
  377. ctx,
  378. &ctx.reg(r),
  379. &LocalOrImmediate::Immediate(imm as i32),
  380. );
  381. }
  382. );
  383. );
  384. macro_rules! define_instruction_read32(
  385. ($fn:expr, $name_mem:ident, $name_reg:ident) => (
  386. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  387. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  388. let dest_operand = ctx.builder.set_new_local();
  389. $fn(
  390. ctx,
  391. &dest_operand,
  392. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  393. );
  394. ctx.builder.free_local(dest_operand);
  395. }
  396. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  397. $fn(
  398. ctx,
  399. &ctx.reg(r1),
  400. &LocalOrImmediate::WasmLocal(&ctx.reg(r2))
  401. );
  402. }
  403. );
  404. ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
  405. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  406. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  407. let dest_operand = ctx.builder.set_new_local();
  408. let imm = mask_imm!(imm, $imm);
  409. $fn(
  410. ctx,
  411. &dest_operand,
  412. &LocalOrImmediate::Immediate(imm as i32),
  413. );
  414. ctx.builder.free_local(dest_operand);
  415. }
  416. pub fn $name_reg(ctx: &mut JitContext, r: u32, imm: u32) {
  417. let imm = mask_imm!(imm, $imm);
  418. $fn(
  419. ctx,
  420. &ctx.reg(r),
  421. &LocalOrImmediate::Immediate(imm as i32),
  422. );
  423. }
  424. );
  425. );
  426. macro_rules! define_instruction_write_reg8(
  427. ($fn:expr, $name_mem:ident, $name_reg:ident) => (
  428. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  429. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
  430. let source_operand = ctx.builder.set_new_local();
  431. let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r);
  432. $fn(ctx, &dest_operand, &LocalOrImmediate::WasmLocal(&source_operand));
  433. codegen::gen_set_reg8_unmasked(ctx, r);
  434. ctx.builder.free_local(source_operand);
  435. codegen::gen_free_reg8_or_alias(ctx, r, dest_operand);
  436. }
  437. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  438. let source_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r1);
  439. let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r2);
  440. $fn(ctx, &dest_operand, &LocalOrImmediate::WasmLocal(&source_operand));
  441. codegen::gen_set_reg8_unmasked(ctx, r2);
  442. codegen::gen_free_reg8_or_alias(ctx, r1, source_operand);
  443. codegen::gen_free_reg8_or_alias(ctx, r2, dest_operand);
  444. }
  445. )
  446. );
  447. macro_rules! define_instruction_write_reg16(
  448. ($fn:expr, $name_mem:ident, $name_reg:ident) => (
  449. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  450. codegen::gen_get_reg16(ctx, r);
  451. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  452. ctx.builder.call_fn2_ret($fn);
  453. codegen::gen_set_reg16(ctx, r);
  454. }
  455. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  456. codegen::gen_get_reg16(ctx, r2);
  457. codegen::gen_get_reg16(ctx, r1);
  458. ctx.builder.call_fn2_ret($fn);
  459. codegen::gen_set_reg16(ctx, r2);
  460. }
  461. )
  462. );
  463. macro_rules! define_instruction_write_reg32(
  464. ($fn:expr, $name_mem:ident, $name_reg:ident) => (
  465. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  466. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  467. let source_operand = ctx.builder.set_new_local();
  468. $fn(
  469. ctx,
  470. &ctx.reg(r),
  471. &LocalOrImmediate::WasmLocal(&source_operand),
  472. );
  473. ctx.builder.free_local(source_operand);
  474. }
  475. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  476. $fn(
  477. ctx,
  478. &ctx.reg(r2),
  479. &LocalOrImmediate::WasmLocal(&ctx.reg(r1)),
  480. );
  481. }
  482. );
  483. );
  484. macro_rules! mask_imm(
  485. ($imm:expr, imm8_5bits) => { $imm & 31 };
  486. ($imm:expr, imm8) => { $imm };
  487. ($imm:expr, imm8s) => { $imm };
  488. ($imm:expr, imm8s_16bits) => { $imm & 0xFFFF };
  489. ($imm:expr, imm16) => { $imm };
  490. ($imm:expr, imm32) => { $imm };
  491. );
  492. macro_rules! define_instruction_read_write_mem8(
  493. ($fn:expr, $name_mem:ident, $name_reg:ident, reg) => (
  494. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  495. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  496. codegen::gen_safe_read_write(ctx, BitSize::BYTE, &addr, &|ref mut ctx| {
  497. let dest_operand = ctx.builder.set_new_local();
  498. let source_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r);
  499. $fn(ctx, &dest_operand, &LocalOrImmediate::WasmLocal(&source_operand));
  500. codegen::gen_free_reg8_or_alias(ctx, r, source_operand);
  501. ctx.builder.free_local(dest_operand);
  502. });
  503. });
  504. }
  505. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  506. let source_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r2);
  507. let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r1);
  508. $fn(ctx, &dest_operand, &LocalOrImmediate::WasmLocal(&source_operand));
  509. codegen::gen_set_reg8_unmasked(ctx, r1);
  510. codegen::gen_free_reg8_or_alias(ctx, r2, source_operand);
  511. codegen::gen_free_reg8_or_alias(ctx, r1, dest_operand);
  512. }
  513. );
  514. ($fn:expr, $name_mem:ident, $name_reg:ident, constant_one) => (
  515. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  516. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  517. codegen::gen_safe_read_write(ctx, BitSize::BYTE, &addr, &|ref mut ctx| {
  518. ctx.builder.const_i32(1);
  519. ctx.builder.call_fn2_ret($fn);
  520. });
  521. });
  522. }
  523. pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
  524. codegen::gen_get_reg8(ctx, r1);
  525. ctx.builder.const_i32(1);
  526. ctx.builder.call_fn2_ret($fn);
  527. codegen::gen_set_reg8(ctx, r1);
  528. }
  529. );
  530. ($fn:expr, $name_mem:ident, $name_reg:ident, cl) => (
  531. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  532. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  533. codegen::gen_safe_read_write(ctx, BitSize::BYTE, &addr, &|ref mut ctx| {
  534. codegen::gen_get_reg8(ctx, regs::CL);
  535. ctx.builder.const_i32(31);
  536. ctx.builder.and_i32();
  537. ctx.builder.call_fn2_ret($fn);
  538. });
  539. });
  540. }
  541. pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
  542. codegen::gen_get_reg8(ctx, r1);
  543. codegen::gen_get_reg8(ctx, regs::CL);
  544. ctx.builder.const_i32(31);
  545. ctx.builder.and_i32();
  546. ctx.builder.call_fn2_ret($fn);
  547. codegen::gen_set_reg8(ctx, r1);
  548. }
  549. );
  550. ($fn:expr, $name_mem:ident, $name_reg:ident, none) => (
  551. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  552. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  553. codegen::gen_safe_read_write(ctx, BitSize::BYTE, &addr, &|ref mut ctx| {
  554. ctx.builder.call_fn1_ret($fn);
  555. });
  556. });
  557. }
  558. pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
  559. codegen::gen_get_reg8(ctx, r1);
  560. ctx.builder.call_fn1_ret($fn);
  561. codegen::gen_set_reg8(ctx, r1);
  562. }
  563. );
  564. ($fn:expr, $name_mem:ident, $name_reg:ident, ximm8) => (
  565. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  566. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  567. codegen::gen_safe_read_write(ctx, BitSize::BYTE, &addr, &|ref mut ctx| {
  568. let dest_operand = ctx.builder.set_new_local();
  569. $fn(ctx, &dest_operand, &LocalOrImmediate::Immediate(imm as i32));
  570. ctx.builder.free_local(dest_operand);
  571. });
  572. });
  573. }
  574. pub fn $name_reg(ctx: &mut JitContext, r1: u32, imm: u32) {
  575. let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r1);
  576. $fn(ctx, &dest_operand, &LocalOrImmediate::Immediate(imm as i32));
  577. codegen::gen_set_reg8_unmasked(ctx, r1);
  578. codegen::gen_free_reg8_or_alias(ctx, r1, dest_operand);
  579. }
  580. );
  581. ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
  582. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  583. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  584. let imm = mask_imm!(imm, $imm) as i32;
  585. codegen::gen_safe_read_write(ctx, BitSize::BYTE, &addr, &|ref mut ctx| {
  586. ctx.builder.const_i32(imm as i32);
  587. ctx.builder.call_fn2_ret($fn);
  588. });
  589. });
  590. }
  591. pub fn $name_reg(ctx: &mut JitContext, r1: u32, imm: u32) {
  592. let imm = mask_imm!(imm, $imm);
  593. codegen::gen_get_reg8(ctx, r1);
  594. ctx.builder.const_i32(imm as i32);
  595. ctx.builder.call_fn2_ret($fn);
  596. codegen::gen_set_reg8(ctx, r1);
  597. }
  598. );
  599. );
  600. macro_rules! define_instruction_read_write_mem16(
  601. ($fn:expr, $name_mem:ident, $name_reg:ident, reg) => (
  602. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  603. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  604. codegen::gen_safe_read_write(ctx, BitSize::WORD, &addr, &|ref mut ctx| {
  605. codegen::gen_get_reg16(ctx, r);
  606. ctx.builder.call_fn2_ret($fn);
  607. });
  608. });
  609. }
  610. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  611. codegen::gen_get_reg16(ctx, r1);
  612. codegen::gen_get_reg16(ctx, r2);
  613. ctx.builder.call_fn2_ret($fn);
  614. codegen::gen_set_reg16(ctx, r1);
  615. }
  616. );
  617. ($fn:expr, $name_mem:ident, $name_reg:ident, constant_one) => (
  618. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  619. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  620. codegen::gen_safe_read_write(ctx, BitSize::WORD, &addr, &|ref mut ctx| {
  621. ctx.builder.const_i32(1);
  622. ctx.builder.call_fn2_ret($fn);
  623. });
  624. });
  625. }
  626. pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
  627. codegen::gen_get_reg16(ctx, r1);
  628. ctx.builder.const_i32(1);
  629. ctx.builder.call_fn2_ret($fn);
  630. codegen::gen_set_reg16(ctx, r1);
  631. }
  632. );
  633. ($fn:expr, $name_mem:ident, $name_reg:ident, cl) => (
  634. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  635. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  636. codegen::gen_safe_read_write(ctx, BitSize::WORD, &addr, &|ref mut ctx| {
  637. codegen::gen_get_reg8(ctx, regs::CL);
  638. ctx.builder.const_i32(31);
  639. ctx.builder.and_i32();
  640. ctx.builder.call_fn2_ret($fn);
  641. });
  642. });
  643. }
  644. pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
  645. codegen::gen_get_reg16(ctx, r1);
  646. codegen::gen_get_reg8(ctx, regs::CL);
  647. ctx.builder.const_i32(31);
  648. ctx.builder.and_i32();
  649. ctx.builder.call_fn2_ret($fn);
  650. codegen::gen_set_reg16(ctx, r1);
  651. }
  652. );
  653. ($fn:expr, $name_mem:ident, $name_reg:ident, reg, cl) => (
  654. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  655. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  656. codegen::gen_safe_read_write(ctx, BitSize::WORD, &addr, &|ref mut ctx| {
  657. codegen::gen_get_reg16(ctx, r);
  658. codegen::gen_get_reg8(ctx, regs::CL);
  659. ctx.builder.const_i32(31);
  660. ctx.builder.and_i32();
  661. ctx.builder.call_fn3_ret($fn);
  662. });
  663. });
  664. }
  665. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  666. codegen::gen_get_reg16(ctx, r1);
  667. codegen::gen_get_reg16(ctx, r2);
  668. codegen::gen_get_reg8(ctx, regs::CL);
  669. ctx.builder.const_i32(31);
  670. ctx.builder.and_i32();
  671. ctx.builder.call_fn3_ret($fn);
  672. codegen::gen_set_reg16(ctx, r1);
  673. }
  674. );
  675. ($fn:expr, $name_mem:ident, $name_reg:ident, reg, $imm:ident) => (
  676. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm: u32) {
  677. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  678. let imm = mask_imm!(imm, $imm);
  679. codegen::gen_safe_read_write(ctx, BitSize::WORD, &addr, &|ref mut ctx| {
  680. codegen::gen_get_reg16(ctx, r);
  681. ctx.builder.const_i32(imm as i32);
  682. ctx.builder.call_fn3_ret($fn);
  683. });
  684. });
  685. }
  686. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32, imm: u32) {
  687. let imm = mask_imm!(imm, $imm);
  688. codegen::gen_get_reg16(ctx, r1);
  689. codegen::gen_get_reg16(ctx, r2);
  690. ctx.builder.const_i32(imm as i32);
  691. ctx.builder.call_fn3_ret($fn);
  692. codegen::gen_set_reg16(ctx, r1);
  693. }
  694. );
  695. ($fn:expr, $name_mem:ident, $name_reg:ident, none) => (
  696. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  697. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  698. codegen::gen_safe_read_write(ctx, BitSize::WORD, &addr, &|ref mut ctx| {
  699. let mut dest_operand = ctx.builder.set_new_local();
  700. $fn(ctx, &mut dest_operand);
  701. ctx.builder.get_local(&dest_operand);
  702. ctx.builder.free_local(dest_operand);
  703. });
  704. });
  705. }
  706. pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
  707. $fn(ctx, &mut ctx.reg(r1));
  708. }
  709. );
  710. ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
  711. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  712. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  713. let imm = mask_imm!(imm, $imm) as i32;
  714. codegen::gen_safe_read_write(ctx, BitSize::WORD, &addr, &|ref mut ctx| {
  715. ctx.builder.const_i32(imm as i32);
  716. ctx.builder.call_fn2_ret($fn);
  717. });
  718. });
  719. }
  720. pub fn $name_reg(ctx: &mut JitContext, r1: u32, imm: u32) {
  721. let imm = mask_imm!(imm, $imm);
  722. codegen::gen_get_reg16(ctx, r1);
  723. ctx.builder.const_i32(imm as i32);
  724. ctx.builder.call_fn2_ret($fn);
  725. codegen::gen_set_reg16(ctx, r1);
  726. }
  727. );
  728. );
  729. macro_rules! define_instruction_read_write_mem32(
  730. ($fn:expr, $name_mem:ident, $name_reg:ident, reg) => (
  731. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  732. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  733. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &addr, &|ref mut ctx| {
  734. let dest_operand = ctx.builder.set_new_local();
  735. $fn(
  736. ctx,
  737. &dest_operand,
  738. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  739. );
  740. ctx.builder.get_local(&dest_operand);
  741. ctx.builder.free_local(dest_operand);
  742. });
  743. });
  744. }
  745. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  746. $fn(
  747. ctx,
  748. &ctx.reg(r1),
  749. &LocalOrImmediate::WasmLocal(&ctx.reg(r2)),
  750. );
  751. }
  752. );
  753. ($fn:expr, $name_mem:ident, $name_reg:ident, constant_one) => (
  754. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  755. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  756. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &addr, &|ref mut ctx| {
  757. let dest_operand = ctx.builder.set_new_local();
  758. $fn(ctx, &dest_operand, &LocalOrImmediate::Immediate(1));
  759. ctx.builder.get_local(&dest_operand);
  760. ctx.builder.free_local(dest_operand);
  761. });
  762. });
  763. }
  764. pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
  765. $fn(ctx, &ctx.reg(r1), &LocalOrImmediate::Immediate(1));
  766. }
  767. );
  768. ($fn:expr, $name_mem:ident, $name_reg:ident, cl) => (
  769. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  770. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  771. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &addr, &|ref mut ctx| {
  772. let dest_operand = ctx.builder.set_new_local();
  773. $fn(
  774. ctx,
  775. &dest_operand,
  776. &LocalOrImmediate::WasmLocal(&ctx.reg(regs::ECX)),
  777. );
  778. ctx.builder.get_local(&dest_operand);
  779. ctx.builder.free_local(dest_operand);
  780. });
  781. });
  782. }
  783. pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
  784. $fn(
  785. ctx,
  786. &ctx.reg(r1),
  787. &LocalOrImmediate::WasmLocal(&ctx.reg(regs::ECX)),
  788. );
  789. }
  790. );
  791. ($fn:expr, $name_mem:ident, $name_reg:ident, reg, cl) => (
  792. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  793. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  794. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &addr, &|ref mut ctx| {
  795. codegen::gen_get_reg32(ctx, r);
  796. codegen::gen_get_reg8(ctx, regs::CL);
  797. ctx.builder.const_i32(31);
  798. ctx.builder.and_i32();
  799. ctx.builder.call_fn3_ret($fn);
  800. });
  801. });
  802. }
  803. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  804. codegen::gen_get_reg32(ctx, r1);
  805. codegen::gen_get_reg32(ctx, r2);
  806. codegen::gen_get_reg8(ctx, regs::CL);
  807. ctx.builder.const_i32(31);
  808. ctx.builder.and_i32();
  809. ctx.builder.call_fn3_ret($fn);
  810. codegen::gen_set_reg32(ctx, r1);
  811. }
  812. );
  813. ($fn:expr, $name_mem:ident, $name_reg:ident, reg, $imm:ident) => (
  814. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm: u32) {
  815. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  816. let imm = mask_imm!(imm, $imm) as i32;
  817. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &addr, &|ref mut ctx| {
  818. codegen::gen_get_reg32(ctx, r);
  819. ctx.builder.const_i32(imm as i32);
  820. ctx.builder.call_fn3_ret($fn);
  821. });
  822. });
  823. }
  824. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32, imm: u32) {
  825. let imm = mask_imm!(imm, $imm);
  826. codegen::gen_get_reg32(ctx, r1);
  827. codegen::gen_get_reg32(ctx, r2);
  828. ctx.builder.const_i32(imm as i32);
  829. ctx.builder.call_fn3_ret($fn);
  830. codegen::gen_set_reg32(ctx, r1);
  831. }
  832. );
  833. ($fn:expr, $name_mem:ident, $name_reg:ident, none) => (
  834. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  835. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  836. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &addr, &|ref mut ctx| {
  837. let mut dest_operand = ctx.builder.set_new_local();
  838. $fn(ctx, &mut dest_operand);
  839. ctx.builder.get_local(&dest_operand);
  840. ctx.builder.free_local(dest_operand);
  841. });
  842. });
  843. }
  844. pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
  845. $fn(ctx, &mut ctx.reg(r1));
  846. }
  847. );
  848. ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
  849. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  850. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  851. let imm = mask_imm!(imm, $imm);
  852. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &addr, &|ref mut ctx| {
  853. let dest_operand = ctx.builder.set_new_local();
  854. $fn(
  855. ctx,
  856. &dest_operand,
  857. &LocalOrImmediate::Immediate(imm as i32),
  858. );
  859. ctx.builder.get_local(&dest_operand);
  860. ctx.builder.free_local(dest_operand);
  861. });
  862. });
  863. }
  864. pub fn $name_reg(ctx: &mut JitContext, r1: u32, imm: u32) {
  865. let imm = mask_imm!(imm, $imm);
  866. $fn(
  867. ctx,
  868. &ctx.reg(r1),
  869. &LocalOrImmediate::Immediate(imm as i32),
  870. );
  871. }
  872. );
  873. );
  874. fn gen_add8(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  875. ctx.current_instruction = Instruction::Add {
  876. opsize: OPSIZE_8,
  877. dest: local_to_instruction_operand(ctx, dest_operand),
  878. source: if source_operand.eq_local(dest_operand) {
  879. InstructionOperand::Other // aliasing
  880. }
  881. else {
  882. source_operand.to_instruction_operand(ctx)
  883. },
  884. is_inc: false,
  885. };
  886. ctx.builder.const_i32(global_pointers::last_op1 as i32);
  887. ctx.builder.get_local(dest_operand);
  888. ctx.builder.const_i32(0xFF);
  889. ctx.builder.and_i32();
  890. ctx.builder.store_aligned_i32(0);
  891. ctx.builder.const_i32(global_pointers::last_result as i32);
  892. ctx.builder.get_local(dest_operand);
  893. source_operand.gen_get(ctx.builder);
  894. ctx.builder.add_i32();
  895. ctx.builder.const_i32(0xFF);
  896. ctx.builder.and_i32();
  897. ctx.builder.store_aligned_i32(0);
  898. codegen::gen_set_last_op_size_and_flags_changed(ctx.builder, OPSIZE_8, FLAGS_ALL);
  899. ctx.builder
  900. .load_fixed_u8(global_pointers::last_result as u32);
  901. }
  902. fn gen_add32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  903. ctx.current_instruction = Instruction::Add {
  904. opsize: OPSIZE_32,
  905. dest: local_to_instruction_operand(ctx, dest_operand),
  906. source: if source_operand.eq_local(dest_operand) {
  907. InstructionOperand::Other // aliasing
  908. }
  909. else {
  910. source_operand.to_instruction_operand(ctx)
  911. },
  912. is_inc: false,
  913. };
  914. codegen::gen_set_last_op1(ctx.builder, &dest_operand);
  915. ctx.builder.get_local(&dest_operand);
  916. source_operand.gen_get(ctx.builder);
  917. ctx.builder.add_i32();
  918. ctx.builder.set_local(dest_operand);
  919. codegen::gen_set_last_result(ctx.builder, &dest_operand);
  920. codegen::gen_set_last_op_size_and_flags_changed(ctx.builder, OPSIZE_32, FLAGS_ALL);
  921. }
  922. fn gen_sub8(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  923. ctx.current_instruction = Instruction::Sub {
  924. opsize: OPSIZE_8,
  925. dest: local_to_instruction_operand(ctx, dest_operand),
  926. source: if source_operand.eq_local(dest_operand) {
  927. InstructionOperand::Other // aliasing
  928. }
  929. else {
  930. source_operand.to_instruction_operand(ctx)
  931. },
  932. is_dec: false,
  933. };
  934. ctx.builder.const_i32(global_pointers::last_op1 as i32);
  935. ctx.builder.get_local(dest_operand);
  936. ctx.builder.const_i32(0xFF);
  937. ctx.builder.and_i32();
  938. ctx.builder.store_aligned_i32(0);
  939. ctx.builder.const_i32(global_pointers::last_result as i32);
  940. ctx.builder.get_local(dest_operand);
  941. source_operand.gen_get(ctx.builder);
  942. ctx.builder.sub_i32();
  943. ctx.builder.const_i32(0xFF);
  944. ctx.builder.and_i32();
  945. ctx.builder.store_aligned_i32(0);
  946. codegen::gen_set_last_op_size_and_flags_changed(ctx.builder, OPSIZE_8, FLAGS_ALL | FLAG_SUB);
  947. ctx.builder
  948. .load_fixed_u8(global_pointers::last_result as u32);
  949. }
  950. fn gen_sub32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  951. ctx.current_instruction = Instruction::Sub {
  952. opsize: OPSIZE_32,
  953. dest: local_to_instruction_operand(ctx, dest_operand),
  954. source: if source_operand.eq_local(dest_operand) {
  955. InstructionOperand::Other // aliasing
  956. }
  957. else {
  958. source_operand.to_instruction_operand(ctx)
  959. },
  960. is_dec: false,
  961. };
  962. codegen::gen_set_last_op1(ctx.builder, &dest_operand);
  963. ctx.builder.get_local(&dest_operand);
  964. source_operand.gen_get(ctx.builder);
  965. ctx.builder.sub_i32();
  966. ctx.builder.set_local(dest_operand);
  967. codegen::gen_set_last_result(ctx.builder, &dest_operand);
  968. codegen::gen_set_last_op_size_and_flags_changed(ctx.builder, OPSIZE_32, FLAGS_ALL | FLAG_SUB);
  969. }
  970. fn gen_cmp(
  971. ctx: &mut JitContext,
  972. dest_operand: &WasmLocal,
  973. source_operand: &LocalOrImmediate,
  974. size: i32,
  975. ) {
  976. ctx.current_instruction = Instruction::Cmp {
  977. dest: local_to_instruction_operand(ctx, dest_operand),
  978. source: source_operand.to_instruction_operand(ctx),
  979. opsize: size,
  980. };
  981. ctx.builder.const_i32(global_pointers::last_result as i32);
  982. if source_operand.is_zero() {
  983. ctx.builder.get_local(&dest_operand);
  984. }
  985. else {
  986. ctx.builder.get_local(&dest_operand);
  987. source_operand.gen_get(ctx.builder);
  988. ctx.builder.sub_i32();
  989. }
  990. if size == OPSIZE_8 || size == OPSIZE_16 {
  991. ctx.builder
  992. .const_i32(if size == OPSIZE_8 { 0xFF } else { 0xFFFF });
  993. ctx.builder.and_i32();
  994. }
  995. ctx.builder.store_aligned_i32(0);
  996. ctx.builder.const_i32(global_pointers::last_op1 as i32);
  997. ctx.builder.get_local(&dest_operand);
  998. if size == OPSIZE_8 || size == OPSIZE_16 {
  999. ctx.builder
  1000. .const_i32(if size == OPSIZE_8 { 0xFF } else { 0xFFFF });
  1001. ctx.builder.and_i32();
  1002. }
  1003. ctx.builder.store_aligned_i32(0);
  1004. codegen::gen_set_last_op_size_and_flags_changed(ctx.builder, size, FLAGS_ALL | FLAG_SUB);
  1005. }
  1006. fn gen_cmp8(ctx: &mut JitContext, dest: &WasmLocal, source: &LocalOrImmediate) {
  1007. gen_cmp(ctx, dest, source, OPSIZE_8)
  1008. }
  1009. fn gen_cmp16(ctx: &mut JitContext, dest: &WasmLocal, source: &LocalOrImmediate) {
  1010. gen_cmp(ctx, dest, source, OPSIZE_16)
  1011. }
  1012. fn gen_cmp32(ctx: &mut JitContext, dest: &WasmLocal, source: &LocalOrImmediate) {
  1013. gen_cmp(ctx, dest, source, OPSIZE_32)
  1014. }
  1015. fn gen_adc8(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1016. ctx.builder.get_local(dest_operand);
  1017. ctx.builder.const_i32(0xFF);
  1018. ctx.builder.and_i32();
  1019. source_operand.gen_get_mask255(ctx.builder);
  1020. ctx.builder.call_fn2_ret("adc8");
  1021. ctx.builder.const_i32(0xFF);
  1022. ctx.builder.and_i32();
  1023. ctx.current_instruction = Instruction::AdcSbb {
  1024. opsize: OPSIZE_8,
  1025. dest: local_to_instruction_operand(ctx, dest_operand),
  1026. source: if source_operand.eq_local(dest_operand) {
  1027. InstructionOperand::Other // aliasing
  1028. }
  1029. else {
  1030. source_operand.to_instruction_operand(ctx)
  1031. },
  1032. };
  1033. }
  1034. fn gen_adc32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1035. ctx.builder.get_local(&dest_operand);
  1036. source_operand.gen_get(ctx.builder);
  1037. ctx.builder.add_i32();
  1038. codegen::gen_getcf(ctx, ConditionNegate::False);
  1039. ctx.builder.add_i32();
  1040. let res = ctx.builder.set_new_local();
  1041. codegen::gen_set_last_result(ctx.builder, &res);
  1042. codegen::gen_set_last_op_size_and_flags_changed(
  1043. ctx.builder,
  1044. OPSIZE_32,
  1045. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
  1046. );
  1047. ctx.builder.const_i32(global_pointers::flags as i32);
  1048. codegen::gen_get_flags(ctx.builder);
  1049. ctx.builder
  1050. .const_i32(!FLAG_CARRY & !FLAG_ADJUST & !FLAG_OVERFLOW);
  1051. ctx.builder.and_i32();
  1052. // cf: (dest_operand ^ ((dest_operand ^ source_operand) & (source_operand ^ res))) >> op_size & FLAG_CARRY
  1053. ctx.builder.get_local(&dest_operand);
  1054. ctx.builder.get_local(&dest_operand);
  1055. source_operand.gen_get(ctx.builder);
  1056. ctx.builder.xor_i32();
  1057. source_operand.gen_get(ctx.builder);
  1058. ctx.builder.get_local(&res);
  1059. ctx.builder.xor_i32();
  1060. ctx.builder.and_i32();
  1061. ctx.builder.xor_i32();
  1062. ctx.builder.const_i32(31);
  1063. ctx.builder.shr_u_i32();
  1064. ctx.builder.const_i32(FLAG_CARRY);
  1065. ctx.builder.and_i32();
  1066. ctx.builder.or_i32();
  1067. // af: (dest_operand ^ source_operand ^ res) & FLAG_ADJUST
  1068. ctx.builder.get_local(&dest_operand);
  1069. source_operand.gen_get(ctx.builder);
  1070. ctx.builder.get_local(&res);
  1071. ctx.builder.xor_i32();
  1072. ctx.builder.xor_i32();
  1073. ctx.builder.const_i32(FLAG_ADJUST);
  1074. ctx.builder.and_i32();
  1075. ctx.builder.or_i32();
  1076. // of: ((source_operand ^ res) & (dest_operand ^ res)) >> op_size << 11 & FLAG_OVERFLOW
  1077. source_operand.gen_get(ctx.builder);
  1078. ctx.builder.get_local(&res);
  1079. ctx.builder.xor_i32();
  1080. ctx.builder.get_local(&dest_operand);
  1081. ctx.builder.get_local(&res);
  1082. ctx.builder.xor_i32();
  1083. ctx.builder.and_i32();
  1084. ctx.builder.const_i32(31 - 11);
  1085. ctx.builder.shr_u_i32();
  1086. ctx.builder.const_i32(FLAG_OVERFLOW);
  1087. ctx.builder.and_i32();
  1088. ctx.builder.or_i32();
  1089. ctx.builder.store_aligned_i32(0);
  1090. ctx.builder.get_local(&res);
  1091. ctx.builder.set_local(dest_operand);
  1092. ctx.builder.free_local(res);
  1093. ctx.current_instruction = Instruction::AdcSbb {
  1094. opsize: OPSIZE_32,
  1095. dest: local_to_instruction_operand(ctx, dest_operand),
  1096. source: if source_operand.eq_local(dest_operand) {
  1097. InstructionOperand::Other // aliasing
  1098. }
  1099. else {
  1100. source_operand.to_instruction_operand(ctx)
  1101. },
  1102. };
  1103. }
  1104. fn gen_sbb8(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1105. ctx.builder.get_local(dest_operand);
  1106. ctx.builder.const_i32(0xFF);
  1107. ctx.builder.and_i32();
  1108. source_operand.gen_get_mask255(ctx.builder);
  1109. ctx.builder.call_fn2_ret("sbb8");
  1110. ctx.builder.const_i32(0xFF);
  1111. ctx.builder.and_i32();
  1112. ctx.current_instruction = Instruction::AdcSbb {
  1113. opsize: OPSIZE_8,
  1114. dest: local_to_instruction_operand(ctx, dest_operand),
  1115. source: if source_operand.eq_local(dest_operand) {
  1116. InstructionOperand::Other // aliasing
  1117. }
  1118. else {
  1119. source_operand.to_instruction_operand(ctx)
  1120. },
  1121. };
  1122. }
  1123. fn gen_sbb32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1124. ctx.builder.get_local(&dest_operand);
  1125. source_operand.gen_get(ctx.builder);
  1126. ctx.builder.sub_i32();
  1127. codegen::gen_getcf(ctx, ConditionNegate::False);
  1128. ctx.builder.sub_i32();
  1129. let res = ctx.builder.set_new_local();
  1130. codegen::gen_set_last_result(ctx.builder, &res);
  1131. codegen::gen_set_last_op_size_and_flags_changed(
  1132. ctx.builder,
  1133. OPSIZE_32,
  1134. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
  1135. );
  1136. ctx.builder.const_i32(global_pointers::flags as i32);
  1137. codegen::gen_get_flags(ctx.builder);
  1138. ctx.builder
  1139. .const_i32(!FLAG_CARRY & !FLAG_ADJUST & !FLAG_OVERFLOW);
  1140. ctx.builder.and_i32();
  1141. // cf: (res ^ ((res ^ source_operand) & (source_operand ^ dest_operand))) >> op_size & FLAG_CARRY
  1142. ctx.builder.get_local(&res);
  1143. ctx.builder.get_local(&res);
  1144. source_operand.gen_get(ctx.builder);
  1145. ctx.builder.xor_i32();
  1146. source_operand.gen_get(ctx.builder);
  1147. ctx.builder.get_local(&dest_operand);
  1148. ctx.builder.xor_i32();
  1149. ctx.builder.and_i32();
  1150. ctx.builder.xor_i32();
  1151. ctx.builder.const_i32(31);
  1152. ctx.builder.shr_u_i32();
  1153. ctx.builder.const_i32(FLAG_CARRY);
  1154. ctx.builder.and_i32();
  1155. ctx.builder.or_i32();
  1156. // af: (dest_operand ^ source_operand ^ res) & FLAG_ADJUST
  1157. ctx.builder.get_local(&dest_operand);
  1158. source_operand.gen_get(ctx.builder);
  1159. ctx.builder.get_local(&res);
  1160. ctx.builder.xor_i32();
  1161. ctx.builder.xor_i32();
  1162. ctx.builder.const_i32(FLAG_ADJUST);
  1163. ctx.builder.and_i32();
  1164. ctx.builder.or_i32();
  1165. // of: ((source_operand ^ dest_operand) & (res ^ dest_operand)) >> op_size << 11 & FLAG_OVERFLOW
  1166. source_operand.gen_get(ctx.builder);
  1167. ctx.builder.get_local(&dest_operand);
  1168. ctx.builder.xor_i32();
  1169. ctx.builder.get_local(&res);
  1170. ctx.builder.get_local(&dest_operand);
  1171. ctx.builder.xor_i32();
  1172. ctx.builder.and_i32();
  1173. ctx.builder.const_i32(31 - 11);
  1174. ctx.builder.shr_u_i32();
  1175. ctx.builder.const_i32(FLAG_OVERFLOW);
  1176. ctx.builder.and_i32();
  1177. ctx.builder.or_i32();
  1178. ctx.builder.store_aligned_i32(0);
  1179. ctx.builder.get_local(&res);
  1180. ctx.builder.set_local(dest_operand);
  1181. ctx.builder.free_local(res);
  1182. ctx.current_instruction = Instruction::AdcSbb {
  1183. opsize: OPSIZE_32,
  1184. dest: local_to_instruction_operand(ctx, dest_operand),
  1185. source: if source_operand.eq_local(dest_operand) {
  1186. InstructionOperand::Other // aliasing
  1187. }
  1188. else {
  1189. source_operand.to_instruction_operand(ctx)
  1190. },
  1191. };
  1192. }
  1193. fn gen_and8(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1194. ctx.current_instruction = Instruction::Bitwise {
  1195. opsize: OPSIZE_8,
  1196. dest: local_to_instruction_operand(ctx, dest_operand),
  1197. };
  1198. ctx.builder.const_i32(global_pointers::last_result as i32);
  1199. ctx.builder.get_local(dest_operand);
  1200. source_operand.gen_get(ctx.builder);
  1201. ctx.builder.and_i32();
  1202. ctx.builder.store_aligned_i32(0);
  1203. codegen::gen_set_last_op_size_and_flags_changed(
  1204. ctx.builder,
  1205. OPSIZE_8,
  1206. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
  1207. );
  1208. codegen::gen_clear_flags_bits(ctx.builder, FLAG_CARRY | FLAG_OVERFLOW | FLAG_ADJUST);
  1209. ctx.builder
  1210. .load_fixed_u8(global_pointers::last_result as u32);
  1211. }
  1212. fn gen_and32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1213. ctx.current_instruction = Instruction::Bitwise {
  1214. opsize: OPSIZE_32,
  1215. dest: local_to_instruction_operand(ctx, dest_operand),
  1216. };
  1217. ctx.builder.get_local(&dest_operand);
  1218. source_operand.gen_get(ctx.builder);
  1219. ctx.builder.and_i32();
  1220. ctx.builder.set_local(dest_operand);
  1221. codegen::gen_set_last_result(ctx.builder, &dest_operand);
  1222. codegen::gen_set_last_op_size_and_flags_changed(
  1223. ctx.builder,
  1224. OPSIZE_32,
  1225. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
  1226. );
  1227. codegen::gen_clear_flags_bits(ctx.builder, FLAG_CARRY | FLAG_OVERFLOW | FLAG_ADJUST);
  1228. }
  1229. fn gen_test(
  1230. ctx: &mut JitContext,
  1231. dest_operand: &WasmLocal,
  1232. source_operand: &LocalOrImmediate,
  1233. size: i32,
  1234. ) {
  1235. let is_self_test = source_operand.eq_local(dest_operand);
  1236. ctx.current_instruction = Instruction::Bitwise {
  1237. opsize: size,
  1238. dest: if is_self_test {
  1239. local_to_instruction_operand(ctx, dest_operand)
  1240. }
  1241. else {
  1242. InstructionOperandDest::Other
  1243. },
  1244. };
  1245. ctx.builder.const_i32(global_pointers::last_result as i32);
  1246. if is_self_test {
  1247. ctx.builder.get_local(&dest_operand);
  1248. }
  1249. else {
  1250. ctx.builder.get_local(&dest_operand);
  1251. source_operand.gen_get(ctx.builder);
  1252. ctx.builder.and_i32();
  1253. }
  1254. ctx.builder.store_aligned_i32(0);
  1255. codegen::gen_set_last_op_size_and_flags_changed(
  1256. ctx.builder,
  1257. size,
  1258. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
  1259. );
  1260. codegen::gen_clear_flags_bits(ctx.builder, FLAG_CARRY | FLAG_OVERFLOW | FLAG_ADJUST);
  1261. }
  1262. fn gen_test8(ctx: &mut JitContext, dest: &WasmLocal, source: &LocalOrImmediate) {
  1263. gen_test(ctx, dest, source, OPSIZE_8)
  1264. }
  1265. fn gen_test16(ctx: &mut JitContext, dest: &WasmLocal, source: &LocalOrImmediate) {
  1266. gen_test(ctx, dest, source, OPSIZE_16)
  1267. }
  1268. fn gen_test32(ctx: &mut JitContext, dest: &WasmLocal, source: &LocalOrImmediate) {
  1269. gen_test(ctx, dest, source, OPSIZE_32)
  1270. }
  1271. fn gen_or8(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1272. ctx.current_instruction = Instruction::Bitwise {
  1273. opsize: OPSIZE_8,
  1274. dest: local_to_instruction_operand(ctx, dest_operand),
  1275. };
  1276. ctx.builder.const_i32(global_pointers::last_result as i32);
  1277. ctx.builder.get_local(dest_operand);
  1278. source_operand.gen_get(ctx.builder);
  1279. ctx.builder.or_i32();
  1280. ctx.builder.store_aligned_i32(0);
  1281. codegen::gen_set_last_op_size_and_flags_changed(
  1282. ctx.builder,
  1283. OPSIZE_8,
  1284. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
  1285. );
  1286. codegen::gen_clear_flags_bits(ctx.builder, FLAG_CARRY | FLAG_OVERFLOW | FLAG_ADJUST);
  1287. ctx.builder
  1288. .load_fixed_u8(global_pointers::last_result as u32);
  1289. }
  1290. fn gen_or32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1291. ctx.current_instruction = Instruction::Bitwise {
  1292. opsize: OPSIZE_32,
  1293. dest: local_to_instruction_operand(ctx, dest_operand),
  1294. };
  1295. ctx.builder.get_local(&dest_operand);
  1296. source_operand.gen_get(ctx.builder);
  1297. ctx.builder.or_i32();
  1298. ctx.builder.set_local(dest_operand);
  1299. codegen::gen_set_last_result(ctx.builder, &dest_operand);
  1300. codegen::gen_set_last_op_size_and_flags_changed(
  1301. ctx.builder,
  1302. OPSIZE_32,
  1303. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
  1304. );
  1305. codegen::gen_clear_flags_bits(ctx.builder, FLAG_CARRY | FLAG_OVERFLOW | FLAG_ADJUST);
  1306. }
  1307. fn gen_xor8(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1308. ctx.current_instruction = Instruction::Bitwise {
  1309. opsize: OPSIZE_8,
  1310. dest: local_to_instruction_operand(ctx, dest_operand),
  1311. };
  1312. ctx.builder.const_i32(global_pointers::last_result as i32);
  1313. ctx.builder.get_local(dest_operand);
  1314. source_operand.gen_get(ctx.builder);
  1315. ctx.builder.xor_i32();
  1316. ctx.builder.store_aligned_i32(0);
  1317. codegen::gen_set_last_op_size_and_flags_changed(
  1318. ctx.builder,
  1319. OPSIZE_8,
  1320. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
  1321. );
  1322. codegen::gen_clear_flags_bits(ctx.builder, FLAG_CARRY | FLAG_OVERFLOW | FLAG_ADJUST);
  1323. ctx.builder
  1324. .load_fixed_u8(global_pointers::last_result as u32);
  1325. }
  1326. fn gen_xor32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1327. ctx.current_instruction = Instruction::Bitwise {
  1328. opsize: OPSIZE_32,
  1329. dest: local_to_instruction_operand(ctx, dest_operand),
  1330. };
  1331. if source_operand.eq_local(dest_operand) {
  1332. ctx.builder.const_i32(0);
  1333. ctx.builder.set_local(dest_operand);
  1334. // TODO:
  1335. // - Set last_result to zero rather than reading from local
  1336. // - Skip setting opsize (not relevant for SF, ZF, and PF on zero)
  1337. }
  1338. else {
  1339. ctx.builder.get_local(&dest_operand);
  1340. source_operand.gen_get(ctx.builder);
  1341. ctx.builder.xor_i32();
  1342. ctx.builder.set_local(dest_operand);
  1343. }
  1344. codegen::gen_set_last_result(ctx.builder, &dest_operand);
  1345. codegen::gen_set_last_op_size_and_flags_changed(
  1346. ctx.builder,
  1347. OPSIZE_32,
  1348. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
  1349. );
  1350. codegen::gen_clear_flags_bits(ctx.builder, FLAG_CARRY | FLAG_OVERFLOW | FLAG_ADJUST);
  1351. }
  1352. fn gen_rol32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1353. let builder = &mut ctx.builder;
  1354. builder.get_local(dest_operand);
  1355. match source_operand {
  1356. LocalOrImmediate::WasmLocal(l) => {
  1357. builder.get_local(l);
  1358. builder.const_i32(31);
  1359. builder.and_i32();
  1360. },
  1361. LocalOrImmediate::Immediate(i) => {
  1362. builder.const_i32(*i & 31);
  1363. },
  1364. }
  1365. builder.const_i32(31);
  1366. builder.and_i32();
  1367. builder.call_fn2_ret("rol32");
  1368. builder.set_local(dest_operand);
  1369. }
  1370. fn gen_ror32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1371. let builder = &mut ctx.builder;
  1372. builder.get_local(dest_operand);
  1373. match source_operand {
  1374. LocalOrImmediate::WasmLocal(l) => {
  1375. builder.get_local(l);
  1376. builder.const_i32(31);
  1377. builder.and_i32();
  1378. },
  1379. LocalOrImmediate::Immediate(i) => {
  1380. builder.const_i32(*i & 31);
  1381. },
  1382. }
  1383. builder.const_i32(31);
  1384. builder.and_i32();
  1385. builder.call_fn2_ret("ror32");
  1386. builder.set_local(dest_operand);
  1387. }
  1388. fn gen_rcl32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1389. let builder = &mut ctx.builder;
  1390. builder.get_local(dest_operand);
  1391. match source_operand {
  1392. LocalOrImmediate::WasmLocal(l) => {
  1393. builder.get_local(l);
  1394. builder.const_i32(31);
  1395. builder.and_i32();
  1396. },
  1397. LocalOrImmediate::Immediate(i) => {
  1398. builder.const_i32(*i & 31);
  1399. },
  1400. }
  1401. builder.const_i32(31);
  1402. builder.and_i32();
  1403. builder.call_fn2_ret("rcl32");
  1404. builder.set_local(dest_operand);
  1405. }
  1406. fn gen_rcr32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1407. let builder = &mut ctx.builder;
  1408. builder.get_local(dest_operand);
  1409. match source_operand {
  1410. LocalOrImmediate::WasmLocal(l) => {
  1411. builder.get_local(l);
  1412. builder.const_i32(31);
  1413. builder.and_i32();
  1414. },
  1415. LocalOrImmediate::Immediate(i) => {
  1416. builder.const_i32(*i & 31);
  1417. },
  1418. }
  1419. builder.const_i32(31);
  1420. builder.and_i32();
  1421. builder.call_fn2_ret("rcr32");
  1422. builder.set_local(dest_operand);
  1423. }
  1424. enum ShiftCount {
  1425. Local(WasmLocal),
  1426. Immediate(i32),
  1427. }
  1428. impl ShiftCount {
  1429. pub fn gen_get(builder: &mut WasmBuilder, count: &ShiftCount) {
  1430. match &count {
  1431. ShiftCount::Local(l) => builder.get_local(l),
  1432. ShiftCount::Immediate(i) => builder.const_i32(*i),
  1433. }
  1434. }
  1435. pub fn gen_get_thirtytwo_minus(builder: &mut WasmBuilder, count: &ShiftCount) {
  1436. match &count {
  1437. ShiftCount::Local(l) => {
  1438. builder.const_i32(32);
  1439. builder.get_local(l);
  1440. builder.sub_i32();
  1441. },
  1442. ShiftCount::Immediate(i) => builder.const_i32(32 - *i),
  1443. }
  1444. }
  1445. pub fn gen_get_minus_one(builder: &mut WasmBuilder, count: &ShiftCount) {
  1446. match &count {
  1447. ShiftCount::Local(l) => {
  1448. builder.get_local(l);
  1449. builder.const_i32(1);
  1450. builder.sub_i32()
  1451. },
  1452. ShiftCount::Immediate(i) => builder.const_i32(*i - 1),
  1453. }
  1454. }
  1455. }
  1456. fn gen_shl32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1457. if let &LocalOrImmediate::Immediate(1..=31) = source_operand {
  1458. ctx.current_instruction = Instruction::NonZeroShift {
  1459. dest: local_to_instruction_operand(ctx, dest_operand),
  1460. opsize: OPSIZE_32,
  1461. };
  1462. }
  1463. let builder = &mut ctx.builder;
  1464. let count = match source_operand {
  1465. LocalOrImmediate::WasmLocal(l) => {
  1466. let exit = builder.block_void();
  1467. builder.get_local(l);
  1468. builder.const_i32(31); // Note: mask can probably be avoided since wasm has the same semantics on shl_i32
  1469. builder.and_i32();
  1470. let count = builder.tee_new_local();
  1471. builder.eqz_i32();
  1472. builder.br_if(exit);
  1473. ShiftCount::Local(count)
  1474. },
  1475. LocalOrImmediate::Immediate(i) => {
  1476. if *i & 31 == 0 {
  1477. return;
  1478. }
  1479. ShiftCount::Immediate(*i & 31)
  1480. },
  1481. };
  1482. builder.get_local(&dest_operand);
  1483. ShiftCount::gen_get_thirtytwo_minus(builder, &count);
  1484. builder.shr_u_i32();
  1485. builder.const_i32(1);
  1486. builder.and_i32();
  1487. let b = builder.set_new_local();
  1488. builder.get_local(dest_operand);
  1489. ShiftCount::gen_get(builder, &count);
  1490. builder.shl_i32();
  1491. builder.set_local(dest_operand);
  1492. codegen::gen_set_last_result(builder, dest_operand);
  1493. codegen::gen_set_last_op_size_and_flags_changed(
  1494. builder,
  1495. OPSIZE_32,
  1496. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW,
  1497. );
  1498. builder.const_i32(global_pointers::flags as i32);
  1499. codegen::gen_get_flags(builder);
  1500. builder.const_i32(!(FLAG_CARRY | FLAG_OVERFLOW));
  1501. builder.and_i32();
  1502. builder.get_local(&b);
  1503. builder.or_i32();
  1504. {
  1505. builder.get_local(&b);
  1506. builder.get_local(&dest_operand);
  1507. builder.const_i32(31);
  1508. builder.shr_u_i32();
  1509. builder.xor_i32();
  1510. builder.const_i32(11);
  1511. builder.shl_i32();
  1512. builder.const_i32(FLAG_OVERFLOW);
  1513. builder.and_i32();
  1514. builder.or_i32();
  1515. }
  1516. builder.store_aligned_i32(0);
  1517. builder.free_local(b);
  1518. if let ShiftCount::Local(l) = count {
  1519. builder.block_end();
  1520. builder.free_local(l);
  1521. }
  1522. }
  1523. fn gen_shr32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1524. if let &LocalOrImmediate::Immediate(1..=31) = source_operand {
  1525. ctx.current_instruction = Instruction::NonZeroShift {
  1526. dest: local_to_instruction_operand(ctx, dest_operand),
  1527. opsize: OPSIZE_32,
  1528. };
  1529. }
  1530. let builder = &mut ctx.builder;
  1531. let count = match source_operand {
  1532. LocalOrImmediate::WasmLocal(l) => {
  1533. let exit = builder.block_void();
  1534. builder.get_local(l);
  1535. builder.const_i32(31); // Note: mask can probably be avoided since wasm has the same semantics on shl_i32
  1536. builder.and_i32();
  1537. let count = builder.tee_new_local();
  1538. builder.eqz_i32();
  1539. builder.br_if(exit);
  1540. ShiftCount::Local(count)
  1541. },
  1542. LocalOrImmediate::Immediate(i) => {
  1543. if *i & 31 == 0 {
  1544. return;
  1545. }
  1546. ShiftCount::Immediate(*i & 31)
  1547. },
  1548. };
  1549. builder.const_i32(global_pointers::flags as i32);
  1550. codegen::gen_get_flags(builder);
  1551. builder.const_i32(!(FLAG_CARRY | FLAG_OVERFLOW));
  1552. builder.and_i32();
  1553. {
  1554. builder.get_local(dest_operand);
  1555. ShiftCount::gen_get_minus_one(builder, &count);
  1556. builder.shr_u_i32();
  1557. builder.const_i32(1);
  1558. builder.and_i32();
  1559. builder.or_i32()
  1560. }
  1561. {
  1562. builder.get_local(dest_operand);
  1563. builder.const_i32(20);
  1564. builder.shr_u_i32();
  1565. builder.const_i32(FLAG_OVERFLOW);
  1566. builder.and_i32();
  1567. builder.or_i32()
  1568. }
  1569. builder.store_aligned_i32(0);
  1570. builder.get_local(dest_operand);
  1571. ShiftCount::gen_get(builder, &count);
  1572. builder.shr_u_i32();
  1573. builder.set_local(dest_operand);
  1574. codegen::gen_set_last_result(builder, dest_operand);
  1575. codegen::gen_set_last_op_size_and_flags_changed(
  1576. builder,
  1577. OPSIZE_32,
  1578. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW,
  1579. );
  1580. if let ShiftCount::Local(l) = count {
  1581. builder.block_end();
  1582. builder.free_local(l);
  1583. }
  1584. }
  1585. fn gen_sar32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1586. if let &LocalOrImmediate::Immediate(1..=31) = source_operand {
  1587. ctx.current_instruction = Instruction::NonZeroShift {
  1588. dest: local_to_instruction_operand(ctx, dest_operand),
  1589. opsize: OPSIZE_32,
  1590. };
  1591. }
  1592. let builder = &mut ctx.builder;
  1593. let count = match source_operand {
  1594. LocalOrImmediate::WasmLocal(l) => {
  1595. let exit = builder.block_void();
  1596. builder.get_local(l);
  1597. builder.const_i32(31); // Note: mask can probably be avoided since wasm has the same semantics on shl_i32
  1598. builder.and_i32();
  1599. let count = builder.tee_new_local();
  1600. builder.eqz_i32();
  1601. builder.br_if(exit);
  1602. ShiftCount::Local(count)
  1603. },
  1604. LocalOrImmediate::Immediate(i) => {
  1605. if *i & 31 == 0 {
  1606. return;
  1607. }
  1608. ShiftCount::Immediate(*i & 31)
  1609. },
  1610. };
  1611. builder.const_i32(global_pointers::flags as i32);
  1612. codegen::gen_get_flags(builder);
  1613. builder.const_i32(!(FLAG_CARRY | FLAG_OVERFLOW));
  1614. builder.and_i32();
  1615. {
  1616. builder.get_local(dest_operand);
  1617. ShiftCount::gen_get_minus_one(builder, &count);
  1618. builder.shr_u_i32();
  1619. builder.const_i32(1);
  1620. builder.and_i32();
  1621. builder.or_i32()
  1622. }
  1623. builder.store_aligned_i32(0);
  1624. builder.get_local(dest_operand);
  1625. ShiftCount::gen_get(builder, &count);
  1626. builder.shr_s_i32();
  1627. builder.set_local(dest_operand);
  1628. codegen::gen_set_last_result(builder, dest_operand);
  1629. codegen::gen_set_last_op_size_and_flags_changed(
  1630. builder,
  1631. OPSIZE_32,
  1632. FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW,
  1633. );
  1634. if let ShiftCount::Local(l) = count {
  1635. builder.block_end();
  1636. builder.free_local(l);
  1637. }
  1638. }
  1639. fn gen_xadd32(ctx: &mut JitContext, dest_operand: &WasmLocal, r: u32) {
  1640. ctx.builder.get_local(&ctx.register_locals[r as usize]);
  1641. let tmp = ctx.builder.set_new_local();
  1642. ctx.builder.get_local(&dest_operand);
  1643. codegen::gen_set_reg32(ctx, r);
  1644. gen_add32(ctx, &dest_operand, &LocalOrImmediate::WasmLocal(&tmp));
  1645. ctx.builder.free_local(tmp);
  1646. }
  1647. fn gen_cmpxchg32(ctx: &mut JitContext, r: u32) {
  1648. let source = ctx.builder.set_new_local();
  1649. ctx.builder.const_i32(global_pointers::last_result as i32);
  1650. codegen::gen_get_reg32(ctx, regs::EAX);
  1651. ctx.builder.get_local(&source);
  1652. ctx.builder.sub_i32();
  1653. ctx.builder.store_aligned_i32(0);
  1654. ctx.builder.const_i32(global_pointers::last_op1 as i32);
  1655. codegen::gen_get_reg32(ctx, regs::EAX);
  1656. ctx.builder.store_aligned_i32(0);
  1657. codegen::gen_set_last_op_size_and_flags_changed(ctx.builder, OPSIZE_32, FLAGS_ALL | FLAG_SUB);
  1658. codegen::gen_get_reg32(ctx, regs::EAX);
  1659. ctx.builder.get_local(&source);
  1660. ctx.builder.eq_i32();
  1661. ctx.builder.if_i32();
  1662. codegen::gen_get_reg32(ctx, r);
  1663. ctx.builder.else_();
  1664. ctx.builder.get_local(&source);
  1665. codegen::gen_set_reg32(ctx, regs::EAX);
  1666. ctx.builder.get_local(&source);
  1667. ctx.builder.block_end();
  1668. ctx.builder.free_local(source);
  1669. }
  1670. fn gen_mul32(ctx: &mut JitContext) {
  1671. ctx.builder.extend_unsigned_i32_to_i64();
  1672. codegen::gen_get_reg32(ctx, regs::EAX);
  1673. ctx.builder.extend_unsigned_i32_to_i64();
  1674. ctx.builder.mul_i64();
  1675. let result = ctx.builder.tee_new_local_i64();
  1676. ctx.builder.const_i64(32);
  1677. ctx.builder.shr_u_i64();
  1678. ctx.builder.wrap_i64_to_i32();
  1679. codegen::gen_set_reg32(ctx, regs::EDX);
  1680. ctx.builder.get_local_i64(&result);
  1681. ctx.builder.free_local_i64(result);
  1682. ctx.builder.wrap_i64_to_i32();
  1683. codegen::gen_set_reg32(ctx, regs::EAX);
  1684. codegen::gen_get_reg32(ctx, regs::EDX);
  1685. ctx.builder.if_void();
  1686. codegen::gen_set_flags_bits(ctx.builder, 1 | FLAG_OVERFLOW);
  1687. ctx.builder.else_();
  1688. codegen::gen_clear_flags_bits(ctx.builder, 1 | FLAG_OVERFLOW);
  1689. ctx.builder.block_end();
  1690. codegen::gen_set_last_result(ctx.builder, &ctx.register_locals[regs::EAX as usize]);
  1691. codegen::gen_set_last_op_size_and_flags_changed(
  1692. ctx.builder,
  1693. OPSIZE_32,
  1694. FLAGS_ALL & !1 & !FLAG_OVERFLOW,
  1695. );
  1696. }
  1697. fn gen_imul32(ctx: &mut JitContext) {
  1698. ctx.builder.extend_signed_i32_to_i64();
  1699. codegen::gen_get_reg32(ctx, regs::EAX);
  1700. ctx.builder.extend_signed_i32_to_i64();
  1701. ctx.builder.mul_i64();
  1702. let result = ctx.builder.tee_new_local_i64();
  1703. ctx.builder.const_i64(32);
  1704. ctx.builder.shr_u_i64();
  1705. ctx.builder.wrap_i64_to_i32();
  1706. codegen::gen_set_reg32(ctx, regs::EDX);
  1707. ctx.builder.get_local_i64(&result);
  1708. ctx.builder.free_local_i64(result);
  1709. ctx.builder.wrap_i64_to_i32();
  1710. codegen::gen_set_reg32(ctx, regs::EAX);
  1711. codegen::gen_get_reg32(ctx, regs::EDX);
  1712. codegen::gen_get_reg32(ctx, regs::EAX);
  1713. ctx.builder.const_i32(31);
  1714. ctx.builder.shr_s_i32();
  1715. ctx.builder.eq_i32();
  1716. ctx.builder.if_void();
  1717. codegen::gen_clear_flags_bits(ctx.builder, 1 | FLAG_OVERFLOW);
  1718. ctx.builder.else_();
  1719. codegen::gen_set_flags_bits(ctx.builder, 1 | FLAG_OVERFLOW);
  1720. ctx.builder.block_end();
  1721. codegen::gen_set_last_result(ctx.builder, &ctx.register_locals[regs::EAX as usize]);
  1722. codegen::gen_set_last_op_size_and_flags_changed(
  1723. ctx.builder,
  1724. OPSIZE_32,
  1725. FLAGS_ALL & !1 & !FLAG_OVERFLOW,
  1726. );
  1727. }
  1728. fn gen_imul_reg32(
  1729. ctx: &mut JitContext,
  1730. dest_operand: &WasmLocal,
  1731. source_operand: &LocalOrImmediate,
  1732. ) {
  1733. gen_imul3_reg32(ctx.builder, dest_operand, dest_operand, source_operand);
  1734. }
  1735. fn gen_imul3_reg32(
  1736. builder: &mut WasmBuilder,
  1737. dest_operand: &WasmLocal,
  1738. source_operand1: &WasmLocal,
  1739. source_operand2: &LocalOrImmediate,
  1740. ) {
  1741. builder.get_local(&source_operand1);
  1742. builder.extend_signed_i32_to_i64();
  1743. source_operand2.gen_get(builder);
  1744. builder.extend_signed_i32_to_i64();
  1745. builder.mul_i64();
  1746. let result = builder.tee_new_local_i64();
  1747. builder.wrap_i64_to_i32();
  1748. builder.set_local(&dest_operand);
  1749. codegen::gen_set_last_result(builder, &dest_operand);
  1750. codegen::gen_set_last_op_size_and_flags_changed(
  1751. builder,
  1752. OPSIZE_32,
  1753. FLAGS_ALL & !1 & !FLAG_OVERFLOW,
  1754. );
  1755. builder.const_i32(global_pointers::flags as i32);
  1756. builder.get_local_i64(&result);
  1757. builder.wrap_i64_to_i32();
  1758. builder.extend_signed_i32_to_i64();
  1759. builder.get_local_i64(&result);
  1760. builder.ne_i64();
  1761. builder.const_i32(1 | FLAG_OVERFLOW);
  1762. builder.mul_i32();
  1763. codegen::gen_get_flags(builder);
  1764. builder.const_i32(!1 & !FLAG_OVERFLOW);
  1765. builder.and_i32();
  1766. builder.or_i32();
  1767. builder.store_aligned_i32(0);
  1768. builder.free_local_i64(result);
  1769. }
  1770. fn gen_div32(ctx: &mut JitContext, source: &WasmLocal) {
  1771. let done = ctx.builder.block_void();
  1772. {
  1773. let exception = ctx.builder.block_void();
  1774. {
  1775. ctx.builder.get_local(source);
  1776. ctx.builder.eqz_i32();
  1777. ctx.builder.br_if(exception);
  1778. codegen::gen_get_reg32(ctx, regs::EDX);
  1779. ctx.builder.extend_unsigned_i32_to_i64();
  1780. ctx.builder.const_i64(32);
  1781. ctx.builder.shl_i64();
  1782. codegen::gen_get_reg32(ctx, regs::EAX);
  1783. ctx.builder.extend_unsigned_i32_to_i64();
  1784. ctx.builder.or_i64();
  1785. let dest_operand = ctx.builder.tee_new_local_i64();
  1786. ctx.builder.get_local(source);
  1787. ctx.builder.extend_unsigned_i32_to_i64();
  1788. ctx.builder.div_i64();
  1789. let result = ctx.builder.tee_new_local_i64();
  1790. ctx.builder.const_i64(0xFFFF_FFFF);
  1791. ctx.builder.gtu_i64();
  1792. ctx.builder.br_if(exception);
  1793. ctx.builder.get_local_i64(&dest_operand);
  1794. ctx.builder.get_local(source);
  1795. ctx.builder.extend_unsigned_i32_to_i64();
  1796. ctx.builder.rem_i64();
  1797. ctx.builder.wrap_i64_to_i32();
  1798. codegen::gen_set_reg32(ctx, regs::EDX);
  1799. ctx.builder.get_local_i64(&result);
  1800. ctx.builder.wrap_i64_to_i32();
  1801. codegen::gen_set_reg32(ctx, regs::EAX);
  1802. ctx.builder.br(done);
  1803. ctx.builder.free_local_i64(dest_operand);
  1804. ctx.builder.free_local_i64(result);
  1805. }
  1806. ctx.builder.block_end();
  1807. codegen::gen_trigger_de(ctx);
  1808. }
  1809. ctx.builder.block_end();
  1810. }
  1811. fn gen_bt(
  1812. builder: &mut WasmBuilder,
  1813. bit_base: &WasmLocal,
  1814. bit_offset: &LocalOrImmediate,
  1815. offset_mask: u32,
  1816. ) {
  1817. builder.const_i32(global_pointers::flags as i32);
  1818. codegen::gen_get_flags(builder);
  1819. builder.const_i32(!1);
  1820. builder.and_i32();
  1821. builder.get_local(bit_base);
  1822. match bit_offset {
  1823. LocalOrImmediate::WasmLocal(l) => {
  1824. builder.get_local(l);
  1825. builder.const_i32(offset_mask as i32);
  1826. builder.and_i32();
  1827. },
  1828. LocalOrImmediate::Immediate(imm) => builder.const_i32(imm & offset_mask as i32),
  1829. }
  1830. builder.shr_u_i32();
  1831. builder.const_i32(1);
  1832. builder.and_i32();
  1833. builder.or_i32();
  1834. builder.store_aligned_i32(0);
  1835. codegen::gen_clear_flags_changed_bits(builder, 1);
  1836. }
  1837. fn gen_bts(
  1838. builder: &mut WasmBuilder,
  1839. dest_bit_base: &WasmLocal,
  1840. bit_offset: &LocalOrImmediate,
  1841. offset_mask: u32,
  1842. ) {
  1843. gen_bt(builder, dest_bit_base, bit_offset, offset_mask);
  1844. builder.get_local(dest_bit_base);
  1845. match bit_offset {
  1846. LocalOrImmediate::WasmLocal(l) => {
  1847. builder.const_i32(1);
  1848. builder.get_local(l);
  1849. builder.const_i32(offset_mask as i32);
  1850. builder.and_i32();
  1851. builder.shl_i32();
  1852. },
  1853. LocalOrImmediate::Immediate(imm) => builder.const_i32(1 << (imm & offset_mask as i32)),
  1854. }
  1855. builder.or_i32();
  1856. builder.set_local(dest_bit_base);
  1857. }
  1858. fn gen_btc(
  1859. builder: &mut WasmBuilder,
  1860. dest_bit_base: &WasmLocal,
  1861. bit_offset: &LocalOrImmediate,
  1862. offset_mask: u32,
  1863. ) {
  1864. gen_bt(builder, dest_bit_base, bit_offset, offset_mask);
  1865. builder.get_local(dest_bit_base);
  1866. match bit_offset {
  1867. LocalOrImmediate::WasmLocal(l) => {
  1868. builder.const_i32(1);
  1869. builder.get_local(l);
  1870. builder.const_i32(offset_mask as i32);
  1871. builder.and_i32();
  1872. builder.shl_i32();
  1873. },
  1874. LocalOrImmediate::Immediate(imm) => builder.const_i32(1 << (imm & offset_mask as i32)),
  1875. }
  1876. builder.xor_i32();
  1877. builder.set_local(dest_bit_base);
  1878. }
  1879. fn gen_btr(
  1880. builder: &mut WasmBuilder,
  1881. dest_bit_base: &WasmLocal,
  1882. bit_offset: &LocalOrImmediate,
  1883. offset_mask: u32,
  1884. ) {
  1885. gen_bt(builder, dest_bit_base, bit_offset, offset_mask);
  1886. builder.get_local(dest_bit_base);
  1887. match bit_offset {
  1888. LocalOrImmediate::WasmLocal(l) => {
  1889. builder.const_i32(1);
  1890. builder.get_local(l);
  1891. builder.const_i32(offset_mask as i32);
  1892. builder.and_i32();
  1893. builder.shl_i32();
  1894. builder.const_i32(-1);
  1895. builder.xor_i32();
  1896. },
  1897. LocalOrImmediate::Immediate(imm) => builder.const_i32(!(1 << (imm & offset_mask as i32))),
  1898. }
  1899. builder.and_i32();
  1900. builder.set_local(dest_bit_base);
  1901. }
  1902. fn gen_bit_rmw(
  1903. ctx: &mut JitContext,
  1904. modrm_byte: ModrmByte,
  1905. op: &dyn Fn(&mut WasmBuilder, &WasmLocal, &LocalOrImmediate, u32),
  1906. source_operand: &LocalOrImmediate,
  1907. opsize: i32,
  1908. ) {
  1909. dbg_assert!(opsize == 16 || opsize == 32);
  1910. codegen::gen_modrm_resolve(ctx, modrm_byte);
  1911. match source_operand {
  1912. LocalOrImmediate::WasmLocal(l) => {
  1913. ctx.builder.get_local(l);
  1914. if opsize == 16 {
  1915. codegen::sign_extend_i16(ctx.builder);
  1916. }
  1917. ctx.builder.const_i32(3);
  1918. ctx.builder.shr_s_i32();
  1919. ctx.builder.add_i32();
  1920. },
  1921. &LocalOrImmediate::Immediate(imm8) => {
  1922. let offset = (imm8 as i32 & (opsize - 1)) >> 3;
  1923. if offset != 0 {
  1924. ctx.builder.const_i32(offset);
  1925. ctx.builder.add_i32();
  1926. }
  1927. },
  1928. }
  1929. let address_local = ctx.builder.set_new_local();
  1930. codegen::gen_safe_read_write(ctx, BitSize::BYTE, &address_local, &|ref mut ctx| {
  1931. let value_local = ctx.builder.set_new_local();
  1932. op(ctx.builder, &value_local, source_operand, 7);
  1933. ctx.builder.get_local(&value_local);
  1934. ctx.builder.free_local(value_local);
  1935. });
  1936. ctx.builder.free_local(address_local);
  1937. }
  1938. fn gen_bsf32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1939. ctx.builder.get_local(&dest_operand);
  1940. source_operand.gen_get(ctx.builder);
  1941. ctx.builder.call_fn2_ret("bsf32");
  1942. ctx.builder.set_local(dest_operand);
  1943. }
  1944. fn gen_bsr32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
  1945. ctx.builder.get_local(&dest_operand);
  1946. source_operand.gen_get(ctx.builder);
  1947. ctx.builder.call_fn2_ret("bsr32");
  1948. ctx.builder.set_local(dest_operand);
  1949. }
  1950. fn gen_bswap(ctx: &mut JitContext, reg: i32) {
  1951. let l = &ctx.register_locals[reg as usize];
  1952. ctx.builder.get_local(l);
  1953. ctx.builder.const_i32(8);
  1954. ctx.builder.rotl_i32();
  1955. ctx.builder.const_i32(0xFF00FF);
  1956. ctx.builder.and_i32();
  1957. ctx.builder.get_local(l);
  1958. ctx.builder.const_i32(24);
  1959. ctx.builder.rotl_i32();
  1960. ctx.builder.const_i32(0xFF00FF00u32 as i32);
  1961. ctx.builder.and_i32();
  1962. ctx.builder.or_i32();
  1963. ctx.builder.set_local(l);
  1964. }
  1965. define_instruction_read_write_mem8!(gen_add8, instr_00_mem_jit, instr_00_reg_jit, reg);
  1966. define_instruction_read_write_mem16!("add16", instr16_01_mem_jit, instr16_01_reg_jit, reg);
  1967. define_instruction_read_write_mem32!(gen_add32, instr32_01_mem_jit, instr32_01_reg_jit, reg);
  1968. define_instruction_write_reg8!(gen_add8, instr_02_mem_jit, instr_02_reg_jit);
  1969. define_instruction_write_reg16!("add16", instr16_03_mem_jit, instr16_03_reg_jit);
  1970. define_instruction_write_reg32!(gen_add32, instr32_03_mem_jit, instr32_03_reg_jit);
  1971. pub fn instr_04_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, &gen_add8, imm8); }
  1972. pub fn instr16_05_jit(ctx: &mut JitContext, imm16: u32) {
  1973. group_arith_ax_imm16(ctx, "add16", imm16);
  1974. }
  1975. pub fn instr32_05_jit(ctx: &mut JitContext, imm32: u32) {
  1976. group_arith_eax_imm32(ctx, &gen_add32, imm32);
  1977. }
  1978. define_instruction_read_write_mem8!(gen_or8, instr_08_mem_jit, instr_08_reg_jit, reg);
  1979. define_instruction_read_write_mem16!("or16", instr16_09_mem_jit, instr16_09_reg_jit, reg);
  1980. define_instruction_read_write_mem32!(gen_or32, instr32_09_mem_jit, instr32_09_reg_jit, reg);
  1981. define_instruction_write_reg8!(gen_or8, instr_0A_mem_jit, instr_0A_reg_jit);
  1982. define_instruction_write_reg16!("or16", instr16_0B_mem_jit, instr16_0B_reg_jit);
  1983. define_instruction_write_reg32!(gen_or32, instr32_0B_mem_jit, instr32_0B_reg_jit);
  1984. pub fn instr_0C_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, &gen_or8, imm8); }
  1985. pub fn instr16_0D_jit(ctx: &mut JitContext, imm16: u32) {
  1986. group_arith_ax_imm16(ctx, "or16", imm16);
  1987. }
  1988. pub fn instr32_0D_jit(ctx: &mut JitContext, imm32: u32) {
  1989. group_arith_eax_imm32(ctx, &gen_or32, imm32);
  1990. }
  1991. define_instruction_read_write_mem8!(gen_adc8, instr_10_mem_jit, instr_10_reg_jit, reg);
  1992. define_instruction_read_write_mem16!("adc16", instr16_11_mem_jit, instr16_11_reg_jit, reg);
  1993. define_instruction_read_write_mem32!(gen_adc32, instr32_11_mem_jit, instr32_11_reg_jit, reg);
  1994. define_instruction_write_reg8!(gen_adc8, instr_12_mem_jit, instr_12_reg_jit);
  1995. define_instruction_write_reg16!("adc16", instr16_13_mem_jit, instr16_13_reg_jit);
  1996. define_instruction_write_reg32!(gen_adc32, instr32_13_mem_jit, instr32_13_reg_jit);
  1997. pub fn instr_14_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, &gen_adc8, imm8); }
  1998. pub fn instr16_15_jit(ctx: &mut JitContext, imm16: u32) {
  1999. group_arith_ax_imm16(ctx, "adc16", imm16);
  2000. }
  2001. pub fn instr32_15_jit(ctx: &mut JitContext, imm32: u32) {
  2002. group_arith_eax_imm32(ctx, &gen_adc32, imm32);
  2003. }
  2004. define_instruction_read_write_mem8!(gen_sbb8, instr_18_mem_jit, instr_18_reg_jit, reg);
  2005. define_instruction_read_write_mem16!("sbb16", instr16_19_mem_jit, instr16_19_reg_jit, reg);
  2006. define_instruction_read_write_mem32!(gen_sbb32, instr32_19_mem_jit, instr32_19_reg_jit, reg);
  2007. define_instruction_write_reg8!(gen_sbb8, instr_1A_mem_jit, instr_1A_reg_jit);
  2008. define_instruction_write_reg16!("sbb16", instr16_1B_mem_jit, instr16_1B_reg_jit);
  2009. define_instruction_write_reg32!(gen_sbb32, instr32_1B_mem_jit, instr32_1B_reg_jit);
  2010. pub fn instr_1C_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, &gen_sbb8, imm8); }
  2011. pub fn instr16_1D_jit(ctx: &mut JitContext, imm16: u32) {
  2012. group_arith_ax_imm16(ctx, "sbb16", imm16);
  2013. }
  2014. pub fn instr32_1D_jit(ctx: &mut JitContext, imm32: u32) {
  2015. group_arith_eax_imm32(ctx, &gen_sbb32, imm32);
  2016. }
  2017. define_instruction_read_write_mem8!(gen_and8, instr_20_mem_jit, instr_20_reg_jit, reg);
  2018. define_instruction_read_write_mem16!("and16", instr16_21_mem_jit, instr16_21_reg_jit, reg);
  2019. define_instruction_read_write_mem32!(gen_and32, instr32_21_mem_jit, instr32_21_reg_jit, reg);
  2020. define_instruction_write_reg8!(gen_and8, instr_22_mem_jit, instr_22_reg_jit);
  2021. define_instruction_write_reg16!("and16", instr16_23_mem_jit, instr16_23_reg_jit);
  2022. define_instruction_write_reg32!(gen_and32, instr32_23_mem_jit, instr32_23_reg_jit);
  2023. pub fn instr_24_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, &gen_and8, imm8); }
  2024. pub fn instr16_25_jit(ctx: &mut JitContext, imm16: u32) {
  2025. group_arith_ax_imm16(ctx, "and16", imm16);
  2026. }
  2027. pub fn instr32_25_jit(ctx: &mut JitContext, imm32: u32) {
  2028. group_arith_eax_imm32(ctx, &gen_and32, imm32);
  2029. }
  2030. define_instruction_read_write_mem8!(gen_sub8, instr_28_mem_jit, instr_28_reg_jit, reg);
  2031. define_instruction_read_write_mem16!("sub16", instr16_29_mem_jit, instr16_29_reg_jit, reg);
  2032. define_instruction_read_write_mem32!(gen_sub32, instr32_29_mem_jit, instr32_29_reg_jit, reg);
  2033. define_instruction_write_reg8!(gen_sub8, instr_2A_mem_jit, instr_2A_reg_jit);
  2034. define_instruction_write_reg16!("sub16", instr16_2B_mem_jit, instr16_2B_reg_jit);
  2035. define_instruction_write_reg32!(gen_sub32, instr32_2B_mem_jit, instr32_2B_reg_jit);
  2036. pub fn instr_2C_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, &gen_sub8, imm8); }
  2037. pub fn instr16_2D_jit(ctx: &mut JitContext, imm16: u32) {
  2038. group_arith_ax_imm16(ctx, "sub16", imm16);
  2039. }
  2040. pub fn instr32_2D_jit(ctx: &mut JitContext, imm32: u32) {
  2041. group_arith_eax_imm32(ctx, &gen_sub32, imm32);
  2042. }
  2043. define_instruction_read_write_mem8!(gen_xor8, instr_30_mem_jit, instr_30_reg_jit, reg);
  2044. define_instruction_read_write_mem16!("xor16", instr16_31_mem_jit, instr16_31_reg_jit, reg);
  2045. define_instruction_read_write_mem32!(gen_xor32, instr32_31_mem_jit, instr32_31_reg_jit, reg);
  2046. define_instruction_write_reg8!(gen_xor8, instr_32_mem_jit, instr_32_reg_jit);
  2047. define_instruction_write_reg16!("xor16", instr16_33_mem_jit, instr16_33_reg_jit);
  2048. define_instruction_write_reg32!(gen_xor32, instr32_33_mem_jit, instr32_33_reg_jit);
  2049. pub fn instr_34_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, &gen_xor8, imm8); }
  2050. pub fn instr16_35_jit(ctx: &mut JitContext, imm16: u32) {
  2051. group_arith_ax_imm16(ctx, "xor16", imm16);
  2052. }
  2053. pub fn instr32_35_jit(ctx: &mut JitContext, imm32: u32) {
  2054. group_arith_eax_imm32(ctx, &gen_xor32, imm32);
  2055. }
  2056. define_instruction_read8!(gen_cmp8, instr_38_mem_jit, instr_38_reg_jit);
  2057. define_instruction_read16!(gen_cmp16, instr16_39_mem_jit, instr16_39_reg_jit);
  2058. define_instruction_read32!(gen_cmp32, instr32_39_mem_jit, instr32_39_reg_jit);
  2059. pub fn instr_3A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2060. let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r);
  2061. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
  2062. let source_operand = ctx.builder.set_new_local();
  2063. gen_cmp8(
  2064. ctx,
  2065. &dest_operand,
  2066. &LocalOrImmediate::WasmLocal(&source_operand),
  2067. );
  2068. codegen::gen_free_reg8_or_alias(ctx, r, dest_operand);
  2069. ctx.builder.free_local(source_operand);
  2070. }
  2071. pub fn instr_3A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2072. let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r2);
  2073. let source_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r1);
  2074. gen_cmp8(
  2075. ctx,
  2076. &dest_operand,
  2077. &LocalOrImmediate::WasmLocal(&source_operand),
  2078. );
  2079. codegen::gen_free_reg8_or_alias(ctx, r2, dest_operand);
  2080. codegen::gen_free_reg8_or_alias(ctx, r1, source_operand);
  2081. }
  2082. pub fn instr16_3B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2083. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  2084. let source_operand = ctx.builder.set_new_local();
  2085. gen_cmp16(
  2086. ctx,
  2087. &ctx.reg(r),
  2088. &LocalOrImmediate::WasmLocal(&source_operand),
  2089. );
  2090. ctx.builder.free_local(source_operand);
  2091. }
  2092. pub fn instr16_3B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2093. gen_cmp16(
  2094. ctx,
  2095. &ctx.reg(r2),
  2096. &LocalOrImmediate::WasmLocal(&ctx.reg(r1)),
  2097. );
  2098. }
  2099. pub fn instr32_3B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2100. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  2101. let source_operand = ctx.builder.set_new_local();
  2102. gen_cmp32(
  2103. ctx,
  2104. &ctx.reg(r),
  2105. &LocalOrImmediate::WasmLocal(&source_operand),
  2106. );
  2107. ctx.builder.free_local(source_operand);
  2108. }
  2109. pub fn instr32_3B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2110. gen_cmp32(
  2111. ctx,
  2112. &ctx.reg(r2),
  2113. &LocalOrImmediate::WasmLocal(&ctx.reg(r1)),
  2114. );
  2115. }
  2116. pub fn instr_3C_jit(ctx: &mut JitContext, imm8: u32) {
  2117. gen_cmp8(ctx, &ctx.reg(0), &LocalOrImmediate::Immediate(imm8 as i32));
  2118. }
  2119. pub fn instr16_3D_jit(ctx: &mut JitContext, imm16: u32) {
  2120. gen_cmp16(ctx, &ctx.reg(0), &LocalOrImmediate::Immediate(imm16 as i32));
  2121. }
  2122. pub fn instr32_3D_jit(ctx: &mut JitContext, imm32: u32) {
  2123. gen_cmp32(ctx, &ctx.reg(0), &LocalOrImmediate::Immediate(imm32 as i32));
  2124. }
  2125. fn gen_inc(ctx: &mut JitContext, dest_operand: &WasmLocal, size: i32) {
  2126. ctx.builder.const_i32(global_pointers::flags as i32);
  2127. codegen::gen_get_flags(ctx.builder);
  2128. ctx.builder.const_i32(!1);
  2129. ctx.builder.and_i32();
  2130. codegen::gen_getcf(ctx, ConditionNegate::False);
  2131. ctx.builder.or_i32();
  2132. ctx.builder.store_aligned_i32(0);
  2133. ctx.builder.const_i32(global_pointers::last_op1 as i32);
  2134. ctx.builder.get_local(&dest_operand);
  2135. if size == OPSIZE_8 || size == OPSIZE_16 {
  2136. ctx.builder
  2137. .const_i32(if size == OPSIZE_8 { 0xFF } else { 0xFFFF });
  2138. ctx.builder.and_i32();
  2139. }
  2140. ctx.builder.store_aligned_i32(0);
  2141. ctx.builder.get_local(dest_operand);
  2142. ctx.builder.const_i32(1);
  2143. ctx.builder.add_i32();
  2144. if size == OPSIZE_16 {
  2145. codegen::gen_set_reg16_local(ctx.builder, dest_operand);
  2146. }
  2147. else {
  2148. ctx.builder.set_local(dest_operand);
  2149. }
  2150. ctx.builder.const_i32(global_pointers::last_result as i32);
  2151. ctx.builder.get_local(&dest_operand);
  2152. if size == OPSIZE_16 {
  2153. ctx.builder.const_i32(0xFFFF);
  2154. ctx.builder.and_i32();
  2155. }
  2156. ctx.builder.store_aligned_i32(0);
  2157. codegen::gen_set_last_op_size_and_flags_changed(ctx.builder, size, FLAGS_ALL & !1);
  2158. ctx.current_instruction = Instruction::Add {
  2159. opsize: size,
  2160. dest: local_to_instruction_operand(ctx, dest_operand),
  2161. source: InstructionOperand::Immediate(1),
  2162. is_inc: true,
  2163. };
  2164. }
  2165. fn gen_inc16(ctx: &mut JitContext, dest_operand: &WasmLocal) {
  2166. gen_inc(ctx, dest_operand, OPSIZE_16);
  2167. }
  2168. fn gen_inc32(ctx: &mut JitContext, dest_operand: &WasmLocal) {
  2169. gen_inc(ctx, dest_operand, OPSIZE_32);
  2170. }
  2171. fn gen_dec(ctx: &mut JitContext, dest_operand: &WasmLocal, size: i32) {
  2172. ctx.builder.const_i32(global_pointers::flags as i32);
  2173. codegen::gen_get_flags(ctx.builder);
  2174. ctx.builder.const_i32(!1);
  2175. ctx.builder.and_i32();
  2176. codegen::gen_getcf(ctx, ConditionNegate::False);
  2177. ctx.builder.or_i32();
  2178. ctx.builder.store_aligned_i32(0);
  2179. ctx.builder.const_i32(global_pointers::last_op1 as i32);
  2180. ctx.builder.get_local(&dest_operand);
  2181. if size == OPSIZE_8 || size == OPSIZE_16 {
  2182. ctx.builder
  2183. .const_i32(if size == OPSIZE_8 { 0xFF } else { 0xFFFF });
  2184. ctx.builder.and_i32();
  2185. }
  2186. ctx.builder.store_aligned_i32(0);
  2187. ctx.builder.get_local(dest_operand);
  2188. ctx.builder.const_i32(1);
  2189. ctx.builder.sub_i32();
  2190. if size == OPSIZE_16 {
  2191. codegen::gen_set_reg16_local(ctx.builder, dest_operand);
  2192. }
  2193. else {
  2194. ctx.builder.set_local(dest_operand);
  2195. }
  2196. ctx.builder.const_i32(global_pointers::last_result as i32);
  2197. ctx.builder.get_local(&dest_operand);
  2198. if size == OPSIZE_16 {
  2199. ctx.builder.const_i32(0xFFFF);
  2200. ctx.builder.and_i32();
  2201. }
  2202. ctx.builder.store_aligned_i32(0);
  2203. codegen::gen_set_last_op_size_and_flags_changed(ctx.builder, size, FLAGS_ALL & !1 | FLAG_SUB);
  2204. ctx.current_instruction = Instruction::Sub {
  2205. opsize: size,
  2206. dest: local_to_instruction_operand(ctx, dest_operand),
  2207. source: InstructionOperand::Immediate(1),
  2208. is_dec: true,
  2209. };
  2210. }
  2211. fn gen_dec16(ctx: &mut JitContext, dest_operand: &WasmLocal) {
  2212. gen_dec(ctx, dest_operand, OPSIZE_16)
  2213. }
  2214. fn gen_dec32(ctx: &mut JitContext, dest_operand: &WasmLocal) {
  2215. gen_dec(ctx, dest_operand, OPSIZE_32)
  2216. }
  2217. fn gen_inc16_r(ctx: &mut JitContext, r: u32) { gen_inc16(ctx, &mut ctx.reg(r)) }
  2218. fn gen_inc32_r(ctx: &mut JitContext, r: u32) { gen_inc32(ctx, &mut ctx.reg(r)) }
  2219. fn gen_dec16_r(ctx: &mut JitContext, r: u32) { gen_dec16(ctx, &mut ctx.reg(r)) }
  2220. fn gen_dec32_r(ctx: &mut JitContext, r: u32) { gen_dec32(ctx, &mut ctx.reg(r)) }
  2221. fn gen_not16(ctx: &mut JitContext, dest_operand: &WasmLocal) {
  2222. let builder = &mut ctx.builder;
  2223. builder.get_local(dest_operand);
  2224. builder.const_i32(-1);
  2225. builder.xor_i32();
  2226. codegen::gen_set_reg16_local(builder, dest_operand);
  2227. }
  2228. fn gen_not32(ctx: &mut JitContext, dest_operand: &WasmLocal) {
  2229. let builder = &mut ctx.builder;
  2230. builder.get_local(dest_operand);
  2231. builder.const_i32(-1);
  2232. builder.xor_i32();
  2233. builder.set_local(dest_operand);
  2234. }
  2235. fn gen_neg16(ctx: &mut JitContext, dest_operand: &WasmLocal) {
  2236. let builder = &mut ctx.builder;
  2237. builder.get_local(dest_operand);
  2238. builder.call_fn1_ret("neg16");
  2239. codegen::gen_set_reg16_local(builder, dest_operand);
  2240. }
  2241. fn gen_neg32(ctx: &mut JitContext, dest_operand: &WasmLocal) {
  2242. let builder = &mut ctx.builder;
  2243. builder.const_i32(global_pointers::last_op1 as i32);
  2244. builder.const_i32(0);
  2245. builder.store_aligned_i32(0);
  2246. builder.const_i32(0);
  2247. builder.get_local(&dest_operand);
  2248. builder.sub_i32();
  2249. builder.set_local(dest_operand);
  2250. codegen::gen_set_last_result(builder, &dest_operand);
  2251. codegen::gen_set_last_op_size_and_flags_changed(builder, OPSIZE_32, FLAGS_ALL | FLAG_SUB);
  2252. }
  2253. pub fn instr16_06_jit(ctx: &mut JitContext) {
  2254. codegen::gen_get_sreg(ctx, regs::ES);
  2255. let sreg = ctx.builder.set_new_local();
  2256. codegen::gen_push16(ctx, &sreg);
  2257. ctx.builder.free_local(sreg);
  2258. }
  2259. pub fn instr32_06_jit(ctx: &mut JitContext) { codegen::gen_push32_sreg(ctx, regs::ES) }
  2260. pub fn instr16_0E_jit(ctx: &mut JitContext) {
  2261. codegen::gen_get_sreg(ctx, regs::CS);
  2262. let sreg = ctx.builder.set_new_local();
  2263. codegen::gen_push16(ctx, &sreg);
  2264. ctx.builder.free_local(sreg);
  2265. }
  2266. pub fn instr32_0E_jit(ctx: &mut JitContext) { codegen::gen_push32_sreg(ctx, regs::CS) }
  2267. pub fn instr16_16_jit(ctx: &mut JitContext) {
  2268. codegen::gen_get_sreg(ctx, regs::SS);
  2269. let sreg = ctx.builder.set_new_local();
  2270. codegen::gen_push16(ctx, &sreg);
  2271. ctx.builder.free_local(sreg);
  2272. }
  2273. pub fn instr32_16_jit(ctx: &mut JitContext) { codegen::gen_push32_sreg(ctx, regs::SS) }
  2274. pub fn instr16_1E_jit(ctx: &mut JitContext) {
  2275. codegen::gen_get_sreg(ctx, regs::DS);
  2276. let sreg = ctx.builder.set_new_local();
  2277. codegen::gen_push16(ctx, &sreg);
  2278. ctx.builder.free_local(sreg);
  2279. }
  2280. pub fn instr32_1E_jit(ctx: &mut JitContext) { codegen::gen_push32_sreg(ctx, regs::DS) }
  2281. pub fn instr16_40_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, AX); }
  2282. pub fn instr32_40_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EAX); }
  2283. pub fn instr16_41_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, CX); }
  2284. pub fn instr32_41_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, ECX); }
  2285. pub fn instr16_42_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, DX); }
  2286. pub fn instr32_42_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EDX); }
  2287. pub fn instr16_43_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, BX); }
  2288. pub fn instr32_43_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EBX); }
  2289. pub fn instr16_44_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, SP); }
  2290. pub fn instr32_44_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, ESP); }
  2291. pub fn instr16_45_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, BP); }
  2292. pub fn instr32_45_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EBP); }
  2293. pub fn instr16_46_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, SI); }
  2294. pub fn instr32_46_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, ESI); }
  2295. pub fn instr16_47_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, DI); }
  2296. pub fn instr32_47_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EDI); }
  2297. pub fn instr16_48_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, AX); }
  2298. pub fn instr32_48_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EAX); }
  2299. pub fn instr16_49_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, CX); }
  2300. pub fn instr32_49_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, ECX); }
  2301. pub fn instr16_4A_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, DX); }
  2302. pub fn instr32_4A_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EDX); }
  2303. pub fn instr16_4B_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, BX); }
  2304. pub fn instr32_4B_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EBX); }
  2305. pub fn instr16_4C_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, SP); }
  2306. pub fn instr32_4C_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, ESP); }
  2307. pub fn instr16_4D_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, BP); }
  2308. pub fn instr32_4D_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EBP); }
  2309. pub fn instr16_4E_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, SI); }
  2310. pub fn instr32_4E_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, ESI); }
  2311. pub fn instr16_4F_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, DI); }
  2312. pub fn instr32_4F_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EDI); }
  2313. pub fn instr16_50_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, AX); }
  2314. pub fn instr32_50_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EAX); }
  2315. pub fn instr16_51_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, CX); }
  2316. pub fn instr32_51_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, ECX); }
  2317. pub fn instr16_52_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, DX); }
  2318. pub fn instr32_52_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EDX); }
  2319. pub fn instr16_53_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, BX); }
  2320. pub fn instr32_53_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EBX); }
  2321. pub fn instr16_54_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, SP); }
  2322. pub fn instr32_54_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, ESP); }
  2323. pub fn instr16_55_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, BP); }
  2324. pub fn instr32_55_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EBP); }
  2325. pub fn instr16_56_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, SI); }
  2326. pub fn instr32_56_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, ESI); }
  2327. pub fn instr16_57_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, DI); }
  2328. pub fn instr32_57_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EDI); }
  2329. pub fn instr16_58_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, AX); }
  2330. pub fn instr32_58_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EAX); }
  2331. pub fn instr16_59_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, CX); }
  2332. pub fn instr32_59_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, ECX); }
  2333. pub fn instr16_5A_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, DX); }
  2334. pub fn instr32_5A_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EDX); }
  2335. pub fn instr16_5B_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, BX); }
  2336. pub fn instr32_5B_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EBX); }
  2337. pub fn instr16_5C_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, SP); }
  2338. pub fn instr32_5C_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, ESP); }
  2339. pub fn instr16_5D_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, BP); }
  2340. pub fn instr32_5D_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EBP); }
  2341. pub fn instr16_5E_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, SI); }
  2342. pub fn instr32_5E_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, ESI); }
  2343. pub fn instr16_5F_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, DI); }
  2344. pub fn instr32_5F_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EDI); }
  2345. pub fn instr16_68_jit(ctx: &mut JitContext, imm16: u32) { push16_imm_jit(ctx, imm16) }
  2346. pub fn instr32_68_jit(ctx: &mut JitContext, imm32: u32) { push32_imm_jit(ctx, imm32) }
  2347. pub fn instr16_6A_jit(ctx: &mut JitContext, imm16: u32) { push16_imm_jit(ctx, imm16) }
  2348. pub fn instr32_6A_jit(ctx: &mut JitContext, imm32: u32) { push32_imm_jit(ctx, imm32) }
  2349. pub fn instr16_69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm16: u32) {
  2350. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  2351. ctx.builder.const_i32(imm16 as i32);
  2352. ctx.builder.call_fn2_ret("imul_reg16");
  2353. codegen::gen_set_reg16(ctx, r);
  2354. }
  2355. pub fn instr16_69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm16: u32) {
  2356. codegen::gen_get_reg16(ctx, r1);
  2357. ctx.builder.const_i32(imm16 as i32);
  2358. ctx.builder.call_fn2_ret("imul_reg16");
  2359. codegen::gen_set_reg16(ctx, r2);
  2360. }
  2361. pub fn instr32_69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm32: u32) {
  2362. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  2363. let value_local = ctx.builder.set_new_local();
  2364. gen_imul3_reg32(
  2365. ctx.builder,
  2366. &ctx.register_locals[r as usize],
  2367. &value_local,
  2368. &LocalOrImmediate::Immediate(imm32 as i32),
  2369. );
  2370. ctx.builder.free_local(value_local);
  2371. }
  2372. pub fn instr32_69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm32: u32) {
  2373. gen_imul3_reg32(
  2374. ctx.builder,
  2375. &ctx.register_locals[r2 as usize],
  2376. &ctx.register_locals[r1 as usize],
  2377. &LocalOrImmediate::Immediate(imm32 as i32),
  2378. );
  2379. }
  2380. pub fn instr16_6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8s: u32) {
  2381. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  2382. ctx.builder.const_i32(imm8s as i32);
  2383. ctx.builder.call_fn2_ret("imul_reg16");
  2384. codegen::gen_set_reg16(ctx, r);
  2385. }
  2386. pub fn instr16_6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8s: u32) {
  2387. codegen::gen_get_reg16(ctx, r1);
  2388. ctx.builder.const_i32(imm8s as i32);
  2389. ctx.builder.call_fn2_ret("imul_reg16");
  2390. codegen::gen_set_reg16(ctx, r2);
  2391. }
  2392. pub fn instr32_6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8s: u32) {
  2393. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  2394. let value_local = ctx.builder.set_new_local();
  2395. gen_imul3_reg32(
  2396. ctx.builder,
  2397. &ctx.register_locals[r as usize],
  2398. &value_local,
  2399. &LocalOrImmediate::Immediate(imm8s as i32),
  2400. );
  2401. ctx.builder.free_local(value_local);
  2402. }
  2403. pub fn instr32_6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8s: u32) {
  2404. gen_imul3_reg32(
  2405. ctx.builder,
  2406. &ctx.register_locals[r2 as usize],
  2407. &ctx.register_locals[r1 as usize],
  2408. &LocalOrImmediate::Immediate(imm8s as i32),
  2409. );
  2410. }
  2411. // Code for conditional jumps is generated automatically by the basic block codegen
  2412. pub fn instr16_70_jit(_ctx: &mut JitContext, _imm: u32) {}
  2413. pub fn instr32_70_jit(_ctx: &mut JitContext, _imm: u32) {}
  2414. pub fn instr16_71_jit(_ctx: &mut JitContext, _imm: u32) {}
  2415. pub fn instr32_71_jit(_ctx: &mut JitContext, _imm: u32) {}
  2416. pub fn instr16_72_jit(_ctx: &mut JitContext, _imm: u32) {}
  2417. pub fn instr32_72_jit(_ctx: &mut JitContext, _imm: u32) {}
  2418. pub fn instr16_73_jit(_ctx: &mut JitContext, _imm: u32) {}
  2419. pub fn instr32_73_jit(_ctx: &mut JitContext, _imm: u32) {}
  2420. pub fn instr16_74_jit(_ctx: &mut JitContext, _imm: u32) {}
  2421. pub fn instr32_74_jit(_ctx: &mut JitContext, _imm: u32) {}
  2422. pub fn instr16_75_jit(_ctx: &mut JitContext, _imm: u32) {}
  2423. pub fn instr32_75_jit(_ctx: &mut JitContext, _imm: u32) {}
  2424. pub fn instr16_76_jit(_ctx: &mut JitContext, _imm: u32) {}
  2425. pub fn instr32_76_jit(_ctx: &mut JitContext, _imm: u32) {}
  2426. pub fn instr16_77_jit(_ctx: &mut JitContext, _imm: u32) {}
  2427. pub fn instr32_77_jit(_ctx: &mut JitContext, _imm: u32) {}
  2428. pub fn instr16_78_jit(_ctx: &mut JitContext, _imm: u32) {}
  2429. pub fn instr32_78_jit(_ctx: &mut JitContext, _imm: u32) {}
  2430. pub fn instr16_79_jit(_ctx: &mut JitContext, _imm: u32) {}
  2431. pub fn instr32_79_jit(_ctx: &mut JitContext, _imm: u32) {}
  2432. pub fn instr16_7A_jit(_ctx: &mut JitContext, _imm: u32) {}
  2433. pub fn instr32_7A_jit(_ctx: &mut JitContext, _imm: u32) {}
  2434. pub fn instr16_7B_jit(_ctx: &mut JitContext, _imm: u32) {}
  2435. pub fn instr32_7B_jit(_ctx: &mut JitContext, _imm: u32) {}
  2436. pub fn instr16_7C_jit(_ctx: &mut JitContext, _imm: u32) {}
  2437. pub fn instr32_7C_jit(_ctx: &mut JitContext, _imm: u32) {}
  2438. pub fn instr16_7D_jit(_ctx: &mut JitContext, _imm: u32) {}
  2439. pub fn instr32_7D_jit(_ctx: &mut JitContext, _imm: u32) {}
  2440. pub fn instr16_7E_jit(_ctx: &mut JitContext, _imm: u32) {}
  2441. pub fn instr32_7E_jit(_ctx: &mut JitContext, _imm: u32) {}
  2442. pub fn instr16_7F_jit(_ctx: &mut JitContext, _imm: u32) {}
  2443. pub fn instr32_7F_jit(_ctx: &mut JitContext, _imm: u32) {}
  2444. // loop/loopz/loopnz/jcxz: Conditional jump is generated in main loop
  2445. pub fn instr16_E0_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2446. pub fn instr32_E0_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2447. pub fn instr16_E1_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2448. pub fn instr32_E1_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2449. pub fn instr16_E2_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2450. pub fn instr32_E2_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2451. pub fn instr16_E3_jit(_ctx: &mut JitContext, _imm: u32) {}
  2452. pub fn instr32_E3_jit(_ctx: &mut JitContext, _imm: u32) {}
  2453. define_instruction_read_write_mem8!(gen_add8, instr_80_0_mem_jit, instr_80_0_reg_jit, ximm8);
  2454. define_instruction_read_write_mem8!(gen_or8, instr_80_1_mem_jit, instr_80_1_reg_jit, ximm8);
  2455. define_instruction_read_write_mem8!(gen_adc8, instr_80_2_mem_jit, instr_80_2_reg_jit, ximm8);
  2456. define_instruction_read_write_mem8!(gen_sbb8, instr_80_3_mem_jit, instr_80_3_reg_jit, ximm8);
  2457. define_instruction_read_write_mem8!(gen_and8, instr_80_4_mem_jit, instr_80_4_reg_jit, ximm8);
  2458. define_instruction_read_write_mem8!(gen_sub8, instr_80_5_mem_jit, instr_80_5_reg_jit, ximm8);
  2459. define_instruction_read_write_mem8!(gen_xor8, instr_80_6_mem_jit, instr_80_6_reg_jit, ximm8);
  2460. define_instruction_read_write_mem8!(gen_add8, instr_82_0_mem_jit, instr_82_0_reg_jit, ximm8);
  2461. define_instruction_read_write_mem8!(gen_or8, instr_82_1_mem_jit, instr_82_1_reg_jit, ximm8);
  2462. define_instruction_read_write_mem8!(gen_adc8, instr_82_2_mem_jit, instr_82_2_reg_jit, ximm8);
  2463. define_instruction_read_write_mem8!(gen_sbb8, instr_82_3_mem_jit, instr_82_3_reg_jit, ximm8);
  2464. define_instruction_read_write_mem8!(gen_and8, instr_82_4_mem_jit, instr_82_4_reg_jit, ximm8);
  2465. define_instruction_read_write_mem8!(gen_sub8, instr_82_5_mem_jit, instr_82_5_reg_jit, ximm8);
  2466. define_instruction_read_write_mem8!(gen_xor8, instr_82_6_mem_jit, instr_82_6_reg_jit, ximm8);
  2467. define_instruction_read_write_mem16!("add16", instr16_81_0_mem_jit, instr16_81_0_reg_jit, imm16);
  2468. define_instruction_read_write_mem32!(gen_add32, instr32_81_0_mem_jit, instr32_81_0_reg_jit, imm32);
  2469. define_instruction_read_write_mem16!("or16", instr16_81_1_mem_jit, instr16_81_1_reg_jit, imm16);
  2470. define_instruction_read_write_mem32!(gen_or32, instr32_81_1_mem_jit, instr32_81_1_reg_jit, imm32);
  2471. define_instruction_read_write_mem16!("adc16", instr16_81_2_mem_jit, instr16_81_2_reg_jit, imm16);
  2472. define_instruction_read_write_mem32!(gen_adc32, instr32_81_2_mem_jit, instr32_81_2_reg_jit, imm32);
  2473. define_instruction_read_write_mem16!("sbb16", instr16_81_3_mem_jit, instr16_81_3_reg_jit, imm16);
  2474. define_instruction_read_write_mem32!(gen_sbb32, instr32_81_3_mem_jit, instr32_81_3_reg_jit, imm32);
  2475. define_instruction_read_write_mem16!("and16", instr16_81_4_mem_jit, instr16_81_4_reg_jit, imm16);
  2476. define_instruction_read_write_mem32!(gen_and32, instr32_81_4_mem_jit, instr32_81_4_reg_jit, imm32);
  2477. define_instruction_read_write_mem16!("sub16", instr16_81_5_mem_jit, instr16_81_5_reg_jit, imm16);
  2478. define_instruction_read_write_mem32!(gen_sub32, instr32_81_5_mem_jit, instr32_81_5_reg_jit, imm32);
  2479. define_instruction_read_write_mem16!("xor16", instr16_81_6_mem_jit, instr16_81_6_reg_jit, imm16);
  2480. define_instruction_read_write_mem32!(gen_xor32, instr32_81_6_mem_jit, instr32_81_6_reg_jit, imm32);
  2481. define_instruction_read_write_mem16!(
  2482. "add16",
  2483. instr16_83_0_mem_jit,
  2484. instr16_83_0_reg_jit,
  2485. imm8s_16bits
  2486. );
  2487. define_instruction_read_write_mem32!(gen_add32, instr32_83_0_mem_jit, instr32_83_0_reg_jit, imm8s);
  2488. define_instruction_read_write_mem16!(
  2489. "or16",
  2490. instr16_83_1_mem_jit,
  2491. instr16_83_1_reg_jit,
  2492. imm8s_16bits
  2493. );
  2494. define_instruction_read_write_mem32!(gen_or32, instr32_83_1_mem_jit, instr32_83_1_reg_jit, imm8s);
  2495. define_instruction_read_write_mem16!(
  2496. "adc16",
  2497. instr16_83_2_mem_jit,
  2498. instr16_83_2_reg_jit,
  2499. imm8s_16bits
  2500. );
  2501. define_instruction_read_write_mem32!(gen_adc32, instr32_83_2_mem_jit, instr32_83_2_reg_jit, imm8s);
  2502. define_instruction_read_write_mem16!(
  2503. "sbb16",
  2504. instr16_83_3_mem_jit,
  2505. instr16_83_3_reg_jit,
  2506. imm8s_16bits
  2507. );
  2508. define_instruction_read_write_mem32!(gen_sbb32, instr32_83_3_mem_jit, instr32_83_3_reg_jit, imm8s);
  2509. define_instruction_read_write_mem16!(
  2510. "and16",
  2511. instr16_83_4_mem_jit,
  2512. instr16_83_4_reg_jit,
  2513. imm8s_16bits
  2514. );
  2515. define_instruction_read_write_mem32!(gen_and32, instr32_83_4_mem_jit, instr32_83_4_reg_jit, imm8s);
  2516. define_instruction_read_write_mem16!(
  2517. "sub16",
  2518. instr16_83_5_mem_jit,
  2519. instr16_83_5_reg_jit,
  2520. imm8s_16bits
  2521. );
  2522. define_instruction_read_write_mem32!(gen_sub32, instr32_83_5_mem_jit, instr32_83_5_reg_jit, imm8s);
  2523. define_instruction_read_write_mem16!(
  2524. "xor16",
  2525. instr16_83_6_mem_jit,
  2526. instr16_83_6_reg_jit,
  2527. imm8s_16bits
  2528. );
  2529. define_instruction_read_write_mem32!(gen_xor32, instr32_83_6_mem_jit, instr32_83_6_reg_jit, imm8s);
  2530. define_instruction_read8!(gen_cmp8, instr_80_7_mem_jit, instr_80_7_reg_jit, imm8);
  2531. define_instruction_read16!(gen_cmp16, instr16_81_7_mem_jit, instr16_81_7_reg_jit, imm16);
  2532. define_instruction_read32!(gen_cmp32, instr32_81_7_mem_jit, instr32_81_7_reg_jit, imm32);
  2533. define_instruction_read8!(gen_cmp8, instr_82_7_mem_jit, instr_82_7_reg_jit, imm8);
  2534. define_instruction_read16!(
  2535. gen_cmp16,
  2536. instr16_83_7_mem_jit,
  2537. instr16_83_7_reg_jit,
  2538. imm8s_16bits
  2539. );
  2540. define_instruction_read32!(gen_cmp32, instr32_83_7_mem_jit, instr32_83_7_reg_jit, imm8s);
  2541. define_instruction_read8!(gen_test8, instr_84_mem_jit, instr_84_reg_jit);
  2542. define_instruction_read16!(gen_test16, instr16_85_mem_jit, instr16_85_reg_jit);
  2543. define_instruction_read32!(gen_test32, instr32_85_mem_jit, instr32_85_reg_jit);
  2544. pub fn instr_86_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2545. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  2546. codegen::gen_safe_read_write(ctx, BitSize::BYTE, &addr, &|ref mut ctx| {
  2547. codegen::gen_get_reg8(ctx, r);
  2548. let tmp = ctx.builder.set_new_local();
  2549. codegen::gen_set_reg8(ctx, r);
  2550. ctx.builder.get_local(&tmp);
  2551. ctx.builder.free_local(tmp);
  2552. });
  2553. });
  2554. }
  2555. pub fn instr_86_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2556. codegen::gen_get_reg8(ctx, r2);
  2557. let tmp = ctx.builder.set_new_local();
  2558. codegen::gen_get_reg8(ctx, r1);
  2559. codegen::gen_set_reg8(ctx, r2);
  2560. ctx.builder.get_local(&tmp);
  2561. codegen::gen_set_reg8(ctx, r1);
  2562. ctx.builder.free_local(tmp);
  2563. }
  2564. pub fn instr16_87_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2565. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  2566. codegen::gen_safe_read_write(ctx, BitSize::WORD, &addr, &|ref mut ctx| {
  2567. codegen::gen_get_reg16(ctx, r);
  2568. let tmp = ctx.builder.set_new_local();
  2569. codegen::gen_set_reg16(ctx, r);
  2570. ctx.builder.get_local(&tmp);
  2571. ctx.builder.free_local(tmp);
  2572. });
  2573. });
  2574. }
  2575. pub fn instr32_87_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2576. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  2577. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &addr, &|ref mut ctx| {
  2578. codegen::gen_get_reg32(ctx, r);
  2579. let tmp = ctx.builder.set_new_local();
  2580. codegen::gen_set_reg32(ctx, r);
  2581. ctx.builder.get_local(&tmp);
  2582. ctx.builder.free_local(tmp);
  2583. });
  2584. });
  2585. }
  2586. pub fn instr16_87_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2587. codegen::gen_get_reg16(ctx, r2);
  2588. let tmp = ctx.builder.set_new_local();
  2589. codegen::gen_get_reg16(ctx, r1);
  2590. codegen::gen_set_reg16(ctx, r2);
  2591. ctx.builder.get_local(&tmp);
  2592. codegen::gen_set_reg16(ctx, r1);
  2593. ctx.builder.free_local(tmp);
  2594. }
  2595. pub fn instr32_87_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2596. codegen::gen_get_reg32(ctx, r2);
  2597. let tmp = ctx.builder.set_new_local();
  2598. codegen::gen_get_reg32(ctx, r1);
  2599. codegen::gen_set_reg32(ctx, r2);
  2600. ctx.builder.get_local(&tmp);
  2601. codegen::gen_set_reg32(ctx, r1);
  2602. ctx.builder.free_local(tmp);
  2603. }
  2604. pub fn instr_88_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2605. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  2606. codegen::gen_get_reg8(ctx, r);
  2607. let value_local = ctx.builder.set_new_local();
  2608. codegen::gen_safe_write8(ctx, &addr, &value_local);
  2609. ctx.builder.free_local(value_local);
  2610. });
  2611. }
  2612. pub fn instr_88_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2613. codegen::gen_set_reg8_r(ctx, r1, r2);
  2614. }
  2615. pub fn instr16_89_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2616. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  2617. codegen::gen_safe_write16(ctx, addr, &ctx.reg(r));
  2618. });
  2619. }
  2620. pub fn instr16_89_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2621. codegen::gen_set_reg16_r(ctx, r1, r2);
  2622. }
  2623. pub fn instr32_89_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2624. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  2625. codegen::gen_safe_write32(ctx, &addr, &ctx.reg(r));
  2626. });
  2627. }
  2628. pub fn instr32_89_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2629. codegen::gen_set_reg32_r(ctx, r1, r2);
  2630. }
  2631. pub fn instr_8A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2632. // Pseudo: reg8[r] = safe_read8(modrm_resolve(modrm_byte));
  2633. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
  2634. codegen::gen_set_reg8_unmasked(ctx, r);
  2635. }
  2636. pub fn instr_8A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2637. codegen::gen_set_reg8_r(ctx, r2, r1);
  2638. }
  2639. pub fn instr16_8B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2640. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  2641. codegen::gen_set_reg16_unmasked(ctx, r);
  2642. }
  2643. pub fn instr16_8B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2644. codegen::gen_set_reg16_r(ctx, r2, r1);
  2645. }
  2646. pub fn instr32_8B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2647. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  2648. codegen::gen_set_reg32(ctx, r);
  2649. }
  2650. pub fn instr32_8B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2651. codegen::gen_set_reg32_r(ctx, r2, r1);
  2652. }
  2653. pub fn instr16_8C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2654. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2655. let address_local = ctx.builder.set_new_local();
  2656. if r >= 6 {
  2657. codegen::gen_trigger_ud(ctx);
  2658. }
  2659. else {
  2660. codegen::gen_get_sreg(ctx, r);
  2661. let value_local = ctx.builder.set_new_local();
  2662. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  2663. ctx.builder.free_local(value_local);
  2664. }
  2665. ctx.builder.free_local(address_local);
  2666. }
  2667. pub fn instr32_8C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2668. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2669. let address_local = ctx.builder.set_new_local();
  2670. if r >= 6 {
  2671. codegen::gen_trigger_ud(ctx);
  2672. }
  2673. else {
  2674. codegen::gen_get_sreg(ctx, r);
  2675. let value_local = ctx.builder.set_new_local();
  2676. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  2677. ctx.builder.free_local(value_local);
  2678. }
  2679. ctx.builder.free_local(address_local);
  2680. }
  2681. pub fn instr16_8C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2682. if r2 >= 6 {
  2683. codegen::gen_trigger_ud(ctx);
  2684. }
  2685. else {
  2686. codegen::gen_get_sreg(ctx, r2);
  2687. codegen::gen_set_reg16(ctx, r1);
  2688. }
  2689. }
  2690. pub fn instr32_8C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2691. if r2 >= 6 {
  2692. codegen::gen_trigger_ud(ctx);
  2693. }
  2694. else {
  2695. codegen::gen_get_sreg(ctx, r2);
  2696. codegen::gen_set_reg32(ctx, r1);
  2697. }
  2698. }
  2699. pub fn instr16_8D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, reg: u32) {
  2700. ctx.cpu.prefixes |= SEG_PREFIX_ZERO;
  2701. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2702. codegen::gen_set_reg16(ctx, reg);
  2703. }
  2704. pub fn instr32_8D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, reg: u32) {
  2705. if !modrm_byte.is_nop(reg) {
  2706. ctx.cpu.prefixes |= SEG_PREFIX_ZERO;
  2707. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2708. codegen::gen_set_reg32(ctx, reg);
  2709. }
  2710. }
  2711. pub fn instr16_8D_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  2712. codegen::gen_trigger_ud(ctx);
  2713. }
  2714. pub fn instr32_8D_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  2715. codegen::gen_trigger_ud(ctx);
  2716. }
  2717. pub fn instr16_8F_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  2718. // before gen_modrm_resolve, update esp to the new value
  2719. codegen::gen_adjust_stack_reg(ctx, 2);
  2720. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2721. let address_local = ctx.builder.set_new_local();
  2722. // pop takes care of updating esp, so undo the previous change
  2723. codegen::gen_adjust_stack_reg(ctx, (-2i32) as u32);
  2724. codegen::gen_pop16(ctx);
  2725. let value_local = ctx.builder.set_new_local();
  2726. // undo the esp change of pop, as safe_write16 can fail
  2727. codegen::gen_adjust_stack_reg(ctx, (-2i32) as u32);
  2728. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  2729. ctx.builder.free_local(address_local);
  2730. ctx.builder.free_local(value_local);
  2731. // finally, actually update esp
  2732. codegen::gen_adjust_stack_reg(ctx, 2);
  2733. }
  2734. pub fn instr16_8F_0_reg_jit(ctx: &mut JitContext, r: u32) { pop16_reg_jit(ctx, r); }
  2735. pub fn instr32_8F_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  2736. codegen::gen_adjust_stack_reg(ctx, 4);
  2737. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2738. let address_local = ctx.builder.set_new_local();
  2739. codegen::gen_adjust_stack_reg(ctx, (-4i32) as u32);
  2740. codegen::gen_pop32s(ctx);
  2741. let value_local = ctx.builder.set_new_local();
  2742. codegen::gen_adjust_stack_reg(ctx, (-4i32) as u32);
  2743. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  2744. ctx.builder.free_local(address_local);
  2745. ctx.builder.free_local(value_local);
  2746. codegen::gen_adjust_stack_reg(ctx, 4);
  2747. }
  2748. pub fn instr32_8F_0_reg_jit(ctx: &mut JitContext, r: u32) { pop32_reg_jit(ctx, r); }
  2749. define_instruction_read_write_mem16!(
  2750. "rol16",
  2751. instr16_C1_0_mem_jit,
  2752. instr16_C1_0_reg_jit,
  2753. imm8_5bits
  2754. );
  2755. define_instruction_read_write_mem32!(
  2756. gen_rol32,
  2757. instr32_C1_0_mem_jit,
  2758. instr32_C1_0_reg_jit,
  2759. imm8_5bits
  2760. );
  2761. define_instruction_read_write_mem16!(
  2762. "ror16",
  2763. instr16_C1_1_mem_jit,
  2764. instr16_C1_1_reg_jit,
  2765. imm8_5bits
  2766. );
  2767. define_instruction_read_write_mem32!(
  2768. gen_ror32,
  2769. instr32_C1_1_mem_jit,
  2770. instr32_C1_1_reg_jit,
  2771. imm8_5bits
  2772. );
  2773. define_instruction_read_write_mem16!(
  2774. "rcl16",
  2775. instr16_C1_2_mem_jit,
  2776. instr16_C1_2_reg_jit,
  2777. imm8_5bits
  2778. );
  2779. define_instruction_read_write_mem32!(
  2780. gen_rcl32,
  2781. instr32_C1_2_mem_jit,
  2782. instr32_C1_2_reg_jit,
  2783. imm8_5bits
  2784. );
  2785. define_instruction_read_write_mem16!(
  2786. "rcr16",
  2787. instr16_C1_3_mem_jit,
  2788. instr16_C1_3_reg_jit,
  2789. imm8_5bits
  2790. );
  2791. define_instruction_read_write_mem32!(
  2792. gen_rcr32,
  2793. instr32_C1_3_mem_jit,
  2794. instr32_C1_3_reg_jit,
  2795. imm8_5bits
  2796. );
  2797. define_instruction_read_write_mem16!(
  2798. "shl16",
  2799. instr16_C1_4_mem_jit,
  2800. instr16_C1_4_reg_jit,
  2801. imm8_5bits
  2802. );
  2803. define_instruction_read_write_mem32!(
  2804. gen_shl32,
  2805. instr32_C1_4_mem_jit,
  2806. instr32_C1_4_reg_jit,
  2807. imm8_5bits
  2808. );
  2809. define_instruction_read_write_mem16!(
  2810. "shr16",
  2811. instr16_C1_5_mem_jit,
  2812. instr16_C1_5_reg_jit,
  2813. imm8_5bits
  2814. );
  2815. define_instruction_read_write_mem32!(
  2816. gen_shr32,
  2817. instr32_C1_5_mem_jit,
  2818. instr32_C1_5_reg_jit,
  2819. imm8_5bits
  2820. );
  2821. define_instruction_read_write_mem16!(
  2822. "shl16",
  2823. instr16_C1_6_mem_jit,
  2824. instr16_C1_6_reg_jit,
  2825. imm8_5bits
  2826. );
  2827. define_instruction_read_write_mem32!(
  2828. gen_shl32,
  2829. instr32_C1_6_mem_jit,
  2830. instr32_C1_6_reg_jit,
  2831. imm8_5bits
  2832. );
  2833. define_instruction_read_write_mem16!(
  2834. "sar16",
  2835. instr16_C1_7_mem_jit,
  2836. instr16_C1_7_reg_jit,
  2837. imm8_5bits
  2838. );
  2839. define_instruction_read_write_mem32!(
  2840. gen_sar32,
  2841. instr32_C1_7_mem_jit,
  2842. instr32_C1_7_reg_jit,
  2843. imm8_5bits
  2844. );
  2845. pub fn instr16_E8_jit(ctx: &mut JitContext, _imm: u32) {
  2846. codegen::gen_get_real_eip(ctx);
  2847. let value_local = ctx.builder.set_new_local();
  2848. codegen::gen_push16(ctx, &value_local);
  2849. ctx.builder.free_local(value_local);
  2850. }
  2851. pub fn instr32_E8_jit(ctx: &mut JitContext, _imm: u32) {
  2852. codegen::gen_get_real_eip(ctx);
  2853. let value_local = ctx.builder.set_new_local();
  2854. codegen::gen_push32(ctx, &value_local);
  2855. ctx.builder.free_local(value_local);
  2856. }
  2857. pub fn instr16_E9_jit(_ctx: &mut JitContext, _imm: u32) {
  2858. //
  2859. }
  2860. pub fn instr32_E9_jit(_ctx: &mut JitContext, _imm: u32) {
  2861. //
  2862. }
  2863. pub fn instr16_C2_jit(ctx: &mut JitContext, imm16: u32) {
  2864. ctx.builder.const_i32(0);
  2865. codegen::gen_pop16(ctx);
  2866. codegen::gen_add_cs_offset(ctx);
  2867. ctx.builder
  2868. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  2869. codegen::gen_adjust_stack_reg(ctx, imm16);
  2870. }
  2871. pub fn instr32_C2_jit(ctx: &mut JitContext, imm16: u32) {
  2872. ctx.builder.const_i32(0);
  2873. codegen::gen_pop32s(ctx);
  2874. codegen::gen_add_cs_offset(ctx);
  2875. ctx.builder
  2876. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  2877. codegen::gen_adjust_stack_reg(ctx, imm16);
  2878. }
  2879. pub fn instr16_C3_jit(ctx: &mut JitContext) {
  2880. ctx.builder.const_i32(0);
  2881. codegen::gen_pop16(ctx);
  2882. codegen::gen_add_cs_offset(ctx);
  2883. ctx.builder
  2884. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  2885. }
  2886. pub fn instr32_C3_jit(ctx: &mut JitContext) {
  2887. ctx.builder.const_i32(0);
  2888. codegen::gen_pop32s(ctx);
  2889. codegen::gen_add_cs_offset(ctx);
  2890. ctx.builder
  2891. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  2892. }
  2893. pub fn instr16_C9_jit(ctx: &mut JitContext) { codegen::gen_leave(ctx, false); }
  2894. pub fn instr32_C9_jit(ctx: &mut JitContext) { codegen::gen_leave(ctx, true); }
  2895. pub fn gen_mov_reg8_imm(ctx: &mut JitContext, r: u32, imm: u32) {
  2896. ctx.builder.const_i32(imm as i32);
  2897. codegen::gen_set_reg8_unmasked(ctx, r);
  2898. }
  2899. pub fn instr_B0_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 0, imm) }
  2900. pub fn instr_B1_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 1, imm) }
  2901. pub fn instr_B2_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 2, imm) }
  2902. pub fn instr_B3_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 3, imm) }
  2903. pub fn instr_B4_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 4, imm) }
  2904. pub fn instr_B5_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 5, imm) }
  2905. pub fn instr_B6_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 6, imm) }
  2906. pub fn instr_B7_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 7, imm) }
  2907. pub fn gen_mov_reg16_imm(ctx: &mut JitContext, r: u32, imm: u32) {
  2908. ctx.builder.const_i32(imm as i32);
  2909. codegen::gen_set_reg16_unmasked(ctx, r);
  2910. }
  2911. pub fn instr16_B8_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 0, imm) }
  2912. pub fn instr16_B9_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 1, imm) }
  2913. pub fn instr16_BA_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 2, imm) }
  2914. pub fn instr16_BB_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 3, imm) }
  2915. pub fn instr16_BC_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 4, imm) }
  2916. pub fn instr16_BD_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 5, imm) }
  2917. pub fn instr16_BE_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 6, imm) }
  2918. pub fn instr16_BF_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 7, imm) }
  2919. pub fn gen_mov_reg32_imm(ctx: &mut JitContext, r: u32, imm: u32) {
  2920. ctx.builder.const_i32(imm as i32);
  2921. codegen::gen_set_reg32(ctx, r);
  2922. }
  2923. pub fn instr32_B8_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 0, imm) }
  2924. pub fn instr32_B9_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 1, imm) }
  2925. pub fn instr32_BA_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 2, imm) }
  2926. pub fn instr32_BB_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 3, imm) }
  2927. pub fn instr32_BC_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 4, imm) }
  2928. pub fn instr32_BD_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 5, imm) }
  2929. pub fn instr32_BE_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 6, imm) }
  2930. pub fn instr32_BF_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 7, imm) }
  2931. define_instruction_read_write_mem8!("rol8", instr_C0_0_mem_jit, instr_C0_0_reg_jit, imm8_5bits);
  2932. define_instruction_read_write_mem8!("ror8", instr_C0_1_mem_jit, instr_C0_1_reg_jit, imm8_5bits);
  2933. define_instruction_read_write_mem8!("rcl8", instr_C0_2_mem_jit, instr_C0_2_reg_jit, imm8_5bits);
  2934. define_instruction_read_write_mem8!("rcr8", instr_C0_3_mem_jit, instr_C0_3_reg_jit, imm8_5bits);
  2935. define_instruction_read_write_mem8!("shl8", instr_C0_4_mem_jit, instr_C0_4_reg_jit, imm8_5bits);
  2936. define_instruction_read_write_mem8!("shr8", instr_C0_5_mem_jit, instr_C0_5_reg_jit, imm8_5bits);
  2937. define_instruction_read_write_mem8!("shl8", instr_C0_6_mem_jit, instr_C0_6_reg_jit, imm8_5bits);
  2938. define_instruction_read_write_mem8!("sar8", instr_C0_7_mem_jit, instr_C0_7_reg_jit, imm8_5bits);
  2939. define_instruction_read_write_mem8!("rol8", instr_D0_0_mem_jit, instr_D0_0_reg_jit, constant_one);
  2940. define_instruction_read_write_mem8!("ror8", instr_D0_1_mem_jit, instr_D0_1_reg_jit, constant_one);
  2941. define_instruction_read_write_mem8!("rcl8", instr_D0_2_mem_jit, instr_D0_2_reg_jit, constant_one);
  2942. define_instruction_read_write_mem8!("rcr8", instr_D0_3_mem_jit, instr_D0_3_reg_jit, constant_one);
  2943. define_instruction_read_write_mem8!("shl8", instr_D0_4_mem_jit, instr_D0_4_reg_jit, constant_one);
  2944. define_instruction_read_write_mem8!("shr8", instr_D0_5_mem_jit, instr_D0_5_reg_jit, constant_one);
  2945. define_instruction_read_write_mem8!("shl8", instr_D0_6_mem_jit, instr_D0_6_reg_jit, constant_one);
  2946. define_instruction_read_write_mem8!("sar8", instr_D0_7_mem_jit, instr_D0_7_reg_jit, constant_one);
  2947. define_instruction_read_write_mem16!(
  2948. "rol16",
  2949. instr16_D1_0_mem_jit,
  2950. instr16_D1_0_reg_jit,
  2951. constant_one
  2952. );
  2953. define_instruction_read_write_mem32!(
  2954. gen_rol32,
  2955. instr32_D1_0_mem_jit,
  2956. instr32_D1_0_reg_jit,
  2957. constant_one
  2958. );
  2959. define_instruction_read_write_mem16!(
  2960. "ror16",
  2961. instr16_D1_1_mem_jit,
  2962. instr16_D1_1_reg_jit,
  2963. constant_one
  2964. );
  2965. define_instruction_read_write_mem32!(
  2966. gen_ror32,
  2967. instr32_D1_1_mem_jit,
  2968. instr32_D1_1_reg_jit,
  2969. constant_one
  2970. );
  2971. define_instruction_read_write_mem16!(
  2972. "rcl16",
  2973. instr16_D1_2_mem_jit,
  2974. instr16_D1_2_reg_jit,
  2975. constant_one
  2976. );
  2977. define_instruction_read_write_mem32!(
  2978. gen_rcl32,
  2979. instr32_D1_2_mem_jit,
  2980. instr32_D1_2_reg_jit,
  2981. constant_one
  2982. );
  2983. define_instruction_read_write_mem16!(
  2984. "rcr16",
  2985. instr16_D1_3_mem_jit,
  2986. instr16_D1_3_reg_jit,
  2987. constant_one
  2988. );
  2989. define_instruction_read_write_mem32!(
  2990. gen_rcr32,
  2991. instr32_D1_3_mem_jit,
  2992. instr32_D1_3_reg_jit,
  2993. constant_one
  2994. );
  2995. define_instruction_read_write_mem16!(
  2996. "shl16",
  2997. instr16_D1_4_mem_jit,
  2998. instr16_D1_4_reg_jit,
  2999. constant_one
  3000. );
  3001. define_instruction_read_write_mem32!(
  3002. gen_shl32,
  3003. instr32_D1_4_mem_jit,
  3004. instr32_D1_4_reg_jit,
  3005. constant_one
  3006. );
  3007. define_instruction_read_write_mem16!(
  3008. "shr16",
  3009. instr16_D1_5_mem_jit,
  3010. instr16_D1_5_reg_jit,
  3011. constant_one
  3012. );
  3013. define_instruction_read_write_mem32!(
  3014. gen_shr32,
  3015. instr32_D1_5_mem_jit,
  3016. instr32_D1_5_reg_jit,
  3017. constant_one
  3018. );
  3019. define_instruction_read_write_mem16!(
  3020. "shl16",
  3021. instr16_D1_6_mem_jit,
  3022. instr16_D1_6_reg_jit,
  3023. constant_one
  3024. );
  3025. define_instruction_read_write_mem32!(
  3026. gen_shl32,
  3027. instr32_D1_6_mem_jit,
  3028. instr32_D1_6_reg_jit,
  3029. constant_one
  3030. );
  3031. define_instruction_read_write_mem16!(
  3032. "sar16",
  3033. instr16_D1_7_mem_jit,
  3034. instr16_D1_7_reg_jit,
  3035. constant_one
  3036. );
  3037. define_instruction_read_write_mem32!(
  3038. gen_sar32,
  3039. instr32_D1_7_mem_jit,
  3040. instr32_D1_7_reg_jit,
  3041. constant_one
  3042. );
  3043. define_instruction_read_write_mem8!("rol8", instr_D2_0_mem_jit, instr_D2_0_reg_jit, cl);
  3044. define_instruction_read_write_mem8!("ror8", instr_D2_1_mem_jit, instr_D2_1_reg_jit, cl);
  3045. define_instruction_read_write_mem8!("rcl8", instr_D2_2_mem_jit, instr_D2_2_reg_jit, cl);
  3046. define_instruction_read_write_mem8!("rcr8", instr_D2_3_mem_jit, instr_D2_3_reg_jit, cl);
  3047. define_instruction_read_write_mem8!("shl8", instr_D2_4_mem_jit, instr_D2_4_reg_jit, cl);
  3048. define_instruction_read_write_mem8!("shr8", instr_D2_5_mem_jit, instr_D2_5_reg_jit, cl);
  3049. define_instruction_read_write_mem8!("shl8", instr_D2_6_mem_jit, instr_D2_6_reg_jit, cl);
  3050. define_instruction_read_write_mem8!("sar8", instr_D2_7_mem_jit, instr_D2_7_reg_jit, cl);
  3051. define_instruction_read_write_mem16!("rol16", instr16_D3_0_mem_jit, instr16_D3_0_reg_jit, cl);
  3052. define_instruction_read_write_mem32!(gen_rol32, instr32_D3_0_mem_jit, instr32_D3_0_reg_jit, cl);
  3053. define_instruction_read_write_mem16!("ror16", instr16_D3_1_mem_jit, instr16_D3_1_reg_jit, cl);
  3054. define_instruction_read_write_mem32!(gen_ror32, instr32_D3_1_mem_jit, instr32_D3_1_reg_jit, cl);
  3055. define_instruction_read_write_mem16!("rcl16", instr16_D3_2_mem_jit, instr16_D3_2_reg_jit, cl);
  3056. define_instruction_read_write_mem32!(gen_rcl32, instr32_D3_2_mem_jit, instr32_D3_2_reg_jit, cl);
  3057. define_instruction_read_write_mem16!("rcr16", instr16_D3_3_mem_jit, instr16_D3_3_reg_jit, cl);
  3058. define_instruction_read_write_mem32!(gen_rcr32, instr32_D3_3_mem_jit, instr32_D3_3_reg_jit, cl);
  3059. define_instruction_read_write_mem16!("shl16", instr16_D3_4_mem_jit, instr16_D3_4_reg_jit, cl);
  3060. define_instruction_read_write_mem32!(gen_shl32, instr32_D3_4_mem_jit, instr32_D3_4_reg_jit, cl);
  3061. define_instruction_read_write_mem16!("shr16", instr16_D3_5_mem_jit, instr16_D3_5_reg_jit, cl);
  3062. define_instruction_read_write_mem32!(gen_shr32, instr32_D3_5_mem_jit, instr32_D3_5_reg_jit, cl);
  3063. define_instruction_read_write_mem16!("shl16", instr16_D3_6_mem_jit, instr16_D3_6_reg_jit, cl);
  3064. define_instruction_read_write_mem32!(gen_shl32, instr32_D3_6_mem_jit, instr32_D3_6_reg_jit, cl);
  3065. define_instruction_read_write_mem16!("sar16", instr16_D3_7_mem_jit, instr16_D3_7_reg_jit, cl);
  3066. define_instruction_read_write_mem32!(gen_sar32, instr32_D3_7_mem_jit, instr32_D3_7_reg_jit, cl);
  3067. pub fn instr_D7_jit(ctx: &mut JitContext) {
  3068. if ctx.cpu.asize_32() {
  3069. codegen::gen_get_reg32(ctx, regs::EBX);
  3070. }
  3071. else {
  3072. codegen::gen_get_reg16(ctx, regs::BX);
  3073. }
  3074. codegen::gen_get_reg8(ctx, regs::AL);
  3075. ctx.builder.add_i32();
  3076. if !ctx.cpu.asize_32() {
  3077. ctx.builder.const_i32(0xFFFF);
  3078. ctx.builder.and_i32();
  3079. }
  3080. jit_add_seg_offset(ctx, regs::DS);
  3081. let address_local = ctx.builder.set_new_local();
  3082. codegen::gen_safe_read8(ctx, &address_local);
  3083. ctx.builder.free_local(address_local);
  3084. codegen::gen_set_reg8(ctx, regs::AL);
  3085. }
  3086. fn instr_group_D8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) {
  3087. ctx.builder.const_i32(0);
  3088. codegen::gen_fpu_load_m32(ctx, modrm_byte);
  3089. ctx.builder.call_fn3_i32_i64_i32(op)
  3090. }
  3091. fn instr_group_D8_reg_jit(ctx: &mut JitContext, r: u32, op: &str) {
  3092. ctx.builder.const_i32(0);
  3093. codegen::gen_fpu_get_sti(ctx, r);
  3094. ctx.builder.call_fn3_i32_i64_i32(op)
  3095. }
  3096. pub fn instr_D8_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3097. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fadd")
  3098. }
  3099. pub fn instr_D8_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3100. instr_group_D8_reg_jit(ctx, r, "fpu_fadd")
  3101. }
  3102. pub fn instr_D8_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3103. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fmul")
  3104. }
  3105. pub fn instr_D8_1_reg_jit(ctx: &mut JitContext, r: u32) {
  3106. instr_group_D8_reg_jit(ctx, r, "fpu_fmul")
  3107. }
  3108. pub fn instr_D8_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3109. codegen::gen_fpu_load_m32(ctx, modrm_byte);
  3110. ctx.builder.call_fn2_i64_i32("fpu_fcom")
  3111. }
  3112. pub fn instr_D8_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3113. codegen::gen_fpu_get_sti(ctx, r);
  3114. ctx.builder.call_fn2_i64_i32("fpu_fcom")
  3115. }
  3116. pub fn instr_D8_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3117. codegen::gen_fpu_load_m32(ctx, modrm_byte);
  3118. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3119. }
  3120. pub fn instr_D8_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3121. codegen::gen_fpu_get_sti(ctx, r);
  3122. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3123. }
  3124. pub fn instr_D8_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3125. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fsub")
  3126. }
  3127. pub fn instr_D8_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3128. instr_group_D8_reg_jit(ctx, r, "fpu_fsub")
  3129. }
  3130. pub fn instr_D8_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3131. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fsubr")
  3132. }
  3133. pub fn instr_D8_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3134. instr_group_D8_reg_jit(ctx, r, "fpu_fsubr")
  3135. }
  3136. pub fn instr_D8_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3137. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fdiv")
  3138. }
  3139. pub fn instr_D8_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3140. instr_group_D8_reg_jit(ctx, r, "fpu_fdiv")
  3141. }
  3142. pub fn instr_D8_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3143. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fdivr")
  3144. }
  3145. pub fn instr_D8_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3146. instr_group_D8_reg_jit(ctx, r, "fpu_fdivr")
  3147. }
  3148. pub fn instr16_D9_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3149. codegen::gen_fpu_load_m32(ctx, modrm_byte);
  3150. ctx.builder.call_fn2_i64_i32("fpu_push");
  3151. }
  3152. pub fn instr16_D9_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3153. codegen::gen_fpu_get_sti(ctx, r);
  3154. ctx.builder.call_fn2_i64_i32("fpu_push");
  3155. }
  3156. pub fn instr32_D9_0_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_0_reg_jit(ctx, r) }
  3157. pub fn instr32_D9_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3158. instr16_D9_0_mem_jit(ctx, modrm_byte)
  3159. }
  3160. pub fn instr16_D9_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3161. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3162. codegen::gen_trigger_ud(ctx);
  3163. }
  3164. pub fn instr16_D9_1_reg_jit(ctx: &mut JitContext, r: u32) {
  3165. ctx.builder.const_i32(r as i32);
  3166. ctx.builder.call_fn1("fpu_fxch");
  3167. }
  3168. pub fn instr32_D9_1_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_1_reg_jit(ctx, r) }
  3169. pub fn instr32_D9_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3170. instr16_D9_1_mem_jit(ctx, modrm_byte)
  3171. }
  3172. pub fn instr16_D9_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3173. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3174. let address_local = ctx.builder.set_new_local();
  3175. codegen::gen_fpu_get_sti(ctx, 0);
  3176. ctx.builder.call_fn2_i64_i32_ret("f80_to_f32");
  3177. let value_local = ctx.builder.set_new_local();
  3178. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  3179. ctx.builder.free_local(address_local);
  3180. ctx.builder.free_local(value_local);
  3181. }
  3182. pub fn instr16_D9_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3183. if r != 0 {
  3184. codegen::gen_trigger_ud(ctx);
  3185. }
  3186. }
  3187. pub fn instr32_D9_2_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_2_reg_jit(ctx, r) }
  3188. pub fn instr32_D9_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3189. instr16_D9_2_mem_jit(ctx, modrm_byte)
  3190. }
  3191. pub fn instr16_D9_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3192. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3193. let address_local = ctx.builder.set_new_local();
  3194. codegen::gen_fpu_get_sti(ctx, 0);
  3195. ctx.builder.call_fn2_i64_i32_ret("f80_to_f32");
  3196. let value_local = ctx.builder.set_new_local();
  3197. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  3198. ctx.builder.free_local(address_local);
  3199. ctx.builder.free_local(value_local);
  3200. codegen::gen_fn0_const(ctx.builder, "fpu_pop");
  3201. }
  3202. pub fn instr16_D9_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3203. codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
  3204. }
  3205. pub fn instr32_D9_3_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_3_reg_jit(ctx, r) }
  3206. pub fn instr32_D9_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3207. instr16_D9_3_mem_jit(ctx, modrm_byte)
  3208. }
  3209. pub fn instr16_D9_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3210. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3211. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  3212. ctx.builder,
  3213. ctx.start_of_current_instruction as i32 & 0xFFF,
  3214. );
  3215. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3216. ctx.builder.call_fn1("fpu_fldenv32");
  3217. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3218. codegen::gen_get_page_fault(ctx.builder);
  3219. ctx.builder.if_void();
  3220. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  3221. ctx.builder.br(ctx.exit_label);
  3222. ctx.builder.block_end();
  3223. }
  3224. pub fn instr16_D9_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3225. match r {
  3226. 0 | 1 | 4 | 5 => {
  3227. ctx.builder.const_i32(r as i32);
  3228. ctx.builder.call_fn1("instr16_D9_4_reg");
  3229. },
  3230. _ => codegen::gen_trigger_ud(ctx),
  3231. }
  3232. }
  3233. pub fn instr32_D9_4_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_4_reg_jit(ctx, r) }
  3234. pub fn instr32_D9_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3235. instr16_D9_4_mem_jit(ctx, modrm_byte)
  3236. }
  3237. pub fn instr16_D9_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3238. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3239. ctx.builder.call_fn1("set_control_word");
  3240. }
  3241. pub fn instr16_D9_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3242. if r == 7 {
  3243. codegen::gen_trigger_ud(ctx);
  3244. }
  3245. else {
  3246. codegen::gen_fn1_const(ctx.builder, "instr16_D9_5_reg", r);
  3247. }
  3248. }
  3249. pub fn instr32_D9_5_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_5_reg_jit(ctx, r) }
  3250. pub fn instr32_D9_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3251. instr16_D9_5_mem_jit(ctx, modrm_byte)
  3252. }
  3253. pub fn instr16_D9_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3254. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3255. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  3256. ctx.builder,
  3257. ctx.start_of_current_instruction as i32 & 0xFFF,
  3258. );
  3259. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3260. ctx.builder.call_fn1("fpu_fstenv32");
  3261. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3262. codegen::gen_get_page_fault(ctx.builder);
  3263. ctx.builder.if_void();
  3264. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  3265. ctx.builder.br(ctx.exit_label);
  3266. ctx.builder.block_end();
  3267. }
  3268. pub fn instr16_D9_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3269. codegen::gen_fn1_const(ctx.builder, "instr16_D9_6_reg", r);
  3270. }
  3271. pub fn instr32_D9_6_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_6_reg_jit(ctx, r) }
  3272. pub fn instr32_D9_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3273. instr16_D9_6_mem_jit(ctx, modrm_byte)
  3274. }
  3275. pub fn instr16_D9_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3276. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3277. let address_local = ctx.builder.set_new_local();
  3278. ctx.builder
  3279. .const_i32(global_pointers::fpu_control_word as i32);
  3280. ctx.builder.load_aligned_u16(0);
  3281. let value_local = ctx.builder.set_new_local();
  3282. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  3283. ctx.builder.free_local(address_local);
  3284. ctx.builder.free_local(value_local);
  3285. }
  3286. pub fn instr16_D9_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3287. codegen::gen_fn1_const(ctx.builder, "instr16_D9_7_reg", r);
  3288. }
  3289. pub fn instr32_D9_7_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_7_reg_jit(ctx, r) }
  3290. pub fn instr32_D9_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3291. instr16_D9_7_mem_jit(ctx, modrm_byte)
  3292. }
  3293. pub fn instr_DA_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3294. codegen::gen_fn1_const(ctx.builder, "instr_DA_0_reg", r);
  3295. }
  3296. pub fn instr_DA_1_reg_jit(ctx: &mut JitContext, r: u32) {
  3297. codegen::gen_fn1_const(ctx.builder, "instr_DA_1_reg", r);
  3298. }
  3299. pub fn instr_DA_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3300. codegen::gen_fn1_const(ctx.builder, "instr_DA_2_reg", r);
  3301. }
  3302. pub fn instr_DA_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3303. codegen::gen_fn1_const(ctx.builder, "instr_DA_3_reg", r);
  3304. }
  3305. pub fn instr_DA_4_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx) }
  3306. pub fn instr_DA_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3307. if r == 1 {
  3308. codegen::gen_fn0_const(ctx.builder, "fpu_fucompp")
  3309. }
  3310. else {
  3311. codegen::gen_trigger_ud(ctx)
  3312. }
  3313. }
  3314. pub fn instr_DA_6_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx) }
  3315. pub fn instr_DA_7_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx) }
  3316. pub fn instr_group_DA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) {
  3317. ctx.builder.const_i32(0);
  3318. codegen::gen_fpu_load_i32(ctx, modrm_byte);
  3319. ctx.builder.call_fn3_i32_i64_i32(op)
  3320. }
  3321. pub fn instr_DA_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3322. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fadd")
  3323. }
  3324. pub fn instr_DA_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3325. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fmul")
  3326. }
  3327. pub fn instr_DA_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3328. codegen::gen_fpu_load_i32(ctx, modrm_byte);
  3329. ctx.builder.call_fn2_i64_i32("fpu_fcom")
  3330. }
  3331. pub fn instr_DA_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3332. codegen::gen_fpu_load_i32(ctx, modrm_byte);
  3333. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3334. }
  3335. pub fn instr_DA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3336. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fsub")
  3337. }
  3338. pub fn instr_DA_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3339. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fsubr")
  3340. }
  3341. pub fn instr_DA_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3342. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fdiv")
  3343. }
  3344. pub fn instr_DA_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3345. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fdivr")
  3346. }
  3347. pub fn instr_DB_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3348. codegen::gen_fpu_load_i32(ctx, modrm_byte);
  3349. ctx.builder.call_fn2_i64_i32("fpu_push");
  3350. }
  3351. pub fn instr_DB_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3352. codegen::gen_fn1_const(ctx.builder, "instr_DB_0_reg", r);
  3353. }
  3354. pub fn instr_DB_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3355. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3356. let address_local = ctx.builder.set_new_local();
  3357. codegen::gen_fpu_get_sti(ctx, 0);
  3358. ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i32");
  3359. let value_local = ctx.builder.set_new_local();
  3360. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  3361. ctx.builder.free_local(address_local);
  3362. ctx.builder.free_local(value_local);
  3363. }
  3364. pub fn instr_DB_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3365. codegen::gen_fn1_const(ctx.builder, "instr_DB_2_reg", r);
  3366. }
  3367. pub fn instr_DB_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3368. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3369. let address_local = ctx.builder.set_new_local();
  3370. codegen::gen_fpu_get_sti(ctx, 0);
  3371. ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i32");
  3372. let value_local = ctx.builder.set_new_local();
  3373. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  3374. ctx.builder.free_local(address_local);
  3375. ctx.builder.free_local(value_local);
  3376. codegen::gen_fn0_const(ctx.builder, "fpu_pop");
  3377. }
  3378. pub fn instr_DB_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3379. codegen::gen_fn1_const(ctx.builder, "instr_DB_3_reg", r);
  3380. }
  3381. pub fn instr_DB_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3382. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3383. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  3384. ctx.builder,
  3385. ctx.start_of_current_instruction as i32 & 0xFFF,
  3386. );
  3387. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3388. ctx.builder.call_fn1("fpu_fldm80");
  3389. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3390. codegen::gen_get_page_fault(ctx.builder);
  3391. ctx.builder.if_void();
  3392. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  3393. ctx.builder.br(ctx.exit_label);
  3394. ctx.builder.block_end();
  3395. }
  3396. pub fn instr_DB_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3397. ctx.builder.const_i32(r as i32);
  3398. ctx.builder.call_fn1("fpu_fucomi");
  3399. }
  3400. pub fn instr_DB_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte) {
  3401. codegen::gen_trigger_ud(ctx);
  3402. }
  3403. pub fn instr_DB_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3404. ctx.builder.const_i32(r as i32);
  3405. ctx.builder.call_fn1("fpu_fcomi");
  3406. }
  3407. fn instr_group_DC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) {
  3408. ctx.builder.const_i32(0);
  3409. codegen::gen_fpu_load_m64(ctx, modrm_byte);
  3410. ctx.builder.call_fn3_i32_i64_i32(op)
  3411. }
  3412. fn instr_group_DC_reg_jit(ctx: &mut JitContext, r: u32, op: &str) {
  3413. ctx.builder.const_i32(r as i32);
  3414. codegen::gen_fpu_get_sti(ctx, r);
  3415. ctx.builder.call_fn3_i32_i64_i32(op)
  3416. }
  3417. pub fn instr_DC_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3418. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fadd")
  3419. }
  3420. pub fn instr_DC_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3421. instr_group_DC_reg_jit(ctx, r, "fpu_fadd")
  3422. }
  3423. pub fn instr_DC_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3424. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fmul")
  3425. }
  3426. pub fn instr_DC_1_reg_jit(ctx: &mut JitContext, r: u32) {
  3427. instr_group_DC_reg_jit(ctx, r, "fpu_fmul")
  3428. }
  3429. pub fn instr_DC_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3430. codegen::gen_fpu_load_m64(ctx, modrm_byte);
  3431. ctx.builder.call_fn2_i64_i32("fpu_fcom")
  3432. }
  3433. pub fn instr_DC_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3434. codegen::gen_fpu_get_sti(ctx, r);
  3435. ctx.builder.call_fn2_i64_i32("fpu_fcom")
  3436. }
  3437. pub fn instr_DC_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3438. codegen::gen_fpu_load_m64(ctx, modrm_byte);
  3439. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3440. }
  3441. pub fn instr_DC_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3442. codegen::gen_fpu_get_sti(ctx, r);
  3443. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3444. }
  3445. pub fn instr_DC_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3446. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fsub")
  3447. }
  3448. pub fn instr_DC_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3449. instr_group_DC_reg_jit(ctx, r, "fpu_fsub")
  3450. }
  3451. pub fn instr_DC_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3452. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fsubr")
  3453. }
  3454. pub fn instr_DC_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3455. instr_group_DC_reg_jit(ctx, r, "fpu_fsubr")
  3456. }
  3457. pub fn instr_DC_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3458. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fdiv")
  3459. }
  3460. pub fn instr_DC_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3461. instr_group_DC_reg_jit(ctx, r, "fpu_fdiv")
  3462. }
  3463. pub fn instr_DC_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3464. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fdivr")
  3465. }
  3466. pub fn instr_DC_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3467. instr_group_DC_reg_jit(ctx, r, "fpu_fdivr")
  3468. }
  3469. pub fn instr16_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3470. codegen::gen_fpu_load_m64(ctx, modrm_byte);
  3471. ctx.builder.call_fn2_i64_i32("fpu_push");
  3472. }
  3473. pub fn instr16_DD_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3474. codegen::gen_fn1_const(ctx.builder, "fpu_ffree", r);
  3475. }
  3476. pub fn instr32_DD_0_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_0_reg_jit(ctx, r) }
  3477. pub fn instr32_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3478. instr16_DD_0_mem_jit(ctx, modrm_byte)
  3479. }
  3480. pub fn instr16_DD_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3481. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3482. let address_local = ctx.builder.set_new_local();
  3483. codegen::gen_fpu_get_sti(ctx, 0);
  3484. ctx.builder.call_fn2_i64_i32_ret_i64("f80_to_f64");
  3485. let value_local = ctx.builder.set_new_local_i64();
  3486. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  3487. ctx.builder.free_local(address_local);
  3488. ctx.builder.free_local_i64(value_local);
  3489. }
  3490. pub fn instr16_DD_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3491. codegen::gen_fn1_const(ctx.builder, "fpu_fst", r);
  3492. }
  3493. pub fn instr32_DD_2_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_2_reg_jit(ctx, r) }
  3494. pub fn instr32_DD_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3495. instr16_DD_2_mem_jit(ctx, modrm_byte)
  3496. }
  3497. pub fn instr16_DD_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3498. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3499. let address_local = ctx.builder.set_new_local();
  3500. codegen::gen_fpu_get_sti(ctx, 0);
  3501. ctx.builder.call_fn2_i64_i32_ret_i64("f80_to_f64");
  3502. let value_local = ctx.builder.set_new_local_i64();
  3503. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  3504. codegen::gen_fn0_const(ctx.builder, "fpu_pop");
  3505. ctx.builder.free_local(address_local);
  3506. ctx.builder.free_local_i64(value_local);
  3507. }
  3508. pub fn instr16_DD_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3509. codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
  3510. }
  3511. pub fn instr32_DD_3_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_3_reg_jit(ctx, r) }
  3512. pub fn instr32_DD_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3513. instr16_DD_3_mem_jit(ctx, modrm_byte)
  3514. }
  3515. pub fn instr16_DD_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3516. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3517. codegen::gen_trigger_ud(ctx);
  3518. }
  3519. pub fn instr16_DD_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3520. ctx.builder.const_i32(r as i32);
  3521. ctx.builder.call_fn1("fpu_fucomp");
  3522. }
  3523. pub fn instr32_DD_5_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_5_reg_jit(ctx, r) }
  3524. pub fn instr32_DD_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3525. instr16_DD_5_mem_jit(ctx, modrm_byte)
  3526. }
  3527. fn instr_group_DE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) {
  3528. ctx.builder.const_i32(0);
  3529. codegen::gen_fpu_load_i16(ctx, modrm_byte);
  3530. ctx.builder.call_fn3_i32_i64_i32(op)
  3531. }
  3532. fn instr_group_DE_reg_jit(ctx: &mut JitContext, r: u32, op: &str) {
  3533. ctx.builder.const_i32(r as i32);
  3534. codegen::gen_fpu_get_sti(ctx, r);
  3535. ctx.builder.call_fn3_i32_i64_i32(op);
  3536. codegen::gen_fn0_const(ctx.builder, "fpu_pop")
  3537. }
  3538. pub fn instr_DE_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3539. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fadd")
  3540. }
  3541. pub fn instr_DE_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3542. instr_group_DE_reg_jit(ctx, r, "fpu_fadd")
  3543. }
  3544. pub fn instr_DE_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3545. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fmul")
  3546. }
  3547. pub fn instr_DE_1_reg_jit(ctx: &mut JitContext, r: u32) {
  3548. instr_group_DE_reg_jit(ctx, r, "fpu_fmul")
  3549. }
  3550. pub fn instr_DE_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3551. codegen::gen_fpu_load_i16(ctx, modrm_byte);
  3552. ctx.builder.call_fn2_i64_i32("fpu_fcom")
  3553. }
  3554. pub fn instr_DE_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3555. codegen::gen_fpu_get_sti(ctx, r);
  3556. ctx.builder.call_fn2_i64_i32("fpu_fcom");
  3557. codegen::gen_fn0_const(ctx.builder, "fpu_pop")
  3558. }
  3559. pub fn instr_DE_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3560. codegen::gen_fpu_load_i16(ctx, modrm_byte);
  3561. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3562. }
  3563. pub fn instr_DE_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3564. if r == 1 {
  3565. codegen::gen_fpu_get_sti(ctx, r);
  3566. ctx.builder.call_fn2_i64_i32("fpu_fcomp");
  3567. codegen::gen_fn0_const(ctx.builder, "fpu_pop")
  3568. }
  3569. else {
  3570. codegen::gen_trigger_ud(ctx);
  3571. }
  3572. }
  3573. pub fn instr_DE_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3574. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fsub")
  3575. }
  3576. pub fn instr_DE_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3577. instr_group_DE_reg_jit(ctx, r, "fpu_fsub")
  3578. }
  3579. pub fn instr_DE_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3580. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fsubr")
  3581. }
  3582. pub fn instr_DE_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3583. instr_group_DE_reg_jit(ctx, r, "fpu_fsubr")
  3584. }
  3585. pub fn instr_DE_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3586. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fdiv")
  3587. }
  3588. pub fn instr_DE_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3589. instr_group_DE_reg_jit(ctx, r, "fpu_fdiv")
  3590. }
  3591. pub fn instr_DE_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3592. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fdivr")
  3593. }
  3594. pub fn instr_DE_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3595. instr_group_DE_reg_jit(ctx, r, "fpu_fdivr")
  3596. }
  3597. pub fn instr_DF_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3598. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3599. let address_local = ctx.builder.set_new_local();
  3600. codegen::gen_fpu_get_sti(ctx, 0);
  3601. ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i16");
  3602. let value_local = ctx.builder.set_new_local();
  3603. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  3604. ctx.builder.free_local(address_local);
  3605. ctx.builder.free_local(value_local);
  3606. }
  3607. pub fn instr_DF_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3608. codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
  3609. }
  3610. pub fn instr_DF_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3611. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3612. let address_local = ctx.builder.set_new_local();
  3613. codegen::gen_fpu_get_sti(ctx, 0);
  3614. ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i16");
  3615. let value_local = ctx.builder.set_new_local();
  3616. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  3617. ctx.builder.free_local(address_local);
  3618. ctx.builder.free_local(value_local);
  3619. codegen::gen_fn0_const(ctx.builder, "fpu_pop");
  3620. }
  3621. pub fn instr_DF_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3622. codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
  3623. }
  3624. pub fn instr_DF_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3625. dbg_log!("fbld");
  3626. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3627. codegen::gen_trigger_ud(ctx);
  3628. }
  3629. pub fn instr_DF_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3630. if r == 0 {
  3631. ctx.builder.call_fn0_ret("fpu_load_status_word");
  3632. codegen::gen_set_reg16(ctx, regs::AX);
  3633. }
  3634. else {
  3635. codegen::gen_trigger_ud(ctx);
  3636. };
  3637. }
  3638. pub fn instr_DF_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3639. codegen::gen_fpu_load_i64(ctx, modrm_byte);
  3640. ctx.builder.call_fn2_i64_i32("fpu_push");
  3641. }
  3642. pub fn instr_DF_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3643. codegen::gen_fn1_const(ctx.builder, "fpu_fucomip", r);
  3644. }
  3645. pub fn instr_DF_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3646. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3647. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  3648. ctx.builder,
  3649. ctx.start_of_current_instruction as i32 & 0xFFF,
  3650. );
  3651. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3652. ctx.builder.call_fn1("fpu_fbstp");
  3653. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3654. codegen::gen_get_page_fault(ctx.builder);
  3655. ctx.builder.if_void();
  3656. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  3657. ctx.builder.br(ctx.exit_label);
  3658. ctx.builder.block_end();
  3659. }
  3660. pub fn instr_DF_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3661. ctx.builder.const_i32(r as i32);
  3662. ctx.builder.call_fn1("fpu_fcomip");
  3663. }
  3664. pub fn instr_DF_7_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx); }
  3665. pub fn instr_DF_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3666. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3667. let address_local = ctx.builder.set_new_local();
  3668. codegen::gen_fpu_get_sti(ctx, 0);
  3669. ctx.builder.call_fn2_i64_i32_ret_i64("fpu_convert_to_i64");
  3670. let value_local = ctx.builder.set_new_local_i64();
  3671. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  3672. ctx.builder.free_local(address_local);
  3673. ctx.builder.free_local_i64(value_local);
  3674. codegen::gen_fn0_const(ctx.builder, "fpu_pop");
  3675. }
  3676. pub fn instr16_EB_jit(_ctx: &mut JitContext, _imm8: u32) {
  3677. //
  3678. }
  3679. pub fn instr32_EB_jit(_ctx: &mut JitContext, _imm8: u32) {
  3680. // jmp near
  3681. }
  3682. define_instruction_read8!(gen_test8, instr_F6_0_mem_jit, instr_F6_0_reg_jit, imm8);
  3683. define_instruction_read16!(
  3684. gen_test16,
  3685. instr16_F7_0_mem_jit,
  3686. instr16_F7_0_reg_jit,
  3687. imm16
  3688. );
  3689. define_instruction_read32!(
  3690. gen_test32,
  3691. instr32_F7_0_mem_jit,
  3692. instr32_F7_0_reg_jit,
  3693. imm32
  3694. );
  3695. pub fn instr_F6_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  3696. instr_F6_0_mem_jit(ctx, modrm_byte, imm)
  3697. }
  3698. pub fn instr_F6_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  3699. instr_F6_0_reg_jit(ctx, r, imm)
  3700. }
  3701. pub fn instr16_F7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  3702. instr16_F7_0_mem_jit(ctx, modrm_byte, imm)
  3703. }
  3704. pub fn instr16_F7_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  3705. instr16_F7_0_reg_jit(ctx, r, imm)
  3706. }
  3707. pub fn instr32_F7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  3708. instr32_F7_0_mem_jit(ctx, modrm_byte, imm)
  3709. }
  3710. pub fn instr32_F7_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  3711. instr32_F7_0_reg_jit(ctx, r, imm)
  3712. }
  3713. define_instruction_read_write_mem8!("not8", instr_F6_2_mem_jit, instr_F6_2_reg_jit, none);
  3714. define_instruction_read_write_mem8!("neg8", instr_F6_3_mem_jit, instr_F6_3_reg_jit, none);
  3715. define_instruction_read_write_mem16!(gen_not16, instr16_F7_2_mem_jit, instr16_F7_2_reg_jit, none);
  3716. define_instruction_read_write_mem32!(gen_not32, instr32_F7_2_mem_jit, instr32_F7_2_reg_jit, none);
  3717. define_instruction_read_write_mem16!(gen_neg16, instr16_F7_3_mem_jit, instr16_F7_3_reg_jit, none);
  3718. define_instruction_read_write_mem32!(gen_neg32, instr32_F7_3_mem_jit, instr32_F7_3_reg_jit, none);
  3719. pub fn instr16_F7_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3720. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3721. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3722. ctx.builder.call_fn1("mul16");
  3723. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3724. }
  3725. pub fn instr16_F7_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3726. codegen::gen_get_reg16(ctx, r);
  3727. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3728. ctx.builder.call_fn1("mul16");
  3729. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3730. }
  3731. pub fn instr32_F7_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3732. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3733. gen_mul32(ctx);
  3734. }
  3735. pub fn instr32_F7_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3736. codegen::gen_get_reg32(ctx, r);
  3737. gen_mul32(ctx);
  3738. }
  3739. pub fn instr16_F7_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3740. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3741. codegen::sign_extend_i16(ctx.builder);
  3742. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3743. ctx.builder.call_fn1("imul16");
  3744. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3745. }
  3746. pub fn instr16_F7_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3747. codegen::gen_get_reg16(ctx, r);
  3748. codegen::sign_extend_i16(ctx.builder);
  3749. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3750. ctx.builder.call_fn1("imul16");
  3751. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3752. }
  3753. pub fn instr32_F7_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3754. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3755. gen_imul32(ctx);
  3756. }
  3757. pub fn instr32_F7_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3758. codegen::gen_get_reg32(ctx, r);
  3759. gen_imul32(ctx);
  3760. }
  3761. pub fn instr16_F7_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3762. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3763. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3764. ctx.builder.call_fn1_ret("div16_without_fault");
  3765. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3766. ctx.builder.eqz_i32();
  3767. ctx.builder.if_void();
  3768. codegen::gen_trigger_de(ctx);
  3769. ctx.builder.block_end();
  3770. }
  3771. pub fn instr16_F7_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3772. codegen::gen_get_reg16(ctx, r);
  3773. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3774. ctx.builder.call_fn1_ret("div16_without_fault");
  3775. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3776. ctx.builder.eqz_i32();
  3777. ctx.builder.if_void();
  3778. codegen::gen_trigger_de(ctx);
  3779. ctx.builder.block_end();
  3780. }
  3781. pub fn instr32_F7_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3782. if false {
  3783. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3784. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3785. ctx.builder.call_fn1_ret("div32_without_fault");
  3786. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3787. ctx.builder.eqz_i32();
  3788. ctx.builder.if_void();
  3789. codegen::gen_trigger_de(ctx);
  3790. ctx.builder.block_end();
  3791. }
  3792. else {
  3793. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3794. let source_operand = ctx.builder.set_new_local();
  3795. gen_div32(ctx, &source_operand);
  3796. ctx.builder.free_local(source_operand);
  3797. }
  3798. }
  3799. pub fn instr32_F7_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3800. if false {
  3801. codegen::gen_get_reg32(ctx, r);
  3802. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3803. ctx.builder.call_fn1_ret("div32_without_fault");
  3804. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3805. ctx.builder.eqz_i32();
  3806. ctx.builder.if_void();
  3807. codegen::gen_trigger_de(ctx);
  3808. ctx.builder.block_end();
  3809. }
  3810. else {
  3811. gen_div32(ctx, &ctx.reg(r));
  3812. }
  3813. }
  3814. pub fn instr16_F7_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3815. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3816. codegen::sign_extend_i16(ctx.builder);
  3817. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3818. ctx.builder.call_fn1_ret("idiv16_without_fault");
  3819. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3820. ctx.builder.eqz_i32();
  3821. ctx.builder.if_void();
  3822. codegen::gen_trigger_de(ctx);
  3823. ctx.builder.block_end();
  3824. }
  3825. pub fn instr16_F7_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3826. codegen::gen_get_reg16(ctx, r);
  3827. codegen::sign_extend_i16(ctx.builder);
  3828. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3829. ctx.builder.call_fn1_ret("idiv16_without_fault");
  3830. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3831. ctx.builder.eqz_i32();
  3832. ctx.builder.if_void();
  3833. codegen::gen_trigger_de(ctx);
  3834. ctx.builder.block_end();
  3835. }
  3836. pub fn instr32_F7_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3837. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3838. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3839. ctx.builder.call_fn1_ret("idiv32_without_fault");
  3840. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3841. ctx.builder.eqz_i32();
  3842. ctx.builder.if_void();
  3843. codegen::gen_trigger_de(ctx);
  3844. ctx.builder.block_end();
  3845. }
  3846. pub fn instr32_F7_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3847. codegen::gen_get_reg32(ctx, r);
  3848. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3849. ctx.builder.call_fn1_ret("idiv32_without_fault");
  3850. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3851. ctx.builder.eqz_i32();
  3852. ctx.builder.if_void();
  3853. codegen::gen_trigger_de(ctx);
  3854. ctx.builder.block_end();
  3855. }
  3856. pub fn instr_F8_jit(ctx: &mut JitContext) {
  3857. codegen::gen_clear_flags_changed_bits(ctx.builder, 1);
  3858. codegen::gen_clear_flags_bits(ctx.builder, 1);
  3859. }
  3860. pub fn instr_F9_jit(ctx: &mut JitContext) {
  3861. codegen::gen_clear_flags_changed_bits(ctx.builder, 1);
  3862. codegen::gen_set_flags_bits(ctx.builder, 1);
  3863. }
  3864. pub fn instr_FA_jit(ctx: &mut JitContext) {
  3865. ctx.builder.call_fn0_ret("instr_FA_without_fault");
  3866. ctx.builder.eqz_i32();
  3867. ctx.builder.if_void();
  3868. codegen::gen_trigger_gp(ctx, 0);
  3869. ctx.builder.block_end();
  3870. }
  3871. pub fn instr_FB_jit(ctx: &mut JitContext) {
  3872. ctx.builder.call_fn0_ret("instr_FB_without_fault");
  3873. ctx.builder.eqz_i32();
  3874. ctx.builder.if_void();
  3875. codegen::gen_trigger_gp(ctx, 0);
  3876. ctx.builder.block_end();
  3877. // handle_irqs is specially handled in jit to be called one instruction after this one
  3878. }
  3879. pub fn instr_FC_jit(ctx: &mut JitContext) {
  3880. ctx.builder.const_i32(global_pointers::flags as i32);
  3881. codegen::gen_get_flags(ctx.builder);
  3882. ctx.builder.const_i32(!FLAG_DIRECTION);
  3883. ctx.builder.and_i32();
  3884. ctx.builder.store_aligned_i32(0);
  3885. }
  3886. pub fn instr_FD_jit(ctx: &mut JitContext) {
  3887. ctx.builder.const_i32(global_pointers::flags as i32);
  3888. codegen::gen_get_flags(ctx.builder);
  3889. ctx.builder.const_i32(FLAG_DIRECTION);
  3890. ctx.builder.or_i32();
  3891. ctx.builder.store_aligned_i32(0);
  3892. }
  3893. define_instruction_read_write_mem8!("inc8", instr_FE_0_mem_jit, instr_FE_0_reg_jit, none);
  3894. define_instruction_read_write_mem8!("dec8", instr_FE_1_mem_jit, instr_FE_1_reg_jit, none);
  3895. define_instruction_read_write_mem16!(gen_inc16, instr16_FF_0_mem_jit, instr16_FF_0_reg_jit, none);
  3896. define_instruction_read_write_mem32!(gen_inc32, instr32_FF_0_mem_jit, instr32_FF_0_reg_jit, none);
  3897. define_instruction_read_write_mem16!(gen_dec16, instr16_FF_1_mem_jit, instr16_FF_1_reg_jit, none);
  3898. define_instruction_read_write_mem32!(gen_dec32, instr32_FF_1_mem_jit, instr32_FF_1_reg_jit, none);
  3899. pub fn instr16_FF_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3900. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3901. codegen::gen_add_cs_offset(ctx);
  3902. let new_eip = ctx.builder.set_new_local();
  3903. codegen::gen_get_real_eip(ctx);
  3904. let value_local = ctx.builder.set_new_local();
  3905. codegen::gen_push16(ctx, &value_local);
  3906. ctx.builder.free_local(value_local);
  3907. ctx.builder.const_i32(0);
  3908. ctx.builder.get_local(&new_eip);
  3909. ctx.builder
  3910. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3911. ctx.builder.free_local(new_eip);
  3912. }
  3913. pub fn instr16_FF_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3914. codegen::gen_get_real_eip(ctx);
  3915. let value_local = ctx.builder.set_new_local();
  3916. codegen::gen_push16(ctx, &value_local);
  3917. ctx.builder.free_local(value_local);
  3918. ctx.builder.const_i32(0);
  3919. codegen::gen_get_reg16(ctx, r);
  3920. codegen::gen_add_cs_offset(ctx);
  3921. ctx.builder
  3922. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3923. }
  3924. pub fn instr32_FF_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3925. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3926. codegen::gen_add_cs_offset(ctx);
  3927. let new_eip = ctx.builder.set_new_local();
  3928. codegen::gen_get_real_eip(ctx);
  3929. let value_local = ctx.builder.set_new_local();
  3930. codegen::gen_push32(ctx, &value_local);
  3931. ctx.builder.free_local(value_local);
  3932. ctx.builder.const_i32(0);
  3933. ctx.builder.get_local(&new_eip);
  3934. ctx.builder
  3935. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3936. ctx.builder.free_local(new_eip);
  3937. }
  3938. pub fn instr32_FF_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3939. codegen::gen_get_real_eip(ctx);
  3940. let value_local = ctx.builder.set_new_local();
  3941. codegen::gen_push32(ctx, &value_local);
  3942. ctx.builder.free_local(value_local);
  3943. ctx.builder.const_i32(0);
  3944. codegen::gen_get_reg32(ctx, r);
  3945. codegen::gen_add_cs_offset(ctx);
  3946. ctx.builder
  3947. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3948. }
  3949. pub fn instr16_FF_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3950. ctx.builder.const_i32(0);
  3951. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3952. codegen::gen_add_cs_offset(ctx);
  3953. ctx.builder
  3954. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3955. }
  3956. pub fn instr16_FF_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3957. ctx.builder.const_i32(0);
  3958. codegen::gen_get_reg16(ctx, r);
  3959. codegen::gen_add_cs_offset(ctx);
  3960. ctx.builder
  3961. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3962. }
  3963. pub fn instr32_FF_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3964. ctx.builder.const_i32(0);
  3965. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3966. codegen::gen_add_cs_offset(ctx);
  3967. ctx.builder
  3968. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3969. }
  3970. pub fn instr32_FF_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3971. ctx.builder.const_i32(0);
  3972. codegen::gen_get_reg32(ctx, r);
  3973. codegen::gen_add_cs_offset(ctx);
  3974. ctx.builder
  3975. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3976. }
  3977. pub fn instr16_FF_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3978. push16_mem_jit(ctx, modrm_byte)
  3979. }
  3980. pub fn instr16_FF_6_reg_jit(ctx: &mut JitContext, r: u32) { push16_reg_jit(ctx, r) }
  3981. pub fn instr32_FF_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3982. push32_mem_jit(ctx, modrm_byte)
  3983. }
  3984. pub fn instr32_FF_6_reg_jit(ctx: &mut JitContext, r: u32) { push32_reg_jit(ctx, r) }
  3985. // Code for conditional jumps is generated automatically by the basic block codegen
  3986. pub fn instr16_0F80_jit(_ctx: &mut JitContext, _imm: u32) {}
  3987. pub fn instr16_0F81_jit(_ctx: &mut JitContext, _imm: u32) {}
  3988. pub fn instr16_0F82_jit(_ctx: &mut JitContext, _imm: u32) {}
  3989. pub fn instr16_0F83_jit(_ctx: &mut JitContext, _imm: u32) {}
  3990. pub fn instr16_0F84_jit(_ctx: &mut JitContext, _imm: u32) {}
  3991. pub fn instr16_0F85_jit(_ctx: &mut JitContext, _imm: u32) {}
  3992. pub fn instr16_0F86_jit(_ctx: &mut JitContext, _imm: u32) {}
  3993. pub fn instr16_0F87_jit(_ctx: &mut JitContext, _imm: u32) {}
  3994. pub fn instr16_0F88_jit(_ctx: &mut JitContext, _imm: u32) {}
  3995. pub fn instr16_0F89_jit(_ctx: &mut JitContext, _imm: u32) {}
  3996. pub fn instr16_0F8A_jit(_ctx: &mut JitContext, _imm: u32) {}
  3997. pub fn instr16_0F8B_jit(_ctx: &mut JitContext, _imm: u32) {}
  3998. pub fn instr16_0F8C_jit(_ctx: &mut JitContext, _imm: u32) {}
  3999. pub fn instr16_0F8D_jit(_ctx: &mut JitContext, _imm: u32) {}
  4000. pub fn instr16_0F8E_jit(_ctx: &mut JitContext, _imm: u32) {}
  4001. pub fn instr16_0F8F_jit(_ctx: &mut JitContext, _imm: u32) {}
  4002. pub fn instr32_0F80_jit(_ctx: &mut JitContext, _imm: u32) {}
  4003. pub fn instr32_0F81_jit(_ctx: &mut JitContext, _imm: u32) {}
  4004. pub fn instr32_0F82_jit(_ctx: &mut JitContext, _imm: u32) {}
  4005. pub fn instr32_0F83_jit(_ctx: &mut JitContext, _imm: u32) {}
  4006. pub fn instr32_0F84_jit(_ctx: &mut JitContext, _imm: u32) {}
  4007. pub fn instr32_0F85_jit(_ctx: &mut JitContext, _imm: u32) {}
  4008. pub fn instr32_0F86_jit(_ctx: &mut JitContext, _imm: u32) {}
  4009. pub fn instr32_0F87_jit(_ctx: &mut JitContext, _imm: u32) {}
  4010. pub fn instr32_0F88_jit(_ctx: &mut JitContext, _imm: u32) {}
  4011. pub fn instr32_0F89_jit(_ctx: &mut JitContext, _imm: u32) {}
  4012. pub fn instr32_0F8A_jit(_ctx: &mut JitContext, _imm: u32) {}
  4013. pub fn instr32_0F8B_jit(_ctx: &mut JitContext, _imm: u32) {}
  4014. pub fn instr32_0F8C_jit(_ctx: &mut JitContext, _imm: u32) {}
  4015. pub fn instr32_0F8D_jit(_ctx: &mut JitContext, _imm: u32) {}
  4016. pub fn instr32_0F8E_jit(_ctx: &mut JitContext, _imm: u32) {}
  4017. pub fn instr32_0F8F_jit(_ctx: &mut JitContext, _imm: u32) {}
  4018. pub fn instr_90_jit(_ctx: &mut JitContext) {}
  4019. fn gen_xchg_reg16(ctx: &mut JitContext, r: u32) {
  4020. codegen::gen_get_reg16(ctx, r);
  4021. let tmp = ctx.builder.set_new_local();
  4022. codegen::gen_get_reg16(ctx, regs::AX);
  4023. codegen::gen_set_reg16(ctx, r);
  4024. ctx.builder.get_local(&tmp);
  4025. codegen::gen_set_reg16(ctx, regs::AX);
  4026. ctx.builder.free_local(tmp);
  4027. }
  4028. fn gen_xchg_reg32(ctx: &mut JitContext, r: u32) {
  4029. codegen::gen_get_reg32(ctx, r);
  4030. let tmp = ctx.builder.set_new_local();
  4031. codegen::gen_get_reg32(ctx, regs::EAX);
  4032. codegen::gen_set_reg32(ctx, r);
  4033. ctx.builder.get_local(&tmp);
  4034. codegen::gen_set_reg32(ctx, regs::EAX);
  4035. ctx.builder.free_local(tmp);
  4036. }
  4037. pub fn instr16_91_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::CX); }
  4038. pub fn instr16_92_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::DX); }
  4039. pub fn instr16_93_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::BX); }
  4040. pub fn instr16_94_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::SP); }
  4041. pub fn instr16_95_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::BP); }
  4042. pub fn instr16_96_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::SI); }
  4043. pub fn instr16_97_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::DI); }
  4044. pub fn instr32_91_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::CX); }
  4045. pub fn instr32_92_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::DX); }
  4046. pub fn instr32_93_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::BX); }
  4047. pub fn instr32_94_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::SP); }
  4048. pub fn instr32_95_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::BP); }
  4049. pub fn instr32_96_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::SI); }
  4050. pub fn instr32_97_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::DI); }
  4051. pub fn instr16_98_jit(ctx: &mut JitContext) {
  4052. codegen::gen_get_reg32(ctx, regs::EAX);
  4053. codegen::sign_extend_i8(ctx.builder);
  4054. codegen::gen_set_reg16(ctx, regs::AX);
  4055. }
  4056. pub fn instr32_98_jit(ctx: &mut JitContext) {
  4057. codegen::gen_get_reg32(ctx, regs::EAX);
  4058. codegen::sign_extend_i16(ctx.builder);
  4059. codegen::gen_set_reg32(ctx, regs::EAX);
  4060. }
  4061. pub fn instr16_99_jit(ctx: &mut JitContext) {
  4062. codegen::gen_get_reg16(ctx, regs::AX);
  4063. ctx.builder.const_i32(16);
  4064. ctx.builder.shl_i32();
  4065. ctx.builder.const_i32(31);
  4066. ctx.builder.shr_s_i32();
  4067. codegen::gen_set_reg16(ctx, regs::DX);
  4068. }
  4069. pub fn instr32_99_jit(ctx: &mut JitContext) {
  4070. codegen::gen_get_reg32(ctx, regs::EAX);
  4071. ctx.builder.const_i32(31);
  4072. ctx.builder.shr_s_i32();
  4073. codegen::gen_set_reg32(ctx, regs::EDX);
  4074. }
  4075. fn gen_pushf_popf_check(ctx: &mut JitContext) {
  4076. // 0 != *flags & FLAG_VM && getiopl() < 3
  4077. codegen::gen_get_flags(ctx.builder);
  4078. ctx.builder.const_i32(FLAG_VM);
  4079. ctx.builder.and_i32();
  4080. ctx.builder.const_i32(FLAG_VM);
  4081. ctx.builder.eq_i32();
  4082. codegen::gen_get_flags(ctx.builder);
  4083. ctx.builder.const_i32(FLAG_IOPL);
  4084. ctx.builder.and_i32();
  4085. ctx.builder.const_i32(FLAG_IOPL);
  4086. ctx.builder.ne_i32();
  4087. ctx.builder.and_i32();
  4088. }
  4089. pub fn instr16_9C_jit(ctx: &mut JitContext) {
  4090. gen_pushf_popf_check(ctx);
  4091. ctx.builder.if_void();
  4092. codegen::gen_trigger_gp(ctx, 0);
  4093. ctx.builder.else_();
  4094. ctx.builder.call_fn0_ret("get_eflags");
  4095. let value = ctx.builder.set_new_local();
  4096. codegen::gen_push16(ctx, &value);
  4097. ctx.builder.block_end();
  4098. ctx.builder.free_local(value);
  4099. }
  4100. pub fn instr32_9C_jit(ctx: &mut JitContext) {
  4101. gen_pushf_popf_check(ctx);
  4102. ctx.builder.if_void();
  4103. codegen::gen_trigger_gp(ctx, 0);
  4104. ctx.builder.else_();
  4105. ctx.builder.call_fn0_ret("get_eflags");
  4106. ctx.builder.const_i32(0xFCFFFF);
  4107. ctx.builder.and_i32();
  4108. let value = ctx.builder.set_new_local();
  4109. codegen::gen_push32(ctx, &value);
  4110. ctx.builder.block_end();
  4111. ctx.builder.free_local(value);
  4112. }
  4113. fn gen_popf(ctx: &mut JitContext, is_32: bool) {
  4114. gen_pushf_popf_check(ctx);
  4115. ctx.builder.if_void();
  4116. codegen::gen_trigger_gp(ctx, 0);
  4117. ctx.builder.else_();
  4118. codegen::gen_get_flags(ctx.builder);
  4119. let old_eflags = ctx.builder.set_new_local();
  4120. if is_32 {
  4121. codegen::gen_pop32s(ctx);
  4122. }
  4123. else {
  4124. ctx.builder.get_local(&old_eflags);
  4125. ctx.builder.const_i32(!0xFFFF);
  4126. ctx.builder.and_i32();
  4127. codegen::gen_pop16(ctx);
  4128. ctx.builder.or_i32();
  4129. }
  4130. ctx.builder.call_fn1("update_eflags");
  4131. ctx.builder.get_local(&old_eflags);
  4132. ctx.builder.free_local(old_eflags);
  4133. ctx.builder.const_i32(FLAG_INTERRUPT);
  4134. ctx.builder.and_i32();
  4135. ctx.builder.eqz_i32();
  4136. codegen::gen_get_flags(ctx.builder);
  4137. ctx.builder.const_i32(FLAG_INTERRUPT);
  4138. ctx.builder.and_i32();
  4139. ctx.builder.eqz_i32();
  4140. ctx.builder.eqz_i32();
  4141. ctx.builder.and_i32();
  4142. ctx.builder.if_void();
  4143. {
  4144. codegen::gen_set_eip_to_after_current_instruction(ctx);
  4145. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  4146. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4147. codegen::gen_fn0_const(ctx.builder, "handle_irqs");
  4148. codegen::gen_update_instruction_counter(ctx);
  4149. ctx.builder.return_();
  4150. }
  4151. ctx.builder.block_end();
  4152. ctx.builder.block_end();
  4153. }
  4154. pub fn instr16_9D_jit(ctx: &mut JitContext) { gen_popf(ctx, false) }
  4155. pub fn instr32_9D_jit(ctx: &mut JitContext) { gen_popf(ctx, true) }
  4156. pub fn instr_9E_jit(ctx: &mut JitContext) {
  4157. ctx.builder.const_i32(global_pointers::flags as i32);
  4158. codegen::gen_get_flags(ctx.builder);
  4159. ctx.builder.const_i32(!0xFF);
  4160. ctx.builder.and_i32();
  4161. codegen::gen_get_reg8(ctx, regs::AH);
  4162. ctx.builder.or_i32();
  4163. ctx.builder.const_i32(FLAGS_MASK);
  4164. ctx.builder.and_i32();
  4165. ctx.builder.const_i32(FLAGS_DEFAULT);
  4166. ctx.builder.or_i32();
  4167. ctx.builder.store_aligned_i32(0);
  4168. codegen::gen_clear_flags_changed_bits(ctx.builder, 0xFF);
  4169. }
  4170. pub fn instr_9F_jit(ctx: &mut JitContext) {
  4171. ctx.builder.call_fn0_ret("get_eflags");
  4172. codegen::gen_set_reg8(ctx, regs::AH);
  4173. }
  4174. pub fn instr_A0_jit(ctx: &mut JitContext, immaddr: u32) {
  4175. ctx.builder.const_i32(immaddr as i32);
  4176. jit_add_seg_offset(ctx, regs::DS);
  4177. let address_local = ctx.builder.set_new_local();
  4178. codegen::gen_safe_read8(ctx, &address_local);
  4179. ctx.builder.free_local(address_local);
  4180. codegen::gen_set_reg8(ctx, regs::AL);
  4181. }
  4182. pub fn instr16_A1_jit(ctx: &mut JitContext, immaddr: u32) {
  4183. ctx.builder.const_i32(immaddr as i32);
  4184. jit_add_seg_offset(ctx, regs::DS);
  4185. let address_local = ctx.builder.set_new_local();
  4186. codegen::gen_safe_read16(ctx, &address_local);
  4187. ctx.builder.free_local(address_local);
  4188. codegen::gen_set_reg16(ctx, regs::AX);
  4189. }
  4190. pub fn instr32_A1_jit(ctx: &mut JitContext, immaddr: u32) {
  4191. ctx.builder.const_i32(immaddr as i32);
  4192. jit_add_seg_offset(ctx, regs::DS);
  4193. let address_local = ctx.builder.set_new_local();
  4194. codegen::gen_safe_read32(ctx, &address_local);
  4195. ctx.builder.free_local(address_local);
  4196. codegen::gen_set_reg32(ctx, regs::EAX);
  4197. }
  4198. pub fn instr_A2_jit(ctx: &mut JitContext, immaddr: u32) {
  4199. ctx.builder.const_i32(immaddr as i32);
  4200. jit_add_seg_offset(ctx, regs::DS);
  4201. let address_local = ctx.builder.set_new_local();
  4202. codegen::gen_safe_write8(ctx, &address_local, &ctx.reg(regs::EAX));
  4203. ctx.builder.free_local(address_local);
  4204. }
  4205. pub fn instr16_A3_jit(ctx: &mut JitContext, immaddr: u32) {
  4206. ctx.builder.const_i32(immaddr as i32);
  4207. jit_add_seg_offset(ctx, regs::DS);
  4208. let address_local = ctx.builder.set_new_local();
  4209. codegen::gen_safe_write16(ctx, &address_local, &ctx.reg(regs::EAX));
  4210. ctx.builder.free_local(address_local);
  4211. }
  4212. pub fn instr32_A3_jit(ctx: &mut JitContext, immaddr: u32) {
  4213. ctx.builder.const_i32(immaddr as i32);
  4214. jit_add_seg_offset(ctx, regs::DS);
  4215. let address_local = ctx.builder.set_new_local();
  4216. codegen::gen_safe_write32(ctx, &address_local, &ctx.reg(regs::EAX));
  4217. ctx.builder.free_local(address_local);
  4218. }
  4219. pub fn instr_A8_jit(ctx: &mut JitContext, imm8: u32) {
  4220. gen_test8(ctx, &ctx.reg(0), &LocalOrImmediate::Immediate(imm8 as i32));
  4221. }
  4222. pub fn instr16_A9_jit(ctx: &mut JitContext, imm16: u32) {
  4223. gen_test16(ctx, &ctx.reg(0), &LocalOrImmediate::Immediate(imm16 as i32));
  4224. }
  4225. pub fn instr32_A9_jit(ctx: &mut JitContext, imm32: u32) {
  4226. gen_test32(ctx, &ctx.reg(0), &LocalOrImmediate::Immediate(imm32 as i32));
  4227. }
  4228. #[derive(PartialEq)]
  4229. enum String {
  4230. INS,
  4231. OUTS,
  4232. MOVS,
  4233. CMPS,
  4234. STOS,
  4235. LODS,
  4236. SCAS,
  4237. }
  4238. fn gen_string_ins(ctx: &mut JitContext, ins: String, size: u8, prefix: u8) {
  4239. dbg_assert!(prefix == 0 || prefix == 0xF2 || prefix == 0xF3);
  4240. dbg_assert!(size == 8 || size == 16 || size == 32);
  4241. if prefix == 0 {
  4242. fn get_direction(ctx: &mut JitContext, size: u8) {
  4243. let bytes: i32 = (size / 8).into();
  4244. dbg_assert!(bytes == 1 || bytes == 2 || bytes == 4);
  4245. ctx.builder.const_i32(-bytes);
  4246. ctx.builder.const_i32(bytes);
  4247. codegen::gen_get_flags(ctx.builder);
  4248. ctx.builder.const_i32(FLAG_DIRECTION);
  4249. ctx.builder.and_i32();
  4250. ctx.builder.select();
  4251. }
  4252. match &ins {
  4253. String::LODS => {
  4254. if ctx.cpu.asize_32() {
  4255. codegen::gen_get_reg32(ctx, regs::ESI);
  4256. }
  4257. else {
  4258. codegen::gen_get_reg16(ctx, regs::ESI);
  4259. }
  4260. jit_add_seg_offset(ctx, regs::DS);
  4261. let address_local = ctx.builder.set_new_local();
  4262. if size == 8 {
  4263. codegen::gen_safe_read8(ctx, &address_local);
  4264. ctx.builder.free_local(address_local);
  4265. codegen::gen_set_reg8_unmasked(ctx, regs::AL);
  4266. }
  4267. else if size == 16 {
  4268. codegen::gen_safe_read16(ctx, &address_local);
  4269. ctx.builder.free_local(address_local);
  4270. codegen::gen_set_reg16(ctx, regs::AX);
  4271. }
  4272. else {
  4273. codegen::gen_safe_read32(ctx, &address_local);
  4274. ctx.builder.free_local(address_local);
  4275. codegen::gen_set_reg32(ctx, regs::EAX);
  4276. }
  4277. codegen::gen_get_reg32(ctx, regs::ESI);
  4278. get_direction(ctx, size);
  4279. ctx.builder.add_i32();
  4280. if ctx.cpu.asize_32() {
  4281. codegen::gen_set_reg32(ctx, regs::ESI);
  4282. }
  4283. else {
  4284. codegen::gen_set_reg16(ctx, regs::ESI);
  4285. }
  4286. return;
  4287. },
  4288. String::SCAS => {
  4289. if ctx.cpu.asize_32() {
  4290. codegen::gen_get_reg32(ctx, regs::EDI);
  4291. }
  4292. else {
  4293. codegen::gen_get_reg16(ctx, regs::EDI);
  4294. }
  4295. jit_add_seg_offset_no_override(ctx, regs::ES);
  4296. let address_local = ctx.builder.set_new_local();
  4297. if size == 8 {
  4298. codegen::gen_safe_read8(ctx, &address_local);
  4299. ctx.builder.free_local(address_local);
  4300. let value = ctx.builder.set_new_local();
  4301. gen_cmp8(
  4302. ctx,
  4303. &ctx.reg(regs::EAX),
  4304. &LocalOrImmediate::WasmLocal(&value),
  4305. );
  4306. ctx.builder.free_local(value);
  4307. }
  4308. else if size == 16 {
  4309. codegen::gen_safe_read16(ctx, &address_local);
  4310. ctx.builder.free_local(address_local);
  4311. let value = ctx.builder.set_new_local();
  4312. gen_cmp16(
  4313. ctx,
  4314. &ctx.reg(regs::EAX),
  4315. &LocalOrImmediate::WasmLocal(&value),
  4316. );
  4317. ctx.builder.free_local(value);
  4318. }
  4319. else {
  4320. codegen::gen_safe_read32(ctx, &address_local);
  4321. ctx.builder.free_local(address_local);
  4322. let value = ctx.builder.set_new_local();
  4323. gen_cmp32(
  4324. ctx,
  4325. &ctx.reg(regs::EAX),
  4326. &LocalOrImmediate::WasmLocal(&value),
  4327. );
  4328. ctx.builder.free_local(value);
  4329. }
  4330. codegen::gen_get_reg32(ctx, regs::EDI);
  4331. get_direction(ctx, size);
  4332. ctx.builder.add_i32();
  4333. if ctx.cpu.asize_32() {
  4334. codegen::gen_set_reg32(ctx, regs::EDI);
  4335. }
  4336. else {
  4337. codegen::gen_set_reg16(ctx, regs::EDI);
  4338. }
  4339. return;
  4340. },
  4341. String::STOS => {
  4342. if ctx.cpu.asize_32() {
  4343. codegen::gen_get_reg32(ctx, regs::EDI);
  4344. }
  4345. else {
  4346. codegen::gen_get_reg16(ctx, regs::EDI);
  4347. }
  4348. jit_add_seg_offset_no_override(ctx, regs::ES);
  4349. let address_local = ctx.builder.set_new_local();
  4350. if size == 8 {
  4351. codegen::gen_safe_write8(ctx, &address_local, &ctx.reg(regs::AL));
  4352. ctx.builder.free_local(address_local);
  4353. }
  4354. else if size == 16 {
  4355. codegen::gen_safe_write16(ctx, &address_local, &ctx.reg(regs::AX));
  4356. ctx.builder.free_local(address_local);
  4357. }
  4358. else {
  4359. codegen::gen_safe_write32(ctx, &address_local, &ctx.reg(regs::EAX));
  4360. ctx.builder.free_local(address_local);
  4361. }
  4362. codegen::gen_get_reg32(ctx, regs::EDI);
  4363. get_direction(ctx, size);
  4364. ctx.builder.add_i32();
  4365. if ctx.cpu.asize_32() {
  4366. codegen::gen_set_reg32(ctx, regs::EDI);
  4367. }
  4368. else {
  4369. codegen::gen_set_reg16(ctx, regs::EDI);
  4370. }
  4371. return;
  4372. },
  4373. String::MOVS => {
  4374. if ctx.cpu.asize_32() {
  4375. codegen::gen_get_reg32(ctx, regs::EDI);
  4376. }
  4377. else {
  4378. codegen::gen_get_reg16(ctx, regs::EDI);
  4379. }
  4380. jit_add_seg_offset_no_override(ctx, regs::ES);
  4381. let dest_address = ctx.builder.set_new_local();
  4382. if ctx.cpu.asize_32() {
  4383. codegen::gen_get_reg32(ctx, regs::ESI);
  4384. }
  4385. else {
  4386. codegen::gen_get_reg16(ctx, regs::ESI);
  4387. }
  4388. jit_add_seg_offset(ctx, regs::DS);
  4389. let source_address = ctx.builder.set_new_local();
  4390. if size == 8 {
  4391. codegen::gen_safe_read8(ctx, &source_address);
  4392. ctx.builder.free_local(source_address);
  4393. let value = ctx.builder.set_new_local();
  4394. codegen::gen_safe_write8(ctx, &dest_address, &value);
  4395. ctx.builder.free_local(value);
  4396. }
  4397. else if size == 16 {
  4398. codegen::gen_safe_read16(ctx, &source_address);
  4399. ctx.builder.free_local(source_address);
  4400. let value = ctx.builder.set_new_local();
  4401. codegen::gen_safe_write16(ctx, &dest_address, &value);
  4402. ctx.builder.free_local(value);
  4403. }
  4404. else {
  4405. codegen::gen_safe_read32(ctx, &source_address);
  4406. ctx.builder.free_local(source_address);
  4407. let value = ctx.builder.set_new_local();
  4408. codegen::gen_safe_write32(ctx, &dest_address, &value);
  4409. ctx.builder.free_local(value);
  4410. }
  4411. ctx.builder.free_local(dest_address);
  4412. codegen::gen_get_reg32(ctx, regs::EDI);
  4413. get_direction(ctx, size);
  4414. ctx.builder.add_i32();
  4415. if ctx.cpu.asize_32() {
  4416. codegen::gen_set_reg32(ctx, regs::EDI);
  4417. }
  4418. else {
  4419. codegen::gen_set_reg16(ctx, regs::EDI);
  4420. }
  4421. codegen::gen_get_reg32(ctx, regs::ESI);
  4422. get_direction(ctx, size);
  4423. ctx.builder.add_i32();
  4424. if ctx.cpu.asize_32() {
  4425. codegen::gen_set_reg32(ctx, regs::ESI);
  4426. }
  4427. else {
  4428. codegen::gen_set_reg16(ctx, regs::ESI);
  4429. }
  4430. return;
  4431. },
  4432. _ => {},
  4433. }
  4434. }
  4435. let mut args = 0;
  4436. args += 1;
  4437. ctx.builder.const_i32(ctx.cpu.asize_32() as i32);
  4438. if ins == String::OUTS || ins == String::CMPS || ins == String::LODS || ins == String::MOVS {
  4439. args += 1;
  4440. ctx.builder.const_i32(0);
  4441. jit_add_seg_offset(ctx, regs::DS);
  4442. }
  4443. let name = format!(
  4444. "{}{}{}",
  4445. match ins {
  4446. String::INS => "ins",
  4447. String::OUTS => "outs",
  4448. String::MOVS => "movs",
  4449. String::CMPS => "cmps",
  4450. String::STOS => "stos",
  4451. String::LODS => "lods",
  4452. String::SCAS => "scas",
  4453. },
  4454. if size == 8 {
  4455. "b"
  4456. }
  4457. else if size == 16 {
  4458. "w"
  4459. }
  4460. else {
  4461. "d"
  4462. },
  4463. if prefix == 0xF2 || prefix == 0xF3 {
  4464. match ins {
  4465. String::CMPS | String::SCAS => {
  4466. if prefix == 0xF2 {
  4467. "_repnz"
  4468. }
  4469. else {
  4470. "_repz"
  4471. }
  4472. },
  4473. _ => "_rep",
  4474. }
  4475. }
  4476. else {
  4477. "_no_rep"
  4478. }
  4479. );
  4480. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4481. if args == 1 {
  4482. ctx.builder.call_fn1(&name)
  4483. }
  4484. else if args == 2 {
  4485. ctx.builder.call_fn2(&name)
  4486. }
  4487. else {
  4488. dbg_assert!(false);
  4489. }
  4490. codegen::gen_move_registers_from_memory_to_locals(ctx);
  4491. }
  4492. pub fn instr_6C_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 8, 0) }
  4493. pub fn instr_F26C_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 8, 0xF2) }
  4494. pub fn instr_F36C_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 8, 0xF3) }
  4495. pub fn instr16_6D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 16, 0) }
  4496. pub fn instr16_F26D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 16, 0xF2) }
  4497. pub fn instr16_F36D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 16, 0xF3) }
  4498. pub fn instr32_6D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 32, 0) }
  4499. pub fn instr32_F26D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 32, 0xF2) }
  4500. pub fn instr32_F36D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 32, 0xF3) }
  4501. pub fn instr_6E_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 8, 0) }
  4502. pub fn instr_F26E_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 8, 0xF2) }
  4503. pub fn instr_F36E_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 8, 0xF3) }
  4504. pub fn instr16_6F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 16, 0) }
  4505. pub fn instr16_F26F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 16, 0xF2) }
  4506. pub fn instr16_F36F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 16, 0xF3) }
  4507. pub fn instr32_6F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 32, 0) }
  4508. pub fn instr32_F26F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 32, 0xF2) }
  4509. pub fn instr32_F36F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 32, 0xF3) }
  4510. pub fn instr_A4_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 8, 0) }
  4511. pub fn instr_F2A4_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 8, 0xF2) }
  4512. pub fn instr_F3A4_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 8, 0xF3) }
  4513. pub fn instr16_A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 16, 0) }
  4514. pub fn instr16_F2A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 16, 0xF2) }
  4515. pub fn instr16_F3A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 16, 0xF3) }
  4516. pub fn instr32_A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 32, 0) }
  4517. pub fn instr32_F2A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 32, 0xF2) }
  4518. pub fn instr32_F3A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 32, 0xF3) }
  4519. pub fn instr_A6_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 8, 0) }
  4520. pub fn instr_F2A6_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 8, 0xF2) }
  4521. pub fn instr_F3A6_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 8, 0xF3) }
  4522. pub fn instr16_A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 16, 0) }
  4523. pub fn instr16_F2A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 16, 0xF2) }
  4524. pub fn instr16_F3A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 16, 0xF3) }
  4525. pub fn instr32_A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 32, 0) }
  4526. pub fn instr32_F2A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 32, 0xF2) }
  4527. pub fn instr32_F3A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 32, 0xF3) }
  4528. pub fn instr_AA_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 8, 0) }
  4529. pub fn instr_F2AA_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 8, 0xF2) }
  4530. pub fn instr_F3AA_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 8, 0xF3) }
  4531. pub fn instr16_AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 16, 0) }
  4532. pub fn instr16_F2AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 16, 0xF2) }
  4533. pub fn instr16_F3AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 16, 0xF3) }
  4534. pub fn instr32_AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 32, 0) }
  4535. pub fn instr32_F2AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 32, 0xF2) }
  4536. pub fn instr32_F3AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 32, 0xF3) }
  4537. pub fn instr_AC_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 8, 0) }
  4538. pub fn instr_F2AC_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 8, 0xF2) }
  4539. pub fn instr_F3AC_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 8, 0xF3) }
  4540. pub fn instr16_AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 16, 0) }
  4541. pub fn instr16_F2AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 16, 0xF2) }
  4542. pub fn instr16_F3AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 16, 0xF3) }
  4543. pub fn instr32_AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 32, 0) }
  4544. pub fn instr32_F2AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 32, 0xF2) }
  4545. pub fn instr32_F3AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 32, 0xF3) }
  4546. pub fn instr_AE_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 8, 0) }
  4547. pub fn instr_F2AE_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 8, 0xF2) }
  4548. pub fn instr_F3AE_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 8, 0xF3) }
  4549. pub fn instr16_AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 16, 0) }
  4550. pub fn instr16_F2AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 16, 0xF2) }
  4551. pub fn instr16_F3AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 16, 0xF3) }
  4552. pub fn instr32_AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 32, 0) }
  4553. pub fn instr32_F2AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 32, 0xF2) }
  4554. pub fn instr32_F3AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 32, 0xF3) }
  4555. pub fn instr_0F31_jit(ctx: &mut JitContext) {
  4556. ctx.builder.load_fixed_u8(global_pointers::cpl as u32);
  4557. ctx.builder.eqz_i32();
  4558. dbg_assert!(regs::CR4_TSD < 0x100);
  4559. ctx.builder
  4560. .load_fixed_u8(global_pointers::get_creg_offset(4));
  4561. ctx.builder.const_i32(regs::CR4_TSD as i32);
  4562. ctx.builder.and_i32();
  4563. ctx.builder.eqz_i32();
  4564. ctx.builder.or_i32();
  4565. ctx.builder.if_void();
  4566. ctx.builder.call_fn0_ret_i64("read_tsc");
  4567. let tsc = ctx.builder.tee_new_local_i64();
  4568. ctx.builder.wrap_i64_to_i32();
  4569. codegen::gen_set_reg32(ctx, regs::EAX);
  4570. ctx.builder.get_local_i64(&tsc);
  4571. ctx.builder.const_i64(32);
  4572. ctx.builder.shr_u_i64();
  4573. ctx.builder.wrap_i64_to_i32();
  4574. codegen::gen_set_reg32(ctx, regs::EDX);
  4575. ctx.builder.free_local_i64(tsc);
  4576. ctx.builder.else_();
  4577. codegen::gen_trigger_gp(ctx, 0);
  4578. ctx.builder.block_end();
  4579. }
  4580. pub fn instr_0F0B_jit(ctx: &mut JitContext) { codegen::gen_trigger_ud(ctx) }
  4581. pub fn instr_0F18_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4582. pub fn instr_0F18_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4583. pub fn instr_0F19_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4584. pub fn instr_0F19_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4585. pub fn instr_0F1C_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4586. pub fn instr_0F1C_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4587. pub fn instr_0F1D_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4588. pub fn instr_0F1D_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4589. pub fn instr_0F1E_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4590. pub fn instr_0F1E_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4591. pub fn instr_0F1F_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4592. pub fn instr_0F1F_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4593. define_instruction_read_write_mem16!(
  4594. "shld16",
  4595. instr16_0FA4_mem_jit,
  4596. instr16_0FA4_reg_jit,
  4597. reg,
  4598. imm8_5bits
  4599. );
  4600. define_instruction_read_write_mem32!(
  4601. "shld32",
  4602. instr32_0FA4_mem_jit,
  4603. instr32_0FA4_reg_jit,
  4604. reg,
  4605. imm8_5bits
  4606. );
  4607. define_instruction_read_write_mem16!(
  4608. "shld16",
  4609. instr16_0FA5_mem_jit,
  4610. instr16_0FA5_reg_jit,
  4611. reg,
  4612. cl
  4613. );
  4614. define_instruction_read_write_mem32!(
  4615. "shld32",
  4616. instr32_0FA5_mem_jit,
  4617. instr32_0FA5_reg_jit,
  4618. reg,
  4619. cl
  4620. );
  4621. define_instruction_read_write_mem16!(
  4622. "shrd16",
  4623. instr16_0FAC_mem_jit,
  4624. instr16_0FAC_reg_jit,
  4625. reg,
  4626. imm8_5bits
  4627. );
  4628. define_instruction_read_write_mem32!(
  4629. "shrd32",
  4630. instr32_0FAC_mem_jit,
  4631. instr32_0FAC_reg_jit,
  4632. reg,
  4633. imm8_5bits
  4634. );
  4635. define_instruction_read_write_mem16!(
  4636. "shrd16",
  4637. instr16_0FAD_mem_jit,
  4638. instr16_0FAD_reg_jit,
  4639. reg,
  4640. cl
  4641. );
  4642. define_instruction_read_write_mem32!(
  4643. "shrd32",
  4644. instr32_0FAD_mem_jit,
  4645. instr32_0FAD_reg_jit,
  4646. reg,
  4647. cl
  4648. );
  4649. pub fn instr16_0FB1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4650. codegen::gen_get_reg16(ctx, r1);
  4651. ctx.builder.const_i32(r2 as i32);
  4652. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4653. ctx.builder.call_fn2_ret("cmpxchg16");
  4654. codegen::gen_move_registers_from_memory_to_locals(ctx);
  4655. codegen::gen_set_reg16(ctx, r1);
  4656. }
  4657. pub fn instr16_0FB1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4658. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4659. let address_local = ctx.builder.set_new_local();
  4660. codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
  4661. ctx.builder.const_i32(r as i32);
  4662. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4663. ctx.builder.call_fn2_ret("cmpxchg16");
  4664. codegen::gen_move_registers_from_memory_to_locals(ctx);
  4665. });
  4666. ctx.builder.free_local(address_local);
  4667. }
  4668. pub fn instr32_0FB1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4669. codegen::gen_get_reg32(ctx, r1);
  4670. gen_cmpxchg32(ctx, r2);
  4671. codegen::gen_set_reg32(ctx, r1);
  4672. }
  4673. pub fn instr32_0FB1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4674. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4675. let address_local = ctx.builder.set_new_local();
  4676. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
  4677. gen_cmpxchg32(ctx, r);
  4678. });
  4679. ctx.builder.free_local(address_local);
  4680. }
  4681. pub fn instr16_0FB6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4682. codegen::gen_get_reg8(ctx, r1);
  4683. codegen::gen_set_reg16_unmasked(ctx, r2);
  4684. }
  4685. pub fn instr16_0FB6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4686. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
  4687. codegen::gen_set_reg16_unmasked(ctx, r);
  4688. }
  4689. pub fn instr32_0FB6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4690. codegen::gen_get_reg8(ctx, r1);
  4691. codegen::gen_set_reg32(ctx, r2);
  4692. }
  4693. pub fn instr32_0FB6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4694. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
  4695. codegen::gen_set_reg32(ctx, r);
  4696. }
  4697. pub fn instr16_0FB7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4698. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  4699. codegen::gen_set_reg16(ctx, r);
  4700. }
  4701. pub fn instr16_0FB7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4702. codegen::gen_get_reg16(ctx, r1);
  4703. codegen::gen_set_reg16(ctx, r2);
  4704. }
  4705. pub fn instr32_0FB7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4706. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  4707. codegen::gen_set_reg32(ctx, r);
  4708. }
  4709. pub fn instr32_0FB7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4710. codegen::gen_get_reg16(ctx, r1);
  4711. codegen::gen_set_reg32(ctx, r2);
  4712. }
  4713. pub fn instr16_F30FB8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4714. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  4715. ctx.builder.call_fn1_ret("popcnt");
  4716. codegen::gen_set_reg16(ctx, r);
  4717. }
  4718. pub fn instr16_F30FB8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4719. codegen::gen_get_reg16(ctx, r1);
  4720. ctx.builder.call_fn1_ret("popcnt");
  4721. codegen::gen_set_reg16(ctx, r2);
  4722. }
  4723. pub fn instr32_F30FB8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4724. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  4725. ctx.builder.call_fn1_ret("popcnt");
  4726. codegen::gen_set_reg32(ctx, r);
  4727. }
  4728. pub fn instr32_F30FB8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4729. codegen::gen_get_reg32(ctx, r1);
  4730. ctx.builder.call_fn1_ret("popcnt");
  4731. codegen::gen_set_reg32(ctx, r2);
  4732. }
  4733. define_instruction_write_reg16!("bsf16", instr16_0FBC_mem_jit, instr16_0FBC_reg_jit);
  4734. define_instruction_write_reg32!(gen_bsf32, instr32_0FBC_mem_jit, instr32_0FBC_reg_jit);
  4735. define_instruction_write_reg16!("bsr16", instr16_0FBD_mem_jit, instr16_0FBD_reg_jit);
  4736. define_instruction_write_reg32!(gen_bsr32, instr32_0FBD_mem_jit, instr32_0FBD_reg_jit);
  4737. pub fn instr16_0FBE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4738. codegen::gen_get_reg8(ctx, r1);
  4739. codegen::sign_extend_i8(ctx.builder);
  4740. codegen::gen_set_reg16(ctx, r2);
  4741. }
  4742. pub fn instr16_0FBE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4743. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte); // TODO: Could use sign-extended read
  4744. codegen::sign_extend_i8(ctx.builder);
  4745. codegen::gen_set_reg16(ctx, r);
  4746. }
  4747. pub fn instr32_0FBE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4748. match r1 {
  4749. regs::AL | regs::CL | regs::DL | regs::BL => {
  4750. ctx.builder.get_local(&ctx.register_locals[r1 as usize]);
  4751. ctx.builder.const_i32(24);
  4752. ctx.builder.shl_i32();
  4753. },
  4754. regs::AH | regs::CH | regs::DH | regs::BH => {
  4755. ctx.builder
  4756. .get_local(&ctx.register_locals[(r1 - 4) as usize]);
  4757. ctx.builder.const_i32(16);
  4758. ctx.builder.shl_i32();
  4759. },
  4760. _ => assert!(false),
  4761. }
  4762. ctx.builder.const_i32(24);
  4763. ctx.builder.shr_s_i32();
  4764. codegen::gen_set_reg32(ctx, r2);
  4765. }
  4766. pub fn instr32_0FBE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4767. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte); // TODO: Could use sign-extended read
  4768. codegen::sign_extend_i8(ctx.builder);
  4769. codegen::gen_set_reg32(ctx, r);
  4770. }
  4771. pub fn instr16_0FBF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4772. codegen::gen_get_reg16(ctx, r1);
  4773. codegen::gen_set_reg16_unmasked(ctx, r2);
  4774. }
  4775. pub fn instr16_0FBF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4776. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  4777. codegen::gen_set_reg16_unmasked(ctx, r);
  4778. }
  4779. pub fn instr32_0FBF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4780. codegen::gen_get_reg32(ctx, r1);
  4781. codegen::sign_extend_i16(ctx.builder);
  4782. codegen::gen_set_reg32(ctx, r2);
  4783. }
  4784. pub fn instr32_0FBF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4785. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte); // TODO: Could use sign-extended read
  4786. codegen::sign_extend_i16(ctx.builder);
  4787. codegen::gen_set_reg32(ctx, r);
  4788. }
  4789. pub fn instr16_0FC1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4790. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4791. let address_local = ctx.builder.set_new_local();
  4792. codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
  4793. ctx.builder.const_i32(r as i32);
  4794. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4795. ctx.builder.call_fn2_ret("xadd16");
  4796. codegen::gen_move_registers_from_memory_to_locals(ctx);
  4797. });
  4798. ctx.builder.free_local(address_local);
  4799. }
  4800. pub fn instr16_0FC1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4801. codegen::gen_get_reg16(ctx, r1);
  4802. ctx.builder.const_i32(r2 as i32);
  4803. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4804. ctx.builder.call_fn2_ret("xadd16");
  4805. codegen::gen_move_registers_from_memory_to_locals(ctx);
  4806. codegen::gen_set_reg16(ctx, r1);
  4807. }
  4808. pub fn instr32_0FC1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4809. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4810. let address_local = ctx.builder.set_new_local();
  4811. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
  4812. let dest_operand = ctx.builder.set_new_local();
  4813. gen_xadd32(ctx, &dest_operand, r);
  4814. ctx.builder.get_local(&dest_operand);
  4815. ctx.builder.free_local(dest_operand);
  4816. });
  4817. ctx.builder.free_local(address_local);
  4818. }
  4819. pub fn instr32_0FC1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4820. codegen::gen_get_reg32(ctx, r1);
  4821. let dest_operand = ctx.builder.set_new_local();
  4822. gen_xadd32(ctx, &dest_operand, r2);
  4823. ctx.builder.get_local(&dest_operand);
  4824. codegen::gen_set_reg32(ctx, r1);
  4825. ctx.builder.free_local(dest_operand);
  4826. }
  4827. pub fn instr_0FC3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4828. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4829. let address_local = ctx.builder.set_new_local();
  4830. codegen::gen_safe_write32(ctx, &address_local, &ctx.reg(r));
  4831. ctx.builder.free_local(address_local);
  4832. }
  4833. pub fn instr_0FC3_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) { codegen::gen_trigger_ud(ctx) }
  4834. pub fn instr_0FC4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4835. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4836. let address_local = ctx.builder.set_new_local();
  4837. codegen::gen_safe_read16(ctx, &address_local);
  4838. ctx.builder.const_i32(r as i32);
  4839. ctx.builder.const_i32(imm8 as i32);
  4840. ctx.builder.call_fn3("instr_0FC4");
  4841. ctx.builder.free_local(address_local);
  4842. }
  4843. pub fn instr_0FC4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4844. codegen::gen_get_reg32(ctx, r1);
  4845. ctx.builder.const_i32(r2 as i32);
  4846. ctx.builder.const_i32(imm8 as i32);
  4847. ctx.builder.call_fn3("instr_0FC4");
  4848. }
  4849. pub fn instr_660FC4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4850. ctx.builder.const_i32(0);
  4851. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4852. let address_local = ctx.builder.set_new_local();
  4853. codegen::gen_safe_read16(ctx, &address_local);
  4854. ctx.builder
  4855. .store_aligned_u16(global_pointers::get_reg_xmm_offset(r) + ((imm8 & 7) << 1));
  4856. ctx.builder.free_local(address_local);
  4857. }
  4858. pub fn instr_660FC4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4859. ctx.builder.const_i32(0);
  4860. codegen::gen_get_reg32(ctx, r1);
  4861. ctx.builder
  4862. .store_aligned_u16(global_pointers::get_reg_xmm_offset(r2) + ((imm8 & 7) << 1));
  4863. }
  4864. pub fn instr_0FC5_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32, _imm8: u32) {
  4865. codegen::gen_trigger_ud(ctx)
  4866. }
  4867. pub fn instr_0FC5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4868. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4869. ctx.builder.const_i32(r1 as i32);
  4870. ctx.builder.const_i32(r2 as i32);
  4871. ctx.builder.const_i32(imm8 as i32);
  4872. ctx.builder.call_fn3("instr_0FC5_reg");
  4873. codegen::gen_move_registers_from_memory_to_locals(ctx);
  4874. }
  4875. pub fn instr_660FC5_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32, _imm8: u32) {
  4876. codegen::gen_trigger_ud(ctx)
  4877. }
  4878. pub fn instr_660FC5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4879. ctx.builder
  4880. .load_fixed_u16(global_pointers::get_reg_xmm_offset(r1) + ((imm8 & 7) << 1));
  4881. codegen::gen_set_reg32(ctx, r2);
  4882. }
  4883. pub fn instr16_0FC7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  4884. // cmpxchg8b
  4885. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4886. let address_local = ctx.builder.set_new_local();
  4887. codegen::gen_safe_read_write(ctx, BitSize::QWORD, &address_local, &|ref mut ctx| {
  4888. let dest_operand = ctx.builder.tee_new_local_i64();
  4889. codegen::gen_get_reg32(ctx, regs::EDX);
  4890. ctx.builder.extend_unsigned_i32_to_i64();
  4891. ctx.builder.const_i64(32);
  4892. ctx.builder.shl_i64();
  4893. codegen::gen_get_reg32(ctx, regs::EAX);
  4894. ctx.builder.extend_unsigned_i32_to_i64();
  4895. ctx.builder.or_i64();
  4896. ctx.builder.eq_i64();
  4897. ctx.builder.if_i64();
  4898. {
  4899. codegen::gen_set_flags_bits(ctx.builder, FLAG_ZERO);
  4900. codegen::gen_get_reg32(ctx, regs::ECX);
  4901. ctx.builder.extend_unsigned_i32_to_i64();
  4902. ctx.builder.const_i64(32);
  4903. ctx.builder.shl_i64();
  4904. codegen::gen_get_reg32(ctx, regs::EBX);
  4905. ctx.builder.extend_unsigned_i32_to_i64();
  4906. ctx.builder.or_i64();
  4907. }
  4908. ctx.builder.else_();
  4909. {
  4910. codegen::gen_clear_flags_bits(ctx.builder, FLAG_ZERO);
  4911. ctx.builder.get_local_i64(&dest_operand);
  4912. ctx.builder.wrap_i64_to_i32();
  4913. codegen::gen_set_reg32(ctx, regs::EAX);
  4914. ctx.builder.get_local_i64(&dest_operand);
  4915. ctx.builder.const_i64(32);
  4916. ctx.builder.shr_u_i64();
  4917. ctx.builder.wrap_i64_to_i32();
  4918. codegen::gen_set_reg32(ctx, regs::EDX);
  4919. ctx.builder.get_local_i64(&dest_operand);
  4920. }
  4921. ctx.builder.block_end();
  4922. codegen::gen_clear_flags_changed_bits(ctx.builder, FLAG_ZERO);
  4923. ctx.builder.free_local_i64(dest_operand);
  4924. });
  4925. ctx.builder.free_local(address_local);
  4926. }
  4927. pub fn instr16_0FC7_1_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx); }
  4928. pub fn instr32_0FC7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  4929. instr16_0FC7_1_mem_jit(ctx, modrm_byte);
  4930. }
  4931. pub fn instr32_0FC7_1_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx); }
  4932. pub fn instr_0FC2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4933. sse_read128_xmm_xmm_imm(ctx, "instr_0FC2", r1, r2, imm8)
  4934. }
  4935. pub fn instr_0FC2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4936. sse_read128_xmm_mem_imm(ctx, "instr_0FC2", modrm_byte, r, imm8)
  4937. }
  4938. pub fn instr_660FC2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4939. sse_read128_xmm_xmm_imm(ctx, "instr_660FC2", r1, r2, imm8)
  4940. }
  4941. pub fn instr_660FC2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4942. sse_read128_xmm_mem_imm(ctx, "instr_660FC2", modrm_byte, r, imm8)
  4943. }
  4944. pub fn instr_F20FC2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4945. ctx.builder
  4946. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  4947. ctx.builder.load_aligned_i64(0);
  4948. ctx.builder.const_i32(r2 as i32);
  4949. ctx.builder.const_i32(imm8 as i32);
  4950. ctx.builder.call_fn3_i64_i32_i32("instr_F20FC2");
  4951. }
  4952. pub fn instr_F20FC2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4953. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  4954. ctx.builder.const_i32(r as i32);
  4955. ctx.builder.const_i32(imm8 as i32);
  4956. ctx.builder.call_fn3_i64_i32_i32("instr_F20FC2");
  4957. }
  4958. pub fn instr_F30FC2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4959. ctx.builder
  4960. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  4961. ctx.builder.load_aligned_i32(0);
  4962. ctx.builder.const_i32(r2 as i32);
  4963. ctx.builder.const_i32(imm8 as i32);
  4964. ctx.builder.call_fn3("instr_F30FC2");
  4965. }
  4966. pub fn instr_F30FC2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4967. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  4968. ctx.builder.const_i32(r as i32);
  4969. ctx.builder.const_i32(imm8 as i32);
  4970. ctx.builder.call_fn3("instr_F30FC2");
  4971. }
  4972. pub fn instr_0FC6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4973. sse_read128_xmm_xmm_imm(ctx, "instr_0FC6", r1, r2, imm8)
  4974. }
  4975. pub fn instr_0FC6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4976. sse_read128_xmm_mem_imm(ctx, "instr_0FC6", modrm_byte, r, imm8)
  4977. }
  4978. pub fn instr_660FC6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4979. sse_read128_xmm_xmm_imm(ctx, "instr_660FC6", r1, r2, imm8)
  4980. }
  4981. pub fn instr_660FC6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4982. sse_read128_xmm_mem_imm(ctx, "instr_660FC6", modrm_byte, r, imm8)
  4983. }
  4984. pub fn instr_C6_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  4985. // reg8[r] = imm;
  4986. ctx.builder.const_i32(imm as i32);
  4987. codegen::gen_set_reg8_unmasked(ctx, r);
  4988. }
  4989. pub fn instr_C6_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  4990. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  4991. ctx.builder.const_i32(imm as i32);
  4992. let value_local = ctx.builder.set_new_local();
  4993. codegen::gen_safe_write8(ctx, &addr, &value_local);
  4994. ctx.builder.free_local(value_local);
  4995. });
  4996. }
  4997. pub fn instr16_C7_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  4998. // reg16[r] = imm;
  4999. ctx.builder.const_i32(imm as i32);
  5000. codegen::gen_set_reg16_unmasked(ctx, r);
  5001. }
  5002. pub fn instr16_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  5003. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  5004. ctx.builder.const_i32(imm as i32);
  5005. let value_local = ctx.builder.set_new_local();
  5006. codegen::gen_safe_write16(ctx, &addr, &value_local);
  5007. ctx.builder.free_local(value_local);
  5008. });
  5009. }
  5010. pub fn instr32_C7_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  5011. // reg32[r] = imm;
  5012. ctx.builder.const_i32(imm as i32);
  5013. codegen::gen_set_reg32(ctx, r);
  5014. }
  5015. pub fn instr32_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  5016. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  5017. ctx.builder.const_i32(imm as i32);
  5018. let value_local = ctx.builder.set_new_local();
  5019. codegen::gen_safe_write32(ctx, &addr, &value_local);
  5020. ctx.builder.free_local(value_local);
  5021. });
  5022. }
  5023. pub fn instr_0FC8_jit(ctx: &mut JitContext) { gen_bswap(ctx, 0) }
  5024. pub fn instr_0FC9_jit(ctx: &mut JitContext) { gen_bswap(ctx, 1) }
  5025. pub fn instr_0FCA_jit(ctx: &mut JitContext) { gen_bswap(ctx, 2) }
  5026. pub fn instr_0FCB_jit(ctx: &mut JitContext) { gen_bswap(ctx, 3) }
  5027. pub fn instr_0FCC_jit(ctx: &mut JitContext) { gen_bswap(ctx, 4) }
  5028. pub fn instr_0FCD_jit(ctx: &mut JitContext) { gen_bswap(ctx, 5) }
  5029. pub fn instr_0FCE_jit(ctx: &mut JitContext) { gen_bswap(ctx, 6) }
  5030. pub fn instr_0FCF_jit(ctx: &mut JitContext) { gen_bswap(ctx, 7) }
  5031. define_instruction_write_reg16!("imul_reg16", instr16_0FAF_mem_jit, instr16_0FAF_reg_jit);
  5032. define_instruction_write_reg32!(gen_imul_reg32, instr32_0FAF_mem_jit, instr32_0FAF_reg_jit);
  5033. macro_rules! define_cmovcc16(
  5034. ($cond:expr, $name_mem:ident, $name_reg:ident) => (
  5035. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5036. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  5037. let value = ctx.builder.set_new_local();
  5038. codegen::gen_condition_fn(ctx, $cond);
  5039. ctx.builder.if_void();
  5040. ctx.builder.get_local(&value);
  5041. codegen::gen_set_reg16(ctx, r);
  5042. ctx.builder.block_end();
  5043. ctx.builder.free_local(value);
  5044. }
  5045. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  5046. codegen::gen_condition_fn(ctx, $cond);
  5047. ctx.builder.if_void();
  5048. codegen::gen_get_reg16(ctx, r1);
  5049. codegen::gen_set_reg16(ctx, r2);
  5050. ctx.builder.block_end();
  5051. }
  5052. );
  5053. );
  5054. macro_rules! define_cmovcc32(
  5055. ($cond:expr, $name_mem:ident, $name_reg:ident) => (
  5056. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5057. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5058. let value = ctx.builder.set_new_local();
  5059. codegen::gen_condition_fn(ctx, $cond);
  5060. ctx.builder.if_void();
  5061. ctx.builder.get_local(&value);
  5062. codegen::gen_set_reg32(ctx, r);
  5063. ctx.builder.block_end();
  5064. ctx.builder.free_local(value);
  5065. }
  5066. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  5067. codegen::gen_condition_fn(ctx, $cond);
  5068. ctx.builder.if_void();
  5069. codegen::gen_get_reg32(ctx, r1);
  5070. codegen::gen_set_reg32(ctx, r2);
  5071. ctx.builder.block_end();
  5072. }
  5073. );
  5074. );
  5075. define_cmovcc16!(0x0, instr16_0F40_mem_jit, instr16_0F40_reg_jit);
  5076. define_cmovcc16!(0x1, instr16_0F41_mem_jit, instr16_0F41_reg_jit);
  5077. define_cmovcc16!(0x2, instr16_0F42_mem_jit, instr16_0F42_reg_jit);
  5078. define_cmovcc16!(0x3, instr16_0F43_mem_jit, instr16_0F43_reg_jit);
  5079. define_cmovcc16!(0x4, instr16_0F44_mem_jit, instr16_0F44_reg_jit);
  5080. define_cmovcc16!(0x5, instr16_0F45_mem_jit, instr16_0F45_reg_jit);
  5081. define_cmovcc16!(0x6, instr16_0F46_mem_jit, instr16_0F46_reg_jit);
  5082. define_cmovcc16!(0x7, instr16_0F47_mem_jit, instr16_0F47_reg_jit);
  5083. define_cmovcc16!(0x8, instr16_0F48_mem_jit, instr16_0F48_reg_jit);
  5084. define_cmovcc16!(0x9, instr16_0F49_mem_jit, instr16_0F49_reg_jit);
  5085. define_cmovcc16!(0xA, instr16_0F4A_mem_jit, instr16_0F4A_reg_jit);
  5086. define_cmovcc16!(0xB, instr16_0F4B_mem_jit, instr16_0F4B_reg_jit);
  5087. define_cmovcc16!(0xC, instr16_0F4C_mem_jit, instr16_0F4C_reg_jit);
  5088. define_cmovcc16!(0xD, instr16_0F4D_mem_jit, instr16_0F4D_reg_jit);
  5089. define_cmovcc16!(0xE, instr16_0F4E_mem_jit, instr16_0F4E_reg_jit);
  5090. define_cmovcc16!(0xF, instr16_0F4F_mem_jit, instr16_0F4F_reg_jit);
  5091. define_cmovcc32!(0x0, instr32_0F40_mem_jit, instr32_0F40_reg_jit);
  5092. define_cmovcc32!(0x1, instr32_0F41_mem_jit, instr32_0F41_reg_jit);
  5093. define_cmovcc32!(0x2, instr32_0F42_mem_jit, instr32_0F42_reg_jit);
  5094. define_cmovcc32!(0x3, instr32_0F43_mem_jit, instr32_0F43_reg_jit);
  5095. define_cmovcc32!(0x4, instr32_0F44_mem_jit, instr32_0F44_reg_jit);
  5096. define_cmovcc32!(0x5, instr32_0F45_mem_jit, instr32_0F45_reg_jit);
  5097. define_cmovcc32!(0x6, instr32_0F46_mem_jit, instr32_0F46_reg_jit);
  5098. define_cmovcc32!(0x7, instr32_0F47_mem_jit, instr32_0F47_reg_jit);
  5099. define_cmovcc32!(0x8, instr32_0F48_mem_jit, instr32_0F48_reg_jit);
  5100. define_cmovcc32!(0x9, instr32_0F49_mem_jit, instr32_0F49_reg_jit);
  5101. define_cmovcc32!(0xA, instr32_0F4A_mem_jit, instr32_0F4A_reg_jit);
  5102. define_cmovcc32!(0xB, instr32_0F4B_mem_jit, instr32_0F4B_reg_jit);
  5103. define_cmovcc32!(0xC, instr32_0F4C_mem_jit, instr32_0F4C_reg_jit);
  5104. define_cmovcc32!(0xD, instr32_0F4D_mem_jit, instr32_0F4D_reg_jit);
  5105. define_cmovcc32!(0xE, instr32_0F4E_mem_jit, instr32_0F4E_reg_jit);
  5106. define_cmovcc32!(0xF, instr32_0F4F_mem_jit, instr32_0F4F_reg_jit);
  5107. macro_rules! define_setcc(
  5108. ($cond:expr, $name_mem:ident, $name_reg:ident) => (
  5109. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, _r: u32) {
  5110. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  5111. codegen::gen_condition_fn(ctx, $cond);
  5112. ctx.builder.const_i32(0);
  5113. ctx.builder.ne_i32();
  5114. let value_local = ctx.builder.set_new_local();
  5115. codegen::gen_safe_write8(ctx, &addr, &value_local);
  5116. ctx.builder.free_local(value_local);
  5117. });
  5118. }
  5119. pub fn $name_reg(ctx: &mut JitContext, r1: u32, _r2: u32) {
  5120. codegen::gen_condition_fn(ctx, $cond);
  5121. ctx.builder.const_i32(0);
  5122. ctx.builder.ne_i32();
  5123. codegen::gen_set_reg8_unmasked(ctx, r1);
  5124. }
  5125. );
  5126. );
  5127. define_setcc!(0x0, instr_0F90_mem_jit, instr_0F90_reg_jit);
  5128. define_setcc!(0x1, instr_0F91_mem_jit, instr_0F91_reg_jit);
  5129. define_setcc!(0x2, instr_0F92_mem_jit, instr_0F92_reg_jit);
  5130. define_setcc!(0x3, instr_0F93_mem_jit, instr_0F93_reg_jit);
  5131. define_setcc!(0x4, instr_0F94_mem_jit, instr_0F94_reg_jit);
  5132. define_setcc!(0x5, instr_0F95_mem_jit, instr_0F95_reg_jit);
  5133. define_setcc!(0x6, instr_0F96_mem_jit, instr_0F96_reg_jit);
  5134. define_setcc!(0x7, instr_0F97_mem_jit, instr_0F97_reg_jit);
  5135. define_setcc!(0x8, instr_0F98_mem_jit, instr_0F98_reg_jit);
  5136. define_setcc!(0x9, instr_0F99_mem_jit, instr_0F99_reg_jit);
  5137. define_setcc!(0xA, instr_0F9A_mem_jit, instr_0F9A_reg_jit);
  5138. define_setcc!(0xB, instr_0F9B_mem_jit, instr_0F9B_reg_jit);
  5139. define_setcc!(0xC, instr_0F9C_mem_jit, instr_0F9C_reg_jit);
  5140. define_setcc!(0xD, instr_0F9D_mem_jit, instr_0F9D_reg_jit);
  5141. define_setcc!(0xE, instr_0F9E_mem_jit, instr_0F9E_reg_jit);
  5142. define_setcc!(0xF, instr_0F9F_mem_jit, instr_0F9F_reg_jit);
  5143. pub fn instr_0F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5144. let dest = global_pointers::get_reg_xmm_offset(r);
  5145. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5146. }
  5147. pub fn instr_0F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5148. pub fn instr_660F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5149. let dest = global_pointers::get_reg_xmm_offset(r);
  5150. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5151. }
  5152. pub fn instr_660F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5153. pub fn instr_F20F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5154. instr_F30F7E_mem_jit(ctx, modrm_byte, r)
  5155. }
  5156. pub fn instr_F20F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5157. ctx.builder.const_i32(0);
  5158. ctx.builder
  5159. .load_fixed_i64(global_pointers::get_reg_xmm_offset(r1));
  5160. ctx.builder
  5161. .store_aligned_i64(global_pointers::get_reg_xmm_offset(r2));
  5162. }
  5163. pub fn instr_F30F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5164. instr_660F6E_mem_jit(ctx, modrm_byte, r)
  5165. }
  5166. pub fn instr_F30F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5167. ctx.builder.const_i32(0);
  5168. ctx.builder
  5169. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r1));
  5170. ctx.builder
  5171. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2));
  5172. }
  5173. pub fn instr_0F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5174. instr_0F29_mem_jit(ctx, modrm_byte, r)
  5175. }
  5176. pub fn instr_0F11_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  5177. pub fn instr_660F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5178. instr_660F29_mem_jit(ctx, modrm_byte, r)
  5179. }
  5180. pub fn instr_660F11_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  5181. pub fn instr_F20F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5182. instr_660FD6_mem_jit(ctx, modrm_byte, r)
  5183. }
  5184. pub fn instr_F20F11_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5185. ctx.builder.const_i32(0);
  5186. ctx.builder
  5187. .load_fixed_i64(global_pointers::get_reg_xmm_offset(r2));
  5188. ctx.builder
  5189. .store_aligned_i64(global_pointers::get_reg_xmm_offset(r1));
  5190. }
  5191. pub fn instr_F30F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5192. instr_660F7E_mem_jit(ctx, modrm_byte, r)
  5193. }
  5194. pub fn instr_F30F11_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5195. ctx.builder.const_i32(0);
  5196. ctx.builder
  5197. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r2));
  5198. ctx.builder
  5199. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r1));
  5200. }
  5201. pub fn instr_0F12_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5202. ctx.builder
  5203. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
  5204. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5205. ctx.builder.store_aligned_i64(0);
  5206. }
  5207. pub fn instr_0F12_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5208. ctx.builder
  5209. .const_i32(global_pointers::get_reg_xmm_offset(r2) as i32);
  5210. ctx.builder
  5211. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32 + 8);
  5212. ctx.builder.load_aligned_i64(0);
  5213. ctx.builder.store_aligned_i64(0);
  5214. }
  5215. pub fn instr_660F12_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5216. ctx.builder
  5217. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
  5218. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5219. ctx.builder.store_aligned_i64(0);
  5220. }
  5221. pub fn instr_660F12_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5222. codegen::gen_trigger_ud(ctx);
  5223. }
  5224. pub fn instr_0F13_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5225. instr_660FD6_mem_jit(ctx, modrm_byte, r)
  5226. }
  5227. pub fn instr_0F13_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5228. codegen::gen_trigger_ud(ctx);
  5229. }
  5230. pub fn instr_660F13_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5231. instr_660FD6_mem_jit(ctx, modrm_byte, r)
  5232. }
  5233. pub fn instr_660F13_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5234. codegen::gen_trigger_ud(ctx);
  5235. }
  5236. pub fn instr_0F14_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5237. sse_read64_xmm_mem(ctx, "instr_0F14", modrm_byte, r);
  5238. }
  5239. pub fn instr_0F14_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5240. sse_read64_xmm_xmm(ctx, "instr_0F14", r1, r2);
  5241. }
  5242. pub fn instr_660F14_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5243. sse_read64_xmm_mem(ctx, "instr_660F14", modrm_byte, r);
  5244. }
  5245. pub fn instr_660F14_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5246. sse_read64_xmm_xmm(ctx, "instr_660F14", r1, r2);
  5247. }
  5248. pub fn instr_0F15_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5249. sse_read128_xmm_mem(ctx, "instr_0F15", modrm_byte, r);
  5250. }
  5251. pub fn instr_0F15_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5252. sse_read128_xmm_xmm(ctx, "instr_0F15", r1, r2);
  5253. }
  5254. pub fn instr_660F15_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5255. sse_read128_xmm_mem(ctx, "instr_660F15", modrm_byte, r);
  5256. }
  5257. pub fn instr_660F15_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5258. sse_read128_xmm_xmm(ctx, "instr_660F15", r1, r2);
  5259. }
  5260. pub fn instr_0F16_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5261. sse_read64_xmm_mem(ctx, "instr_0F16", modrm_byte, r);
  5262. }
  5263. pub fn instr_0F16_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5264. sse_read64_xmm_xmm(ctx, "instr_0F16", r1, r2);
  5265. }
  5266. pub fn instr_660F16_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5267. sse_read64_xmm_mem(ctx, "instr_0F16", modrm_byte, r);
  5268. }
  5269. pub fn instr_660F16_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5270. codegen::gen_trigger_ud(ctx);
  5271. }
  5272. pub fn instr_0F17_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5273. codegen::gen_modrm_resolve(ctx, modrm_byte);
  5274. let address_local = ctx.builder.set_new_local();
  5275. ctx.builder
  5276. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
  5277. ctx.builder.load_aligned_i64(8);
  5278. let value_local = ctx.builder.set_new_local_i64();
  5279. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  5280. ctx.builder.free_local(address_local);
  5281. ctx.builder.free_local_i64(value_local);
  5282. }
  5283. pub fn instr_0F17_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5284. codegen::gen_trigger_ud(ctx);
  5285. }
  5286. pub fn instr_660F17_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5287. instr_0F17_mem_jit(ctx, modrm_byte, r);
  5288. }
  5289. pub fn instr_660F17_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5290. codegen::gen_trigger_ud(ctx);
  5291. }
  5292. pub fn instr_0F28_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5293. let dest = global_pointers::get_reg_xmm_offset(r);
  5294. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5295. }
  5296. pub fn instr_0F28_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5297. pub fn instr_660F28_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5298. let dest = global_pointers::get_reg_xmm_offset(r);
  5299. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5300. }
  5301. pub fn instr_660F28_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5302. pub fn instr_0F29_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5303. // XXX: Aligned write or #gp
  5304. codegen::gen_modrm_resolve(ctx, modrm_byte);
  5305. let address_local = ctx.builder.set_new_local();
  5306. ctx.builder
  5307. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
  5308. ctx.builder.load_aligned_i64(0);
  5309. let value_local_low = ctx.builder.set_new_local_i64();
  5310. ctx.builder
  5311. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32 + 8);
  5312. ctx.builder.load_aligned_i64(0);
  5313. let value_local_high = ctx.builder.set_new_local_i64();
  5314. codegen::gen_safe_write128(ctx, &address_local, &value_local_low, &value_local_high);
  5315. ctx.builder.free_local(address_local);
  5316. ctx.builder.free_local_i64(value_local_low);
  5317. ctx.builder.free_local_i64(value_local_high);
  5318. }
  5319. pub fn instr_0F29_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  5320. pub fn instr_660F29_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5321. instr_0F29_mem_jit(ctx, modrm_byte, r);
  5322. }
  5323. pub fn instr_660F29_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  5324. pub fn instr_0F2A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5325. mmx_read64_mm_mem(ctx, "instr_0F2A", modrm_byte, r);
  5326. }
  5327. pub fn instr_0F2A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5328. mmx_read64_mm_mm(ctx, "instr_0F2A", r1, r2);
  5329. }
  5330. pub fn instr_660F2A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5331. mmx_read64_mm_mem(ctx, "instr_660F2A", modrm_byte, r);
  5332. }
  5333. pub fn instr_660F2A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5334. mmx_read64_mm_mm(ctx, "instr_660F2A", r1, r2);
  5335. }
  5336. pub fn instr_F20F2A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5337. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5338. ctx.builder.const_i32(r as i32);
  5339. ctx.builder.call_fn2("instr_F20F2A")
  5340. }
  5341. pub fn instr_F20F2A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5342. codegen::gen_get_reg32(ctx, r1);
  5343. ctx.builder.const_i32(r2 as i32);
  5344. ctx.builder.call_fn2("instr_F20F2A")
  5345. }
  5346. pub fn instr_F30F2A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5347. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5348. ctx.builder.const_i32(r as i32);
  5349. ctx.builder.call_fn2("instr_F30F2A")
  5350. }
  5351. pub fn instr_F30F2A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5352. codegen::gen_get_reg32(ctx, r1);
  5353. ctx.builder.const_i32(r2 as i32);
  5354. ctx.builder.call_fn2("instr_F30F2A")
  5355. }
  5356. pub fn instr_0F2B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5357. instr_0F29_mem_jit(ctx, modrm_byte, r)
  5358. }
  5359. pub fn instr_0F2B_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5360. codegen::gen_trigger_ud(ctx);
  5361. }
  5362. pub fn instr_660F2B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5363. instr_0F29_mem_jit(ctx, modrm_byte, r)
  5364. }
  5365. pub fn instr_660F2B_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5366. codegen::gen_trigger_ud(ctx);
  5367. }
  5368. pub fn instr_F20F2C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5369. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5370. ctx.builder.reinterpret_i64_as_f64();
  5371. ctx.builder
  5372. .call_fn1_f64_ret("sse_convert_with_truncation_f64_to_i32");
  5373. codegen::gen_set_reg32(ctx, r);
  5374. }
  5375. pub fn instr_F20F2C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5376. ctx.builder
  5377. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  5378. ctx.builder.load_aligned_f64(0);
  5379. ctx.builder
  5380. .call_fn1_f64_ret("sse_convert_with_truncation_f64_to_i32");
  5381. codegen::gen_set_reg32(ctx, r2);
  5382. }
  5383. pub fn instr_F30F2C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5384. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5385. ctx.builder.reinterpret_i32_as_f32();
  5386. ctx.builder
  5387. .call_fn1_f32_ret("sse_convert_with_truncation_f32_to_i32");
  5388. codegen::gen_set_reg32(ctx, r);
  5389. }
  5390. pub fn instr_F30F2C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5391. ctx.builder
  5392. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  5393. ctx.builder.load_aligned_f32(0);
  5394. ctx.builder
  5395. .call_fn1_f32_ret("sse_convert_with_truncation_f32_to_i32");
  5396. codegen::gen_set_reg32(ctx, r2);
  5397. }
  5398. pub fn instr_F20F2D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5399. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5400. ctx.builder.reinterpret_i64_as_f64();
  5401. ctx.builder.call_fn1_f64_ret("sse_convert_f64_to_i32");
  5402. codegen::gen_set_reg32(ctx, r);
  5403. }
  5404. pub fn instr_F20F2D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5405. ctx.builder
  5406. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  5407. ctx.builder.load_aligned_f64(0);
  5408. ctx.builder.call_fn1_f64_ret("sse_convert_f64_to_i32");
  5409. codegen::gen_set_reg32(ctx, r2);
  5410. }
  5411. pub fn instr_F30F2D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5412. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5413. ctx.builder.reinterpret_i32_as_f32();
  5414. ctx.builder.call_fn1_f32_ret("sse_convert_f32_to_i32");
  5415. codegen::gen_set_reg32(ctx, r);
  5416. }
  5417. pub fn instr_F30F2D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5418. ctx.builder
  5419. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  5420. ctx.builder.load_aligned_f32(0);
  5421. ctx.builder.call_fn1_f32_ret("sse_convert_f32_to_i32");
  5422. codegen::gen_set_reg32(ctx, r2);
  5423. }
  5424. pub fn instr_0F2E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5425. sse_read_f32_xmm_mem(ctx, "instr_0F2E", modrm_byte, r);
  5426. }
  5427. pub fn instr_0F2E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5428. sse_read_f32_xmm_xmm(ctx, "instr_0F2E", r1, r2);
  5429. }
  5430. pub fn instr_660F2E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5431. sse_read64_xmm_mem(ctx, "instr_660F2E", modrm_byte, r);
  5432. }
  5433. pub fn instr_660F2E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5434. sse_read64_xmm_xmm(ctx, "instr_660F2E", r1, r2);
  5435. }
  5436. pub fn instr_0F2F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5437. sse_read_f32_xmm_mem(ctx, "instr_0F2F", modrm_byte, r);
  5438. }
  5439. pub fn instr_0F2F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5440. sse_read_f32_xmm_xmm(ctx, "instr_0F2F", r1, r2);
  5441. }
  5442. pub fn instr_660F2F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5443. sse_read64_xmm_mem(ctx, "instr_660F2F", modrm_byte, r);
  5444. }
  5445. pub fn instr_660F2F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5446. sse_read64_xmm_xmm(ctx, "instr_660F2F", r1, r2);
  5447. }
  5448. pub fn instr_0F51_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5449. sse_read128_xmm_mem(ctx, "instr_0F51", modrm_byte, r);
  5450. }
  5451. pub fn instr_0F51_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5452. sse_read128_xmm_xmm(ctx, "instr_0F51", r1, r2);
  5453. }
  5454. pub fn instr_660F51_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5455. sse_read128_xmm_mem(ctx, "instr_660F51", modrm_byte, r);
  5456. }
  5457. pub fn instr_660F51_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5458. sse_read128_xmm_xmm(ctx, "instr_660F51", r1, r2);
  5459. }
  5460. pub fn instr_F20F51_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5461. sse_read64_xmm_mem(ctx, "instr_F20F51", modrm_byte, r);
  5462. }
  5463. pub fn instr_F20F51_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5464. sse_read64_xmm_xmm(ctx, "instr_F20F51", r1, r2);
  5465. }
  5466. pub fn instr_F30F51_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5467. sse_read_f32_xmm_mem(ctx, "instr_F30F51", modrm_byte, r);
  5468. }
  5469. pub fn instr_F30F51_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5470. sse_read_f32_xmm_xmm(ctx, "instr_F30F51", r1, r2);
  5471. }
  5472. pub fn instr_0F52_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5473. sse_read128_xmm_mem(ctx, "instr_0F52", modrm_byte, r);
  5474. }
  5475. pub fn instr_0F52_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5476. sse_read128_xmm_xmm(ctx, "instr_0F52", r1, r2);
  5477. }
  5478. pub fn instr_F30F52_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5479. sse_read_f32_xmm_mem(ctx, "instr_F30F52", modrm_byte, r);
  5480. }
  5481. pub fn instr_F30F52_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5482. sse_read_f32_xmm_xmm(ctx, "instr_F30F52", r1, r2);
  5483. }
  5484. pub fn instr_0F53_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5485. sse_read128_xmm_mem(ctx, "instr_0F53", modrm_byte, r);
  5486. }
  5487. pub fn instr_0F53_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5488. sse_read128_xmm_xmm(ctx, "instr_0F53", r1, r2);
  5489. }
  5490. pub fn instr_F30F53_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5491. sse_read_f32_xmm_mem(ctx, "instr_F30F53", modrm_byte, r);
  5492. }
  5493. pub fn instr_F30F53_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5494. sse_read_f32_xmm_xmm(ctx, "instr_F30F53", r1, r2);
  5495. }
  5496. pub fn instr_0F54_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5497. sse_read128_xmm_mem(ctx, "instr_0F54", modrm_byte, r);
  5498. }
  5499. pub fn instr_0F54_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5500. sse_read128_xmm_xmm(ctx, "instr_0F54", r1, r2);
  5501. }
  5502. pub fn instr_660F54_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5503. sse_read128_xmm_mem(ctx, "instr_660F54", modrm_byte, r);
  5504. }
  5505. pub fn instr_660F54_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5506. sse_read128_xmm_xmm(ctx, "instr_660F54", r1, r2);
  5507. }
  5508. pub fn instr_0F55_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5509. sse_read128_xmm_mem(ctx, "instr_0F55", modrm_byte, r);
  5510. }
  5511. pub fn instr_0F55_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5512. sse_read128_xmm_xmm(ctx, "instr_0F55", r1, r2);
  5513. }
  5514. pub fn instr_660F55_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5515. sse_read128_xmm_mem(ctx, "instr_660F55", modrm_byte, r);
  5516. }
  5517. pub fn instr_660F55_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5518. sse_read128_xmm_xmm(ctx, "instr_660F55", r1, r2);
  5519. }
  5520. pub fn instr_0F56_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5521. sse_read128_xmm_mem(ctx, "instr_0F56", modrm_byte, r);
  5522. }
  5523. pub fn instr_0F56_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5524. sse_read128_xmm_xmm(ctx, "instr_0F56", r1, r2);
  5525. }
  5526. pub fn instr_660F56_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5527. sse_read128_xmm_mem(ctx, "instr_660F56", modrm_byte, r);
  5528. }
  5529. pub fn instr_660F56_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5530. sse_read128_xmm_xmm(ctx, "instr_660F56", r1, r2);
  5531. }
  5532. pub fn instr_0F57_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5533. sse_read128_xmm_mem(ctx, "instr_0F57", modrm_byte, r);
  5534. }
  5535. pub fn instr_0F57_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5536. sse_read128_xmm_xmm(ctx, "instr_0F57", r1, r2);
  5537. }
  5538. pub fn instr_660F57_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5539. sse_read128_xmm_mem(ctx, "instr_660F57", modrm_byte, r);
  5540. }
  5541. pub fn instr_660F57_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5542. sse_read128_xmm_xmm(ctx, "instr_660F57", r1, r2);
  5543. }
  5544. pub fn instr_0F58_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5545. sse_read128_xmm_mem(ctx, "instr_0F58", modrm_byte, r);
  5546. }
  5547. pub fn instr_0F58_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5548. sse_read128_xmm_xmm(ctx, "instr_0F58", r1, r2);
  5549. }
  5550. pub fn instr_660F58_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5551. sse_read128_xmm_mem(ctx, "instr_660F58", modrm_byte, r);
  5552. }
  5553. pub fn instr_660F58_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5554. sse_read128_xmm_xmm(ctx, "instr_660F58", r1, r2);
  5555. }
  5556. pub fn instr_F20F58_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5557. sse_read64_xmm_mem(ctx, "instr_F20F58", modrm_byte, r);
  5558. }
  5559. pub fn instr_F20F58_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5560. sse_read64_xmm_xmm(ctx, "instr_F20F58", r1, r2);
  5561. }
  5562. pub fn instr_F30F58_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5563. sse_read_f32_xmm_mem(ctx, "instr_F30F58", modrm_byte, r);
  5564. }
  5565. pub fn instr_F30F58_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5566. sse_read_f32_xmm_xmm(ctx, "instr_F30F58", r1, r2);
  5567. }
  5568. pub fn instr_0F59_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5569. sse_read128_xmm_mem(ctx, "instr_0F59", modrm_byte, r);
  5570. }
  5571. pub fn instr_0F59_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5572. sse_read128_xmm_xmm(ctx, "instr_0F59", r1, r2);
  5573. }
  5574. pub fn instr_660F59_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5575. sse_read128_xmm_mem(ctx, "instr_660F59", modrm_byte, r);
  5576. }
  5577. pub fn instr_660F59_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5578. sse_read128_xmm_xmm(ctx, "instr_660F59", r1, r2);
  5579. }
  5580. pub fn instr_F20F59_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5581. sse_read64_xmm_mem(ctx, "instr_F20F59", modrm_byte, r);
  5582. }
  5583. pub fn instr_F20F59_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5584. sse_read64_xmm_xmm(ctx, "instr_F20F59", r1, r2);
  5585. }
  5586. pub fn instr_F30F59_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5587. sse_read_f32_xmm_mem(ctx, "instr_F30F59", modrm_byte, r);
  5588. }
  5589. pub fn instr_F30F59_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5590. sse_read_f32_xmm_xmm(ctx, "instr_F30F59", r1, r2);
  5591. }
  5592. pub fn instr_0F5A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5593. sse_read64_xmm_mem(ctx, "instr_0F5A", modrm_byte, r);
  5594. }
  5595. pub fn instr_0F5A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5596. sse_read64_xmm_xmm(ctx, "instr_0F5A", r1, r2);
  5597. }
  5598. pub fn instr_660F5A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5599. sse_read128_xmm_mem(ctx, "instr_660F5A", modrm_byte, r);
  5600. }
  5601. pub fn instr_660F5A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5602. sse_read128_xmm_xmm(ctx, "instr_660F5A", r1, r2);
  5603. }
  5604. pub fn instr_F20F5A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5605. sse_read64_xmm_mem(ctx, "instr_F20F5A", modrm_byte, r);
  5606. }
  5607. pub fn instr_F20F5A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5608. sse_read64_xmm_xmm(ctx, "instr_F20F5A", r1, r2);
  5609. }
  5610. pub fn instr_F30F5A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5611. sse_read_f32_xmm_mem(ctx, "instr_F30F5A", modrm_byte, r);
  5612. }
  5613. pub fn instr_F30F5A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5614. sse_read_f32_xmm_xmm(ctx, "instr_F30F5A", r1, r2);
  5615. }
  5616. pub fn instr_0F5B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5617. sse_read128_xmm_mem(ctx, "instr_0F5B", modrm_byte, r);
  5618. }
  5619. pub fn instr_0F5B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5620. sse_read128_xmm_xmm(ctx, "instr_0F5B", r1, r2);
  5621. }
  5622. pub fn instr_660F5B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5623. sse_read128_xmm_mem(ctx, "instr_660F5B", modrm_byte, r);
  5624. }
  5625. pub fn instr_660F5B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5626. sse_read128_xmm_xmm(ctx, "instr_660F5B", r1, r2);
  5627. }
  5628. pub fn instr_F30F5B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5629. sse_read128_xmm_mem(ctx, "instr_F30F5B", modrm_byte, r);
  5630. }
  5631. pub fn instr_F30F5B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5632. sse_read128_xmm_xmm(ctx, "instr_F30F5B", r1, r2);
  5633. }
  5634. pub fn instr_0F5C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5635. sse_read128_xmm_mem(ctx, "instr_0F5C", modrm_byte, r);
  5636. }
  5637. pub fn instr_0F5C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5638. sse_read128_xmm_xmm(ctx, "instr_0F5C", r1, r2);
  5639. }
  5640. pub fn instr_660F5C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5641. sse_read128_xmm_mem(ctx, "instr_660F5C", modrm_byte, r);
  5642. }
  5643. pub fn instr_660F5C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5644. sse_read128_xmm_xmm(ctx, "instr_660F5C", r1, r2);
  5645. }
  5646. pub fn instr_F20F5C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5647. sse_read64_xmm_mem(ctx, "instr_F20F5C", modrm_byte, r);
  5648. }
  5649. pub fn instr_F20F5C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5650. sse_read64_xmm_xmm(ctx, "instr_F20F5C", r1, r2);
  5651. }
  5652. pub fn instr_F30F5C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5653. sse_read_f32_xmm_mem(ctx, "instr_F30F5C", modrm_byte, r);
  5654. }
  5655. pub fn instr_F30F5C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5656. sse_read_f32_xmm_xmm(ctx, "instr_F30F5C", r1, r2);
  5657. }
  5658. pub fn instr_0F5D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5659. sse_read128_xmm_mem(ctx, "instr_0F5D", modrm_byte, r);
  5660. }
  5661. pub fn instr_0F5D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5662. sse_read128_xmm_xmm(ctx, "instr_0F5D", r1, r2);
  5663. }
  5664. pub fn instr_660F5D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5665. sse_read128_xmm_mem(ctx, "instr_660F5D", modrm_byte, r);
  5666. }
  5667. pub fn instr_660F5D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5668. sse_read128_xmm_xmm(ctx, "instr_660F5D", r1, r2);
  5669. }
  5670. pub fn instr_F20F5D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5671. sse_read64_xmm_mem(ctx, "instr_F20F5D", modrm_byte, r);
  5672. }
  5673. pub fn instr_F20F5D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5674. sse_read64_xmm_xmm(ctx, "instr_F20F5D", r1, r2);
  5675. }
  5676. pub fn instr_F30F5D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5677. sse_read_f32_xmm_mem(ctx, "instr_F30F5D", modrm_byte, r);
  5678. }
  5679. pub fn instr_F30F5D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5680. sse_read_f32_xmm_xmm(ctx, "instr_F30F5D", r1, r2);
  5681. }
  5682. pub fn instr_0F5E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5683. sse_read128_xmm_mem(ctx, "instr_0F5E", modrm_byte, r);
  5684. }
  5685. pub fn instr_0F5E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5686. sse_read128_xmm_xmm(ctx, "instr_0F5E", r1, r2);
  5687. }
  5688. pub fn instr_660F5E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5689. sse_read128_xmm_mem(ctx, "instr_660F5E", modrm_byte, r);
  5690. }
  5691. pub fn instr_660F5E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5692. sse_read128_xmm_xmm(ctx, "instr_660F5E", r1, r2);
  5693. }
  5694. pub fn instr_F20F5E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5695. sse_read64_xmm_mem(ctx, "instr_F20F5E", modrm_byte, r);
  5696. }
  5697. pub fn instr_F20F5E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5698. sse_read64_xmm_xmm(ctx, "instr_F20F5E", r1, r2);
  5699. }
  5700. pub fn instr_F30F5E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5701. sse_read_f32_xmm_mem(ctx, "instr_F30F5E", modrm_byte, r);
  5702. }
  5703. pub fn instr_F30F5E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5704. sse_read_f32_xmm_xmm(ctx, "instr_F30F5E", r1, r2);
  5705. }
  5706. pub fn instr_0F5F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5707. sse_read128_xmm_mem(ctx, "instr_0F5F", modrm_byte, r);
  5708. }
  5709. pub fn instr_0F5F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5710. sse_read128_xmm_xmm(ctx, "instr_0F5F", r1, r2);
  5711. }
  5712. pub fn instr_660F5F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5713. sse_read128_xmm_mem(ctx, "instr_660F5F", modrm_byte, r);
  5714. }
  5715. pub fn instr_660F5F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5716. sse_read128_xmm_xmm(ctx, "instr_660F5F", r1, r2);
  5717. }
  5718. pub fn instr_F20F5F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5719. sse_read64_xmm_mem(ctx, "instr_F20F5F", modrm_byte, r);
  5720. }
  5721. pub fn instr_F20F5F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5722. sse_read64_xmm_xmm(ctx, "instr_F20F5F", r1, r2);
  5723. }
  5724. pub fn instr_F30F5F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5725. sse_read_f32_xmm_mem(ctx, "instr_F30F5F", modrm_byte, r);
  5726. }
  5727. pub fn instr_F30F5F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5728. sse_read_f32_xmm_xmm(ctx, "instr_F30F5F", r1, r2);
  5729. }
  5730. pub fn instr_0F60_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5731. mmx_read64_mm_mem32(ctx, "instr_0F60", modrm_byte, r);
  5732. }
  5733. pub fn instr_0F60_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5734. mmx_read64_mm_mm32(ctx, "instr_0F60", r1, r2);
  5735. }
  5736. pub fn instr_0F61_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5737. mmx_read64_mm_mem32(ctx, "instr_0F61", modrm_byte, r);
  5738. }
  5739. pub fn instr_0F61_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5740. mmx_read64_mm_mm32(ctx, "instr_0F61", r1, r2);
  5741. }
  5742. pub fn instr_0F62_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5743. mmx_read64_mm_mem32(ctx, "instr_0F62", modrm_byte, r);
  5744. }
  5745. pub fn instr_0F62_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5746. mmx_read64_mm_mm32(ctx, "instr_0F62", r1, r2);
  5747. }
  5748. pub fn instr_0F63_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5749. mmx_read64_mm_mem(ctx, "instr_0F63", modrm_byte, r);
  5750. }
  5751. pub fn instr_0F63_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5752. mmx_read64_mm_mm(ctx, "instr_0F63", r1, r2);
  5753. }
  5754. pub fn instr_0F64_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5755. mmx_read64_mm_mem(ctx, "instr_0F64", modrm_byte, r);
  5756. }
  5757. pub fn instr_0F64_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5758. mmx_read64_mm_mm(ctx, "instr_0F64", r1, r2);
  5759. }
  5760. pub fn instr_0F65_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5761. mmx_read64_mm_mem(ctx, "instr_0F65", modrm_byte, r);
  5762. }
  5763. pub fn instr_0F65_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5764. mmx_read64_mm_mm(ctx, "instr_0F65", r1, r2);
  5765. }
  5766. pub fn instr_0F66_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5767. mmx_read64_mm_mem(ctx, "instr_0F66", modrm_byte, r);
  5768. }
  5769. pub fn instr_0F66_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5770. mmx_read64_mm_mm(ctx, "instr_0F66", r1, r2);
  5771. }
  5772. pub fn instr_0F67_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5773. mmx_read64_mm_mem(ctx, "instr_0F67", modrm_byte, r);
  5774. }
  5775. pub fn instr_0F67_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5776. mmx_read64_mm_mm(ctx, "instr_0F67", r1, r2);
  5777. }
  5778. pub fn instr_0F68_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5779. mmx_read64_mm_mem(ctx, "instr_0F68", modrm_byte, r);
  5780. }
  5781. pub fn instr_0F68_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5782. mmx_read64_mm_mm(ctx, "instr_0F68", r1, r2);
  5783. }
  5784. pub fn instr_0F69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5785. mmx_read64_mm_mem(ctx, "instr_0F69", modrm_byte, r);
  5786. }
  5787. pub fn instr_0F69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5788. mmx_read64_mm_mm(ctx, "instr_0F69", r1, r2);
  5789. }
  5790. pub fn instr_0F6A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5791. mmx_read64_mm_mem(ctx, "instr_0F6A", modrm_byte, r);
  5792. }
  5793. pub fn instr_0F6A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5794. mmx_read64_mm_mm(ctx, "instr_0F6A", r1, r2);
  5795. }
  5796. pub fn instr_0F6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5797. mmx_read64_mm_mem(ctx, "instr_0F6B", modrm_byte, r);
  5798. }
  5799. pub fn instr_0F6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5800. mmx_read64_mm_mm(ctx, "instr_0F6B", r1, r2);
  5801. }
  5802. pub fn instr_660F60_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5803. // Note: Only requires 64-bit read, but is allowed to do 128-bit read
  5804. sse_read128_xmm_mem(ctx, "instr_660F60", modrm_byte, r);
  5805. }
  5806. pub fn instr_660F60_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5807. sse_read128_xmm_xmm(ctx, "instr_660F60", r1, r2);
  5808. }
  5809. pub fn instr_660F61_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5810. // Note: Only requires 64-bit read, but is allowed to do 128-bit read
  5811. sse_read128_xmm_mem(ctx, "instr_660F61", modrm_byte, r);
  5812. }
  5813. pub fn instr_660F61_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5814. sse_read128_xmm_xmm(ctx, "instr_660F61", r1, r2);
  5815. }
  5816. pub fn instr_660F62_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5817. let src = global_pointers::sse_scratch_register as u32;
  5818. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, src);
  5819. ctx.builder.const_i32(0);
  5820. ctx.builder.load_fixed_i32(src + 4);
  5821. ctx.builder
  5822. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r) + 12);
  5823. ctx.builder.const_i32(0);
  5824. ctx.builder
  5825. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r) + 4);
  5826. ctx.builder
  5827. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r) + 8);
  5828. ctx.builder.const_i32(0);
  5829. ctx.builder.load_fixed_i32(src + 0);
  5830. ctx.builder
  5831. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r) + 4);
  5832. }
  5833. pub fn instr_660F62_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5834. ctx.builder.const_i32(0);
  5835. ctx.builder
  5836. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r1) + 4);
  5837. ctx.builder
  5838. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2) + 12);
  5839. ctx.builder.const_i32(0);
  5840. ctx.builder
  5841. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r2) + 4);
  5842. ctx.builder
  5843. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2) + 8);
  5844. ctx.builder.const_i32(0);
  5845. ctx.builder
  5846. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r1) + 0);
  5847. ctx.builder
  5848. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2) + 4);
  5849. }
  5850. pub fn instr_660F63_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5851. sse_read128_xmm_mem(ctx, "instr_660F63", modrm_byte, r);
  5852. }
  5853. pub fn instr_660F63_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5854. sse_read128_xmm_xmm(ctx, "instr_660F63", r1, r2);
  5855. }
  5856. pub fn instr_660F64_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5857. sse_read128_xmm_mem(ctx, "instr_660F64", modrm_byte, r);
  5858. }
  5859. pub fn instr_660F64_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5860. sse_read128_xmm_xmm(ctx, "instr_660F64", r1, r2);
  5861. }
  5862. pub fn instr_660F65_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5863. sse_read128_xmm_mem(ctx, "instr_660F65", modrm_byte, r);
  5864. }
  5865. pub fn instr_660F65_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5866. sse_read128_xmm_xmm(ctx, "instr_660F65", r1, r2);
  5867. }
  5868. pub fn instr_660F66_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5869. sse_read128_xmm_mem(ctx, "instr_660F66", modrm_byte, r);
  5870. }
  5871. pub fn instr_660F66_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5872. sse_read128_xmm_xmm(ctx, "instr_660F66", r1, r2);
  5873. }
  5874. pub fn instr_660F67_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5875. sse_read128_xmm_mem(ctx, "instr_660F67", modrm_byte, r);
  5876. }
  5877. pub fn instr_660F67_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5878. sse_read128_xmm_xmm(ctx, "instr_660F67", r1, r2);
  5879. }
  5880. pub fn instr_660F68_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5881. sse_read128_xmm_mem(ctx, "instr_660F68", modrm_byte, r);
  5882. }
  5883. pub fn instr_660F68_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5884. sse_read128_xmm_xmm(ctx, "instr_660F68", r1, r2);
  5885. }
  5886. pub fn instr_660F69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5887. sse_read128_xmm_mem(ctx, "instr_660F69", modrm_byte, r);
  5888. }
  5889. pub fn instr_660F69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5890. sse_read128_xmm_xmm(ctx, "instr_660F69", r1, r2);
  5891. }
  5892. pub fn instr_660F6A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5893. sse_read128_xmm_mem(ctx, "instr_660F6A", modrm_byte, r);
  5894. }
  5895. pub fn instr_660F6A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5896. sse_read128_xmm_xmm(ctx, "instr_660F6A", r1, r2);
  5897. }
  5898. pub fn instr_660F6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5899. sse_read128_xmm_mem(ctx, "instr_660F6B", modrm_byte, r);
  5900. }
  5901. pub fn instr_660F6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5902. sse_read128_xmm_xmm(ctx, "instr_660F6B", r1, r2);
  5903. }
  5904. pub fn instr_660F6C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5905. sse_read128_xmm_mem(ctx, "instr_660F6C", modrm_byte, r);
  5906. }
  5907. pub fn instr_660F6C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5908. sse_read128_xmm_xmm(ctx, "instr_660F6C", r1, r2);
  5909. }
  5910. pub fn instr_660F6D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5911. sse_read128_xmm_mem(ctx, "instr_660F6D", modrm_byte, r);
  5912. }
  5913. pub fn instr_660F6D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5914. sse_read128_xmm_xmm(ctx, "instr_660F6D", r1, r2);
  5915. }
  5916. pub fn instr_0F6E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5917. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5918. ctx.builder.const_i32(r as i32);
  5919. ctx.builder.call_fn2("instr_0F6E")
  5920. }
  5921. pub fn instr_0F6E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5922. codegen::gen_get_reg32(ctx, r1);
  5923. ctx.builder.const_i32(r2 as i32);
  5924. ctx.builder.call_fn2("instr_0F6E")
  5925. }
  5926. pub fn instr_660F6E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5927. ctx.builder.const_i32(0);
  5928. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5929. ctx.builder.extend_unsigned_i32_to_i64();
  5930. ctx.builder
  5931. .store_aligned_i64(global_pointers::get_reg_xmm_offset(r));
  5932. ctx.builder.const_i32(0);
  5933. ctx.builder.const_i64(0);
  5934. ctx.builder
  5935. .store_aligned_i64(global_pointers::get_reg_xmm_offset(r) + 8);
  5936. }
  5937. pub fn instr_660F6E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5938. ctx.builder.const_i32(0);
  5939. codegen::gen_get_reg32(ctx, r1);
  5940. ctx.builder.extend_unsigned_i32_to_i64();
  5941. ctx.builder
  5942. .store_aligned_i64(global_pointers::get_reg_xmm_offset(r2));
  5943. ctx.builder.const_i32(0);
  5944. ctx.builder.const_i64(0);
  5945. ctx.builder
  5946. .store_aligned_i64(global_pointers::get_reg_xmm_offset(r2) + 8);
  5947. }
  5948. pub fn instr_0F6F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5949. // XXX: Aligned read or #gp
  5950. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5951. ctx.builder.const_i32(r as i32);
  5952. ctx.builder.call_fn2_i64_i32("instr_0F6F")
  5953. }
  5954. pub fn instr_0F6F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5955. ctx.builder.const_i32(r1 as i32);
  5956. ctx.builder.const_i32(r2 as i32);
  5957. ctx.builder.call_fn2("instr_0F6F_reg")
  5958. }
  5959. pub fn instr_660F6F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5960. // XXX: Aligned read or #gp
  5961. let dest = global_pointers::get_reg_xmm_offset(r);
  5962. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5963. }
  5964. pub fn instr_660F6F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5965. pub fn instr_F30F6F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5966. let dest = global_pointers::get_reg_xmm_offset(r);
  5967. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5968. }
  5969. pub fn instr_F30F6F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5970. pub fn instr_0F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  5971. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5972. ctx.builder.const_i32(r as i32);
  5973. ctx.builder.const_i32(imm8 as i32);
  5974. ctx.builder.call_fn3_i64_i32_i32("instr_0F70");
  5975. }
  5976. pub fn instr_0F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  5977. ctx.builder
  5978. .const_i32(global_pointers::get_reg_mmx_offset(r1) as i32);
  5979. ctx.builder.load_aligned_i64(0);
  5980. ctx.builder.const_i32(r2 as i32);
  5981. ctx.builder.const_i32(imm8 as i32);
  5982. ctx.builder.call_fn3_i64_i32_i32("instr_0F70");
  5983. }
  5984. pub fn instr_660F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  5985. let src = global_pointers::sse_scratch_register as u32;
  5986. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, src);
  5987. for i in 0..4 {
  5988. ctx.builder.const_i32(0);
  5989. ctx.builder.load_fixed_i32(src + 4 * (imm8 >> 2 * i & 3));
  5990. ctx.builder
  5991. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r) + 4 * i);
  5992. }
  5993. }
  5994. pub fn instr_660F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  5995. codegen::gen_read_reg_xmm128_into_scratch(ctx, r1);
  5996. // TODO: perf: copy less (handle aliased src/dst), use 64-bit loads/stores if possible
  5997. let src = global_pointers::sse_scratch_register as u32;
  5998. for i in 0..4 {
  5999. ctx.builder.const_i32(0);
  6000. ctx.builder.load_fixed_i32(src + 4 * (imm8 >> 2 * i & 3));
  6001. ctx.builder
  6002. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2) + 4 * i);
  6003. }
  6004. }
  6005. pub fn instr_F20F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  6006. sse_read128_xmm_mem_imm(ctx, "instr_F20F70", modrm_byte, r, imm8)
  6007. }
  6008. pub fn instr_F20F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  6009. sse_read128_xmm_xmm_imm(ctx, "instr_F20F70", r1, r2, imm8)
  6010. }
  6011. pub fn instr_F30F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  6012. sse_read128_xmm_mem_imm(ctx, "instr_F30F70", modrm_byte, r, imm8)
  6013. }
  6014. pub fn instr_F30F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  6015. sse_read128_xmm_xmm_imm(ctx, "instr_F30F70", r1, r2, imm8)
  6016. }
  6017. pub fn instr_0F71_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6018. codegen::gen_trigger_ud(ctx);
  6019. }
  6020. pub fn instr_0F71_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6021. ctx.builder.const_i32(r as i32);
  6022. ctx.builder.const_i32(imm8 as i32);
  6023. ctx.builder.call_fn2("instr_0F71_2_reg");
  6024. }
  6025. pub fn instr_0F71_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6026. codegen::gen_trigger_ud(ctx);
  6027. }
  6028. pub fn instr_0F71_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6029. ctx.builder.const_i32(r as i32);
  6030. ctx.builder.const_i32(imm8 as i32);
  6031. ctx.builder.call_fn2("instr_0F71_4_reg");
  6032. }
  6033. pub fn instr_0F71_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6034. codegen::gen_trigger_ud(ctx);
  6035. }
  6036. pub fn instr_0F71_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6037. ctx.builder.const_i32(r as i32);
  6038. ctx.builder.const_i32(imm8 as i32);
  6039. ctx.builder.call_fn2("instr_0F71_6_reg");
  6040. }
  6041. pub fn instr_0F72_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6042. codegen::gen_trigger_ud(ctx);
  6043. }
  6044. pub fn instr_0F72_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6045. ctx.builder.const_i32(r as i32);
  6046. ctx.builder.const_i32(imm8 as i32);
  6047. ctx.builder.call_fn2("instr_0F72_2_reg");
  6048. }
  6049. pub fn instr_0F72_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6050. codegen::gen_trigger_ud(ctx);
  6051. }
  6052. pub fn instr_0F72_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6053. ctx.builder.const_i32(r as i32);
  6054. ctx.builder.const_i32(imm8 as i32);
  6055. ctx.builder.call_fn2("instr_0F72_4_reg");
  6056. }
  6057. pub fn instr_0F72_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6058. codegen::gen_trigger_ud(ctx);
  6059. }
  6060. pub fn instr_0F72_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6061. ctx.builder.const_i32(r as i32);
  6062. ctx.builder.const_i32(imm8 as i32);
  6063. ctx.builder.call_fn2("instr_0F72_6_reg");
  6064. }
  6065. pub fn instr_0F73_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6066. codegen::gen_trigger_ud(ctx);
  6067. }
  6068. pub fn instr_0F73_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6069. ctx.builder.const_i32(r as i32);
  6070. ctx.builder.const_i32(imm8 as i32);
  6071. ctx.builder.call_fn2("instr_0F73_2_reg");
  6072. }
  6073. pub fn instr_0F73_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6074. codegen::gen_trigger_ud(ctx);
  6075. }
  6076. pub fn instr_0F73_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6077. ctx.builder.const_i32(r as i32);
  6078. ctx.builder.const_i32(imm8 as i32);
  6079. ctx.builder.call_fn2("instr_0F73_6_reg");
  6080. }
  6081. pub fn instr_660F71_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6082. codegen::gen_trigger_ud(ctx);
  6083. }
  6084. pub fn instr_660F71_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6085. ctx.builder.const_i32(r as i32);
  6086. ctx.builder.const_i32(imm8 as i32);
  6087. ctx.builder.call_fn2("instr_660F71_2_reg");
  6088. }
  6089. pub fn instr_660F71_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6090. codegen::gen_trigger_ud(ctx);
  6091. }
  6092. pub fn instr_660F71_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6093. ctx.builder.const_i32(r as i32);
  6094. ctx.builder.const_i32(imm8 as i32);
  6095. ctx.builder.call_fn2("instr_660F71_4_reg");
  6096. }
  6097. pub fn instr_660F71_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6098. codegen::gen_trigger_ud(ctx);
  6099. }
  6100. pub fn instr_660F71_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6101. ctx.builder.const_i32(r as i32);
  6102. ctx.builder.const_i32(imm8 as i32);
  6103. ctx.builder.call_fn2("instr_660F71_6_reg");
  6104. }
  6105. pub fn instr_660F72_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6106. codegen::gen_trigger_ud(ctx);
  6107. }
  6108. pub fn instr_660F72_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6109. ctx.builder.const_i32(r as i32);
  6110. ctx.builder.const_i32(imm8 as i32);
  6111. ctx.builder.call_fn2("instr_660F72_2_reg");
  6112. }
  6113. pub fn instr_660F72_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6114. codegen::gen_trigger_ud(ctx);
  6115. }
  6116. pub fn instr_660F72_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6117. ctx.builder.const_i32(r as i32);
  6118. ctx.builder.const_i32(imm8 as i32);
  6119. ctx.builder.call_fn2("instr_660F72_4_reg");
  6120. }
  6121. pub fn instr_660F72_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6122. codegen::gen_trigger_ud(ctx);
  6123. }
  6124. pub fn instr_660F72_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6125. ctx.builder.const_i32(r as i32);
  6126. ctx.builder.const_i32(imm8 as i32);
  6127. ctx.builder.call_fn2("instr_660F72_6_reg");
  6128. }
  6129. pub fn instr_660F73_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6130. codegen::gen_trigger_ud(ctx);
  6131. }
  6132. pub fn instr_660F73_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6133. ctx.builder.const_i32(r as i32);
  6134. ctx.builder.const_i32(imm8 as i32);
  6135. ctx.builder.call_fn2("instr_660F73_2_reg");
  6136. }
  6137. pub fn instr_660F73_3_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6138. codegen::gen_trigger_ud(ctx);
  6139. }
  6140. pub fn instr_660F73_3_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6141. ctx.builder.const_i32(r as i32);
  6142. ctx.builder.const_i32(imm8 as i32);
  6143. ctx.builder.call_fn2("instr_660F73_3_reg");
  6144. }
  6145. pub fn instr_660F73_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6146. codegen::gen_trigger_ud(ctx);
  6147. }
  6148. pub fn instr_660F73_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6149. ctx.builder.const_i32(r as i32);
  6150. ctx.builder.const_i32(imm8 as i32);
  6151. ctx.builder.call_fn2("instr_660F73_6_reg");
  6152. }
  6153. pub fn instr_660F73_7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6154. codegen::gen_trigger_ud(ctx);
  6155. }
  6156. pub fn instr_660F73_7_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6157. ctx.builder.const_i32(r as i32);
  6158. ctx.builder.const_i32(imm8 as i32);
  6159. ctx.builder.call_fn2("instr_660F73_7_reg");
  6160. }
  6161. pub fn instr_0F74_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6162. mmx_read64_mm_mem(ctx, "instr_0F74", modrm_byte, r);
  6163. }
  6164. pub fn instr_0F74_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6165. mmx_read64_mm_mm(ctx, "instr_0F74", r1, r2);
  6166. }
  6167. pub fn instr_0F75_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6168. mmx_read64_mm_mem(ctx, "instr_0F75", modrm_byte, r);
  6169. }
  6170. pub fn instr_0F75_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6171. mmx_read64_mm_mm(ctx, "instr_0F75", r1, r2);
  6172. }
  6173. pub fn instr_0F76_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6174. mmx_read64_mm_mem(ctx, "instr_0F76", modrm_byte, r);
  6175. }
  6176. pub fn instr_0F76_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6177. mmx_read64_mm_mm(ctx, "instr_0F76", r1, r2);
  6178. }
  6179. pub fn instr_660F74_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6180. sse_read128_xmm_mem(ctx, "instr_660F74", modrm_byte, r);
  6181. }
  6182. pub fn instr_660F74_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6183. sse_read128_xmm_xmm(ctx, "instr_660F74", r1, r2);
  6184. }
  6185. pub fn instr_660F75_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6186. sse_read128_xmm_mem(ctx, "instr_660F75", modrm_byte, r);
  6187. }
  6188. pub fn instr_660F75_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6189. sse_read128_xmm_xmm(ctx, "instr_660F75", r1, r2);
  6190. }
  6191. pub fn instr_660F76_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6192. sse_read128_xmm_mem(ctx, "instr_660F76", modrm_byte, r);
  6193. }
  6194. pub fn instr_660F76_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6195. sse_read128_xmm_xmm(ctx, "instr_660F76", r1, r2);
  6196. }
  6197. pub fn instr_0F7E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6198. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6199. let address_local = ctx.builder.set_new_local();
  6200. ctx.builder.const_i32(r as i32);
  6201. ctx.builder.call_fn1_ret("instr_0F7E");
  6202. let value_local = ctx.builder.set_new_local();
  6203. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  6204. ctx.builder.free_local(address_local);
  6205. ctx.builder.free_local(value_local);
  6206. }
  6207. pub fn instr_0F7E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6208. ctx.builder.const_i32(r2 as i32);
  6209. ctx.builder.call_fn1_ret("instr_0F7E");
  6210. codegen::gen_set_reg32(ctx, r1);
  6211. }
  6212. pub fn instr_660F7E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6213. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6214. let address_local = ctx.builder.set_new_local();
  6215. ctx.builder
  6216. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r));
  6217. let value_local = ctx.builder.set_new_local();
  6218. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  6219. ctx.builder.free_local(address_local);
  6220. ctx.builder.free_local(value_local);
  6221. }
  6222. pub fn instr_660F7E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6223. ctx.builder
  6224. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r2));
  6225. codegen::gen_set_reg32(ctx, r1);
  6226. }
  6227. pub fn instr_0F7F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6228. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6229. let address_local = ctx.builder.set_new_local();
  6230. ctx.builder.const_i32(r as i32);
  6231. ctx.builder.call_fn1_ret_i64("instr_0F7F");
  6232. let value_local = ctx.builder.set_new_local_i64();
  6233. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  6234. ctx.builder.free_local(address_local);
  6235. ctx.builder.free_local_i64(value_local);
  6236. }
  6237. pub fn instr_0F7F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6238. ctx.builder.const_i32(r1 as i32);
  6239. ctx.builder.const_i32(r2 as i32);
  6240. ctx.builder.call_fn2("instr_0F7F_reg")
  6241. }
  6242. pub fn instr_F30F7E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6243. ctx.builder
  6244. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
  6245. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  6246. ctx.builder.store_aligned_i64(0);
  6247. ctx.builder
  6248. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32 + 8);
  6249. ctx.builder.const_i64(0);
  6250. ctx.builder.store_aligned_i64(0);
  6251. }
  6252. pub fn instr_F30F7E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6253. instr_660FD6_reg_jit(ctx, r2, r1)
  6254. }
  6255. pub fn instr_660F7F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6256. instr_0F29_mem_jit(ctx, modrm_byte, r);
  6257. }
  6258. pub fn instr_660F7F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  6259. pub fn instr_F30F7F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6260. instr_0F29_mem_jit(ctx, modrm_byte, r);
  6261. }
  6262. pub fn instr_F30F7F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  6263. pub fn instr16_0FA0_jit(ctx: &mut JitContext) {
  6264. codegen::gen_get_sreg(ctx, regs::FS);
  6265. let sreg = ctx.builder.set_new_local();
  6266. codegen::gen_push16(ctx, &sreg);
  6267. ctx.builder.free_local(sreg);
  6268. }
  6269. pub fn instr32_0FA0_jit(ctx: &mut JitContext) { codegen::gen_push32_sreg(ctx, regs::FS) }
  6270. pub fn instr16_0FA8_jit(ctx: &mut JitContext) {
  6271. codegen::gen_get_sreg(ctx, regs::GS);
  6272. let sreg = ctx.builder.set_new_local();
  6273. codegen::gen_push16(ctx, &sreg);
  6274. ctx.builder.free_local(sreg);
  6275. }
  6276. pub fn instr32_0FA8_jit(ctx: &mut JitContext) { codegen::gen_push32_sreg(ctx, regs::GS) }
  6277. pub fn instr16_0FA3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6278. gen_bt(
  6279. &mut ctx.builder,
  6280. &ctx.register_locals[r1 as usize],
  6281. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6282. 15,
  6283. )
  6284. }
  6285. pub fn instr16_0FA3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6286. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6287. codegen::gen_get_reg16(ctx, r);
  6288. codegen::sign_extend_i16(ctx.builder);
  6289. ctx.builder.const_i32(3);
  6290. ctx.builder.shr_s_i32();
  6291. ctx.builder.add_i32();
  6292. let address_local = ctx.builder.set_new_local();
  6293. codegen::gen_safe_read8(ctx, &address_local);
  6294. ctx.builder.free_local(address_local);
  6295. let value = ctx.builder.set_new_local();
  6296. gen_bt(
  6297. &mut ctx.builder,
  6298. &value,
  6299. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize]),
  6300. 7,
  6301. );
  6302. ctx.builder.free_local(value);
  6303. }
  6304. pub fn instr32_0FA3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6305. gen_bt(
  6306. &mut ctx.builder,
  6307. &ctx.register_locals[r1 as usize],
  6308. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6309. 31,
  6310. )
  6311. }
  6312. pub fn instr32_0FA3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6313. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6314. codegen::gen_get_reg32(ctx, r);
  6315. ctx.builder.const_i32(3);
  6316. ctx.builder.shr_s_i32();
  6317. ctx.builder.add_i32();
  6318. let address_local = ctx.builder.set_new_local();
  6319. codegen::gen_safe_read8(ctx, &address_local);
  6320. ctx.builder.free_local(address_local);
  6321. let value = ctx.builder.set_new_local();
  6322. gen_bt(
  6323. &mut ctx.builder,
  6324. &value,
  6325. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize]),
  6326. 7,
  6327. );
  6328. ctx.builder.free_local(value);
  6329. }
  6330. pub fn instr16_0FAB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6331. gen_bts(
  6332. &mut ctx.builder,
  6333. &ctx.register_locals[r1 as usize],
  6334. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6335. 15,
  6336. )
  6337. }
  6338. pub fn instr16_0FAB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6339. gen_bit_rmw(
  6340. ctx,
  6341. modrm_byte,
  6342. &gen_bts,
  6343. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6344. 16,
  6345. );
  6346. }
  6347. pub fn instr32_0FAB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6348. gen_bts(
  6349. &mut ctx.builder,
  6350. &ctx.register_locals[r1 as usize],
  6351. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6352. 31,
  6353. )
  6354. }
  6355. pub fn instr32_0FAB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6356. gen_bit_rmw(
  6357. ctx,
  6358. modrm_byte,
  6359. &gen_bts,
  6360. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6361. 32,
  6362. );
  6363. }
  6364. pub fn instr16_0FB3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6365. gen_btr(
  6366. &mut ctx.builder,
  6367. &ctx.register_locals[r1 as usize],
  6368. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6369. 15,
  6370. )
  6371. }
  6372. pub fn instr16_0FB3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6373. gen_bit_rmw(
  6374. ctx,
  6375. modrm_byte,
  6376. &gen_btr,
  6377. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6378. 16,
  6379. );
  6380. }
  6381. pub fn instr32_0FB3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6382. gen_btr(
  6383. &mut ctx.builder,
  6384. &ctx.register_locals[r1 as usize],
  6385. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6386. 31,
  6387. )
  6388. }
  6389. pub fn instr32_0FB3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6390. gen_bit_rmw(
  6391. ctx,
  6392. modrm_byte,
  6393. &gen_btr,
  6394. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6395. 32,
  6396. );
  6397. }
  6398. pub fn instr16_0FBB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6399. gen_btc(
  6400. &mut ctx.builder,
  6401. &ctx.register_locals[r1 as usize],
  6402. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6403. 15,
  6404. )
  6405. }
  6406. pub fn instr16_0FBB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6407. gen_bit_rmw(
  6408. ctx,
  6409. modrm_byte,
  6410. &gen_btc,
  6411. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6412. 16,
  6413. );
  6414. }
  6415. pub fn instr32_0FBB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6416. gen_btc(
  6417. &mut ctx.builder,
  6418. &ctx.register_locals[r1 as usize],
  6419. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6420. 31,
  6421. )
  6422. }
  6423. pub fn instr32_0FBB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6424. gen_bit_rmw(
  6425. ctx,
  6426. modrm_byte,
  6427. &gen_btc,
  6428. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6429. 32,
  6430. );
  6431. }
  6432. pub fn instr16_0FBA_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6433. gen_bt(
  6434. &mut ctx.builder,
  6435. &ctx.register_locals[r as usize],
  6436. &LocalOrImmediate::Immediate(imm8 as i32),
  6437. 15,
  6438. )
  6439. }
  6440. pub fn instr16_0FBA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6441. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6442. let offset = (imm8 as i32 & 15) >> 3;
  6443. if offset != 0 {
  6444. ctx.builder.const_i32(offset);
  6445. ctx.builder.add_i32();
  6446. }
  6447. let address_local = ctx.builder.set_new_local();
  6448. codegen::gen_safe_read8(ctx, &address_local);
  6449. ctx.builder.free_local(address_local);
  6450. let value = ctx.builder.set_new_local();
  6451. gen_bt(
  6452. &mut ctx.builder,
  6453. &value,
  6454. &LocalOrImmediate::Immediate(imm8 as i32),
  6455. 7,
  6456. );
  6457. ctx.builder.free_local(value);
  6458. }
  6459. pub fn instr32_0FBA_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6460. gen_bt(
  6461. &mut ctx.builder,
  6462. &ctx.register_locals[r as usize],
  6463. &LocalOrImmediate::Immediate(imm8 as i32),
  6464. 31,
  6465. )
  6466. }
  6467. pub fn instr32_0FBA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6468. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6469. let offset = (imm8 as i32 & 31) >> 3;
  6470. if offset != 0 {
  6471. ctx.builder.const_i32(offset);
  6472. ctx.builder.add_i32();
  6473. }
  6474. let address_local = ctx.builder.set_new_local();
  6475. codegen::gen_safe_read8(ctx, &address_local);
  6476. ctx.builder.free_local(address_local);
  6477. let value = ctx.builder.set_new_local();
  6478. gen_bt(
  6479. &mut ctx.builder,
  6480. &value,
  6481. &LocalOrImmediate::Immediate(imm8 as i32),
  6482. 7,
  6483. );
  6484. ctx.builder.free_local(value);
  6485. }
  6486. pub fn instr16_0FBA_5_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6487. gen_bts(
  6488. &mut ctx.builder,
  6489. &ctx.register_locals[r as usize],
  6490. &LocalOrImmediate::Immediate(imm8 as i32),
  6491. 15,
  6492. )
  6493. }
  6494. pub fn instr16_0FBA_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6495. gen_bit_rmw(
  6496. ctx,
  6497. modrm_byte,
  6498. &gen_bts,
  6499. &LocalOrImmediate::Immediate(imm8 as i32),
  6500. 16,
  6501. );
  6502. }
  6503. pub fn instr32_0FBA_5_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6504. gen_bts(
  6505. &mut ctx.builder,
  6506. &ctx.register_locals[r as usize],
  6507. &LocalOrImmediate::Immediate(imm8 as i32),
  6508. 31,
  6509. )
  6510. }
  6511. pub fn instr32_0FBA_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6512. gen_bit_rmw(
  6513. ctx,
  6514. modrm_byte,
  6515. &gen_bts,
  6516. &LocalOrImmediate::Immediate(imm8 as i32),
  6517. 32,
  6518. );
  6519. }
  6520. pub fn instr16_0FBA_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6521. gen_btr(
  6522. &mut ctx.builder,
  6523. &ctx.register_locals[r as usize],
  6524. &LocalOrImmediate::Immediate(imm8 as i32),
  6525. 15,
  6526. )
  6527. }
  6528. pub fn instr16_0FBA_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6529. gen_bit_rmw(
  6530. ctx,
  6531. modrm_byte,
  6532. &gen_btr,
  6533. &LocalOrImmediate::Immediate(imm8 as i32),
  6534. 16,
  6535. );
  6536. }
  6537. pub fn instr32_0FBA_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6538. gen_btr(
  6539. &mut ctx.builder,
  6540. &ctx.register_locals[r as usize],
  6541. &LocalOrImmediate::Immediate(imm8 as i32),
  6542. 31,
  6543. )
  6544. }
  6545. pub fn instr32_0FBA_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6546. gen_bit_rmw(
  6547. ctx,
  6548. modrm_byte,
  6549. &gen_btr,
  6550. &LocalOrImmediate::Immediate(imm8 as i32),
  6551. 32,
  6552. );
  6553. }
  6554. pub fn instr16_0FBA_7_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6555. gen_btc(
  6556. &mut ctx.builder,
  6557. &ctx.register_locals[r as usize],
  6558. &LocalOrImmediate::Immediate(imm8 as i32),
  6559. 15,
  6560. )
  6561. }
  6562. pub fn instr16_0FBA_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6563. gen_bit_rmw(
  6564. ctx,
  6565. modrm_byte,
  6566. &gen_btc,
  6567. &LocalOrImmediate::Immediate(imm8 as i32),
  6568. 16,
  6569. );
  6570. }
  6571. pub fn instr32_0FBA_7_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6572. gen_btc(
  6573. &mut ctx.builder,
  6574. &ctx.register_locals[r as usize],
  6575. &LocalOrImmediate::Immediate(imm8 as i32),
  6576. 31,
  6577. )
  6578. }
  6579. pub fn instr32_0FBA_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6580. gen_bit_rmw(
  6581. ctx,
  6582. modrm_byte,
  6583. &gen_btc,
  6584. &LocalOrImmediate::Immediate(imm8 as i32),
  6585. 32,
  6586. );
  6587. }
  6588. pub fn instr_0FAE_5_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte) {
  6589. dbg_log!("Generating #ud for unimplemented instruction: instr_0FAE_5_mem_jit");
  6590. codegen::gen_trigger_ud(ctx);
  6591. }
  6592. pub fn instr_0FAE_5_reg_jit(_ctx: &mut JitContext, _r: u32) {
  6593. // For this instruction, the processor ignores the r/m field of the ModR/M byte.
  6594. }
  6595. pub fn instr_0FD1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6596. mmx_read64_mm_mem(ctx, "instr_0FD1", modrm_byte, r);
  6597. }
  6598. pub fn instr_0FD1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6599. mmx_read64_mm_mm(ctx, "instr_0FD1", r1, r2);
  6600. }
  6601. pub fn instr_0FD2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6602. mmx_read64_mm_mem(ctx, "instr_0FD2", modrm_byte, r);
  6603. }
  6604. pub fn instr_0FD2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6605. mmx_read64_mm_mm(ctx, "instr_0FD2", r1, r2);
  6606. }
  6607. pub fn instr_0FD3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6608. mmx_read64_mm_mem(ctx, "instr_0FD3", modrm_byte, r);
  6609. }
  6610. pub fn instr_0FD3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6611. mmx_read64_mm_mm(ctx, "instr_0FD3", r1, r2);
  6612. }
  6613. pub fn instr_0FD4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6614. mmx_read64_mm_mem(ctx, "instr_0FD4", modrm_byte, r);
  6615. }
  6616. pub fn instr_0FD4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6617. mmx_read64_mm_mm(ctx, "instr_0FD4", r1, r2);
  6618. }
  6619. pub fn instr_0FD5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6620. mmx_read64_mm_mem(ctx, "instr_0FD5", modrm_byte, r);
  6621. }
  6622. pub fn instr_0FD5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6623. mmx_read64_mm_mm(ctx, "instr_0FD5", r1, r2);
  6624. }
  6625. pub fn instr_0FD7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
  6626. codegen::gen_trigger_ud(ctx)
  6627. }
  6628. pub fn instr_0FD7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6629. ctx.builder.const_i32(r1 as i32);
  6630. ctx.builder.call_fn1_ret("instr_0FD7");
  6631. codegen::gen_set_reg32(ctx, r2);
  6632. }
  6633. pub fn instr_0FD8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6634. mmx_read64_mm_mem(ctx, "instr_0FD8", modrm_byte, r);
  6635. }
  6636. pub fn instr_0FD8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6637. mmx_read64_mm_mm(ctx, "instr_0FD8", r1, r2);
  6638. }
  6639. pub fn instr_0FD9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6640. mmx_read64_mm_mem(ctx, "instr_0FD9", modrm_byte, r);
  6641. }
  6642. pub fn instr_0FD9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6643. mmx_read64_mm_mm(ctx, "instr_0FD9", r1, r2);
  6644. }
  6645. pub fn instr_0FDA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6646. mmx_read64_mm_mem(ctx, "instr_0FDA", modrm_byte, r);
  6647. }
  6648. pub fn instr_0FDA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6649. mmx_read64_mm_mm(ctx, "instr_0FDA", r1, r2);
  6650. }
  6651. pub fn instr_0FDB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6652. mmx_read64_mm_mem(ctx, "instr_0FDB", modrm_byte, r);
  6653. }
  6654. pub fn instr_0FDB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6655. mmx_read64_mm_mm(ctx, "instr_0FDB", r1, r2);
  6656. }
  6657. pub fn instr_0FDC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6658. mmx_read64_mm_mem(ctx, "instr_0FDC", modrm_byte, r);
  6659. }
  6660. pub fn instr_0FDC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6661. mmx_read64_mm_mm(ctx, "instr_0FDC", r1, r2);
  6662. }
  6663. pub fn instr_0FDD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6664. mmx_read64_mm_mem(ctx, "instr_0FDD", modrm_byte, r);
  6665. }
  6666. pub fn instr_0FDD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6667. mmx_read64_mm_mm(ctx, "instr_0FDD", r1, r2);
  6668. }
  6669. pub fn instr_0FDE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6670. mmx_read64_mm_mem(ctx, "instr_0FDE", modrm_byte, r);
  6671. }
  6672. pub fn instr_0FDE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6673. mmx_read64_mm_mm(ctx, "instr_0FDE", r1, r2);
  6674. }
  6675. pub fn instr_0FDF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6676. mmx_read64_mm_mem(ctx, "instr_0FDF", modrm_byte, r);
  6677. }
  6678. pub fn instr_0FDF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6679. mmx_read64_mm_mm(ctx, "instr_0FDF", r1, r2);
  6680. }
  6681. pub fn instr_660FD1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6682. sse_read128_xmm_mem(ctx, "instr_660FD1", modrm_byte, r);
  6683. }
  6684. pub fn instr_660FD1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6685. sse_read128_xmm_xmm(ctx, "instr_660FD1", r1, r2);
  6686. }
  6687. pub fn instr_660FD2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6688. sse_read128_xmm_mem(ctx, "instr_660FD2", modrm_byte, r);
  6689. }
  6690. pub fn instr_660FD2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6691. sse_read128_xmm_xmm(ctx, "instr_660FD2", r1, r2);
  6692. }
  6693. pub fn instr_660FD3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6694. sse_read128_xmm_mem(ctx, "instr_660FD3", modrm_byte, r);
  6695. }
  6696. pub fn instr_660FD3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6697. sse_read128_xmm_xmm(ctx, "instr_660FD3", r1, r2);
  6698. }
  6699. pub fn instr_660FD4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6700. sse_read128_xmm_mem(ctx, "instr_660FD4", modrm_byte, r);
  6701. }
  6702. pub fn instr_660FD4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6703. sse_read128_xmm_xmm(ctx, "instr_660FD4", r1, r2);
  6704. }
  6705. pub fn instr_660FD5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6706. sse_read128_xmm_mem(ctx, "instr_660FD5", modrm_byte, r);
  6707. }
  6708. pub fn instr_660FD5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6709. sse_read128_xmm_xmm(ctx, "instr_660FD5", r1, r2);
  6710. }
  6711. pub fn instr_660FD6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6712. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6713. let address_local = ctx.builder.set_new_local();
  6714. ctx.builder
  6715. .load_fixed_i64(global_pointers::get_reg_xmm_offset(r));
  6716. let value_local = ctx.builder.set_new_local_i64();
  6717. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  6718. ctx.builder.free_local(address_local);
  6719. ctx.builder.free_local_i64(value_local);
  6720. }
  6721. pub fn instr_660FD6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6722. ctx.builder.const_i32(0);
  6723. ctx.builder
  6724. .load_fixed_i64(global_pointers::get_reg_xmm_offset(r2));
  6725. ctx.builder
  6726. .store_aligned_i64(global_pointers::get_reg_xmm_offset(r1));
  6727. ctx.builder.const_i32(0);
  6728. ctx.builder.const_i64(0);
  6729. ctx.builder
  6730. .store_aligned_i64(global_pointers::get_reg_xmm_offset(r1) + 8);
  6731. }
  6732. pub fn instr_660FD7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
  6733. codegen::gen_trigger_ud(ctx)
  6734. }
  6735. pub fn instr_660FD7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6736. ctx.builder.const_i32(r1 as i32);
  6737. ctx.builder.call_fn1_ret("instr_660FD7");
  6738. codegen::gen_set_reg32(ctx, r2);
  6739. }
  6740. pub fn instr_660FD8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6741. sse_read128_xmm_mem(ctx, "instr_660FD8", modrm_byte, r);
  6742. }
  6743. pub fn instr_660FD8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6744. sse_read128_xmm_xmm(ctx, "instr_660FD8", r1, r2);
  6745. }
  6746. pub fn instr_660FD9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6747. sse_read128_xmm_mem(ctx, "instr_660FD9", modrm_byte, r);
  6748. }
  6749. pub fn instr_660FD9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6750. sse_read128_xmm_xmm(ctx, "instr_660FD9", r1, r2);
  6751. }
  6752. pub fn instr_660FDA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6753. sse_read128_xmm_mem(ctx, "instr_660FDA", modrm_byte, r);
  6754. }
  6755. pub fn instr_660FDA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6756. sse_read128_xmm_xmm(ctx, "instr_660FDA", r1, r2);
  6757. }
  6758. pub fn instr_660FDB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6759. sse_read128_xmm_mem(ctx, "instr_660FDB", modrm_byte, r);
  6760. }
  6761. pub fn instr_660FDB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6762. sse_read128_xmm_xmm(ctx, "instr_660FDB", r1, r2);
  6763. }
  6764. pub fn instr_660FDC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6765. sse_read128_xmm_mem(ctx, "instr_660FDC", modrm_byte, r);
  6766. }
  6767. pub fn instr_660FDC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6768. sse_read128_xmm_xmm(ctx, "instr_660FDC", r1, r2);
  6769. }
  6770. pub fn instr_660FDD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6771. sse_read128_xmm_mem(ctx, "instr_660FDD", modrm_byte, r);
  6772. }
  6773. pub fn instr_660FDD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6774. sse_read128_xmm_xmm(ctx, "instr_660FDD", r1, r2);
  6775. }
  6776. pub fn instr_660FDE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6777. sse_read128_xmm_mem(ctx, "instr_660FDE", modrm_byte, r);
  6778. }
  6779. pub fn instr_660FDE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6780. sse_read128_xmm_xmm(ctx, "instr_660FDE", r1, r2);
  6781. }
  6782. pub fn instr_660FDF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6783. sse_read128_xmm_mem(ctx, "instr_660FDF", modrm_byte, r);
  6784. }
  6785. pub fn instr_660FDF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6786. sse_read128_xmm_xmm(ctx, "instr_660FDF", r1, r2);
  6787. }
  6788. pub fn instr_0FE0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6789. mmx_read64_mm_mem(ctx, "instr_0FE0", modrm_byte, r);
  6790. }
  6791. pub fn instr_0FE0_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6792. mmx_read64_mm_mm(ctx, "instr_0FE0", r1, r2);
  6793. }
  6794. pub fn instr_0FE1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6795. mmx_read64_mm_mem(ctx, "instr_0FE1", modrm_byte, r);
  6796. }
  6797. pub fn instr_0FE1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6798. mmx_read64_mm_mm(ctx, "instr_0FE1", r1, r2);
  6799. }
  6800. pub fn instr_0FE2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6801. mmx_read64_mm_mem(ctx, "instr_0FE2", modrm_byte, r);
  6802. }
  6803. pub fn instr_0FE2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6804. mmx_read64_mm_mm(ctx, "instr_0FE2", r1, r2);
  6805. }
  6806. pub fn instr_0FE3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6807. mmx_read64_mm_mem(ctx, "instr_0FE3", modrm_byte, r);
  6808. }
  6809. pub fn instr_0FE3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6810. mmx_read64_mm_mm(ctx, "instr_0FE3", r1, r2);
  6811. }
  6812. pub fn instr_0FE4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6813. mmx_read64_mm_mem(ctx, "instr_0FE4", modrm_byte, r);
  6814. }
  6815. pub fn instr_0FE4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6816. mmx_read64_mm_mm(ctx, "instr_0FE4", r1, r2);
  6817. }
  6818. pub fn instr_0FE5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6819. mmx_read64_mm_mem(ctx, "instr_0FE5", modrm_byte, r);
  6820. }
  6821. pub fn instr_0FE5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6822. mmx_read64_mm_mm(ctx, "instr_0FE5", r1, r2);
  6823. }
  6824. pub fn instr_0FE8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6825. mmx_read64_mm_mem(ctx, "instr_0FE8", modrm_byte, r);
  6826. }
  6827. pub fn instr_0FE8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6828. mmx_read64_mm_mm(ctx, "instr_0FE8", r1, r2);
  6829. }
  6830. pub fn instr_0FE9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6831. mmx_read64_mm_mem(ctx, "instr_0FE9", modrm_byte, r);
  6832. }
  6833. pub fn instr_0FE9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6834. mmx_read64_mm_mm(ctx, "instr_0FE9", r1, r2);
  6835. }
  6836. pub fn instr_0FEA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6837. mmx_read64_mm_mem(ctx, "instr_0FEA", modrm_byte, r);
  6838. }
  6839. pub fn instr_0FEA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6840. mmx_read64_mm_mm(ctx, "instr_0FEA", r1, r2);
  6841. }
  6842. pub fn instr_0FEB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6843. mmx_read64_mm_mem(ctx, "instr_0FEB", modrm_byte, r);
  6844. }
  6845. pub fn instr_0FEB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6846. mmx_read64_mm_mm(ctx, "instr_0FEB", r1, r2);
  6847. }
  6848. pub fn instr_0FEC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6849. mmx_read64_mm_mem(ctx, "instr_0FEC", modrm_byte, r);
  6850. }
  6851. pub fn instr_0FEC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6852. mmx_read64_mm_mm(ctx, "instr_0FEC", r1, r2);
  6853. }
  6854. pub fn instr_0FED_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6855. mmx_read64_mm_mem(ctx, "instr_0FED", modrm_byte, r);
  6856. }
  6857. pub fn instr_0FED_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6858. mmx_read64_mm_mm(ctx, "instr_0FED", r1, r2);
  6859. }
  6860. pub fn instr_0FEE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6861. mmx_read64_mm_mem(ctx, "instr_0FEE", modrm_byte, r);
  6862. }
  6863. pub fn instr_0FEE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6864. mmx_read64_mm_mm(ctx, "instr_0FEE", r1, r2);
  6865. }
  6866. pub fn instr_0FEF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6867. mmx_read64_mm_mem(ctx, "instr_0FEF", modrm_byte, r);
  6868. }
  6869. pub fn instr_0FEF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6870. mmx_read64_mm_mm(ctx, "instr_0FEF", r1, r2);
  6871. }
  6872. pub fn instr_660FE0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6873. sse_read128_xmm_mem(ctx, "instr_660FE0", modrm_byte, r);
  6874. }
  6875. pub fn instr_660FE0_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6876. sse_read128_xmm_xmm(ctx, "instr_660FE0", r1, r2);
  6877. }
  6878. pub fn instr_660FE1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6879. sse_read128_xmm_mem(ctx, "instr_660FE1", modrm_byte, r);
  6880. }
  6881. pub fn instr_660FE1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6882. sse_read128_xmm_xmm(ctx, "instr_660FE1", r1, r2);
  6883. }
  6884. pub fn instr_660FE2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6885. sse_read128_xmm_mem(ctx, "instr_660FE2", modrm_byte, r);
  6886. }
  6887. pub fn instr_660FE2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6888. sse_read128_xmm_xmm(ctx, "instr_660FE2", r1, r2);
  6889. }
  6890. pub fn instr_660FE3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6891. sse_read128_xmm_mem(ctx, "instr_660FE3", modrm_byte, r);
  6892. }
  6893. pub fn instr_660FE3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6894. sse_read128_xmm_xmm(ctx, "instr_660FE3", r1, r2);
  6895. }
  6896. pub fn instr_660FE4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6897. sse_read128_xmm_mem(ctx, "instr_660FE4", modrm_byte, r);
  6898. }
  6899. pub fn instr_660FE4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6900. sse_read128_xmm_xmm(ctx, "instr_660FE4", r1, r2);
  6901. }
  6902. pub fn instr_660FE5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6903. sse_read128_xmm_mem(ctx, "instr_660FE5", modrm_byte, r);
  6904. }
  6905. pub fn instr_660FE5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6906. sse_read128_xmm_xmm(ctx, "instr_660FE5", r1, r2);
  6907. }
  6908. pub fn instr_660FE6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6909. sse_read128_xmm_mem(ctx, "instr_660FE6", modrm_byte, r);
  6910. }
  6911. pub fn instr_660FE6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6912. sse_read128_xmm_xmm(ctx, "instr_660FE6", r1, r2);
  6913. }
  6914. pub fn instr_F20FE6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6915. sse_read128_xmm_mem(ctx, "instr_F20FE6", modrm_byte, r);
  6916. }
  6917. pub fn instr_F20FE6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6918. sse_read128_xmm_xmm(ctx, "instr_F20FE6", r1, r2);
  6919. }
  6920. pub fn instr_F30FE6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6921. sse_read64_xmm_mem(ctx, "instr_F30FE6", modrm_byte, r);
  6922. }
  6923. pub fn instr_F30FE6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6924. sse_read64_xmm_xmm(ctx, "instr_F30FE6", r1, r2);
  6925. }
  6926. pub fn instr_660FE7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6927. instr_0F29_mem_jit(ctx, modrm_byte, r);
  6928. }
  6929. pub fn instr_660FE7_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  6930. codegen::gen_trigger_ud(ctx);
  6931. }
  6932. pub fn instr_660FE8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6933. sse_read128_xmm_mem(ctx, "instr_660FE8", modrm_byte, r);
  6934. }
  6935. pub fn instr_660FE8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6936. sse_read128_xmm_xmm(ctx, "instr_660FE8", r1, r2);
  6937. }
  6938. pub fn instr_660FE9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6939. sse_read128_xmm_mem(ctx, "instr_660FE9", modrm_byte, r);
  6940. }
  6941. pub fn instr_660FE9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6942. sse_read128_xmm_xmm(ctx, "instr_660FE9", r1, r2);
  6943. }
  6944. pub fn instr_660FEA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6945. sse_read128_xmm_mem(ctx, "instr_660FEA", modrm_byte, r);
  6946. }
  6947. pub fn instr_660FEA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6948. sse_read128_xmm_xmm(ctx, "instr_660FEA", r1, r2);
  6949. }
  6950. pub fn instr_660FEB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6951. sse_read128_xmm_mem(ctx, "instr_660FEB", modrm_byte, r);
  6952. }
  6953. pub fn instr_660FEB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6954. sse_read128_xmm_xmm(ctx, "instr_660FEB", r1, r2);
  6955. }
  6956. pub fn instr_660FEC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6957. sse_read128_xmm_mem(ctx, "instr_660FEC", modrm_byte, r);
  6958. }
  6959. pub fn instr_660FEC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6960. sse_read128_xmm_xmm(ctx, "instr_660FEC", r1, r2);
  6961. }
  6962. pub fn instr_660FED_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6963. sse_read128_xmm_mem(ctx, "instr_660FED", modrm_byte, r);
  6964. }
  6965. pub fn instr_660FED_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6966. sse_read128_xmm_xmm(ctx, "instr_660FED", r1, r2);
  6967. }
  6968. pub fn instr_660FEE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6969. sse_read128_xmm_mem(ctx, "instr_660FEE", modrm_byte, r);
  6970. }
  6971. pub fn instr_660FEE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6972. sse_read128_xmm_xmm(ctx, "instr_660FEE", r1, r2);
  6973. }
  6974. pub fn instr_660FEF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6975. sse_read128_xmm_mem(ctx, "instr_660FEF", modrm_byte, r);
  6976. }
  6977. pub fn instr_660FEF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6978. sse_read128_xmm_xmm(ctx, "instr_660FEF", r1, r2);
  6979. }
  6980. pub fn instr_0FF1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6981. mmx_read64_mm_mem(ctx, "instr_0FF1", modrm_byte, r);
  6982. }
  6983. pub fn instr_0FF1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6984. mmx_read64_mm_mm(ctx, "instr_0FF1", r1, r2);
  6985. }
  6986. pub fn instr_0FF2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6987. mmx_read64_mm_mem(ctx, "instr_0FF2", modrm_byte, r);
  6988. }
  6989. pub fn instr_0FF2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6990. mmx_read64_mm_mm(ctx, "instr_0FF2", r1, r2);
  6991. }
  6992. pub fn instr_0FF3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6993. mmx_read64_mm_mem(ctx, "instr_0FF3", modrm_byte, r);
  6994. }
  6995. pub fn instr_0FF3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6996. mmx_read64_mm_mm(ctx, "instr_0FF3", r1, r2);
  6997. }
  6998. pub fn instr_0FF4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6999. mmx_read64_mm_mem(ctx, "instr_0FF4", modrm_byte, r);
  7000. }
  7001. pub fn instr_0FF4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7002. mmx_read64_mm_mm(ctx, "instr_0FF4", r1, r2);
  7003. }
  7004. pub fn instr_0FF5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7005. mmx_read64_mm_mem(ctx, "instr_0FF5", modrm_byte, r);
  7006. }
  7007. pub fn instr_0FF5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7008. mmx_read64_mm_mm(ctx, "instr_0FF5", r1, r2);
  7009. }
  7010. pub fn instr_0FF6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7011. mmx_read64_mm_mem(ctx, "instr_0FF6", modrm_byte, r);
  7012. }
  7013. pub fn instr_0FF6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7014. mmx_read64_mm_mm(ctx, "instr_0FF6", r1, r2);
  7015. }
  7016. pub fn instr_0FF7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
  7017. codegen::gen_trigger_ud(ctx)
  7018. }
  7019. pub fn instr_0FF7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7020. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  7021. ctx.builder,
  7022. ctx.start_of_current_instruction as i32 & 0xFFF,
  7023. );
  7024. codegen::gen_move_registers_from_locals_to_memory(ctx);
  7025. ctx.builder.const_i32(r1 as i32);
  7026. ctx.builder.const_i32(r2 as i32);
  7027. if ctx.cpu.asize_32() {
  7028. codegen::gen_get_reg32(ctx, regs::EDI);
  7029. }
  7030. else {
  7031. codegen::gen_get_reg16(ctx, regs::DI);
  7032. }
  7033. jit_add_seg_offset(ctx, regs::DS);
  7034. ctx.builder.call_fn3("maskmovq");
  7035. codegen::gen_move_registers_from_memory_to_locals(ctx);
  7036. codegen::gen_get_page_fault(ctx.builder);
  7037. ctx.builder.if_void();
  7038. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  7039. ctx.builder.br(ctx.exit_label);
  7040. ctx.builder.block_end();
  7041. }
  7042. pub fn instr_0FF8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7043. mmx_read64_mm_mem(ctx, "instr_0FF8", modrm_byte, r);
  7044. }
  7045. pub fn instr_0FF8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7046. mmx_read64_mm_mm(ctx, "instr_0FF8", r1, r2);
  7047. }
  7048. pub fn instr_0FF9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7049. mmx_read64_mm_mem(ctx, "instr_0FF9", modrm_byte, r);
  7050. }
  7051. pub fn instr_0FF9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7052. mmx_read64_mm_mm(ctx, "instr_0FF9", r1, r2);
  7053. }
  7054. pub fn instr_0FFA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7055. mmx_read64_mm_mem(ctx, "instr_0FFA", modrm_byte, r);
  7056. }
  7057. pub fn instr_0FFA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7058. mmx_read64_mm_mm(ctx, "instr_0FFA", r1, r2);
  7059. }
  7060. pub fn instr_0FFB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7061. mmx_read64_mm_mem(ctx, "instr_0FFB", modrm_byte, r);
  7062. }
  7063. pub fn instr_0FFB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7064. mmx_read64_mm_mm(ctx, "instr_0FFB", r1, r2);
  7065. }
  7066. pub fn instr_0FFC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7067. mmx_read64_mm_mem(ctx, "instr_0FFC", modrm_byte, r);
  7068. }
  7069. pub fn instr_0FFC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7070. mmx_read64_mm_mm(ctx, "instr_0FFC", r1, r2);
  7071. }
  7072. pub fn instr_0FFD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7073. mmx_read64_mm_mem(ctx, "instr_0FFD", modrm_byte, r);
  7074. }
  7075. pub fn instr_0FFD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7076. mmx_read64_mm_mm(ctx, "instr_0FFD", r1, r2);
  7077. }
  7078. pub fn instr_0FFE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7079. mmx_read64_mm_mem(ctx, "instr_0FFE", modrm_byte, r);
  7080. }
  7081. pub fn instr_0FFE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7082. mmx_read64_mm_mm(ctx, "instr_0FFE", r1, r2);
  7083. }
  7084. pub fn instr_660FF1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7085. sse_read128_xmm_mem(ctx, "instr_660FF1", modrm_byte, r);
  7086. }
  7087. pub fn instr_660FF1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7088. sse_read128_xmm_xmm(ctx, "instr_660FF1", r1, r2);
  7089. }
  7090. pub fn instr_660FF2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7091. sse_read128_xmm_mem(ctx, "instr_660FF2", modrm_byte, r);
  7092. }
  7093. pub fn instr_660FF2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7094. sse_read128_xmm_xmm(ctx, "instr_660FF2", r1, r2);
  7095. }
  7096. pub fn instr_660FF3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7097. sse_read128_xmm_mem(ctx, "instr_660FF3", modrm_byte, r);
  7098. }
  7099. pub fn instr_660FF3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7100. sse_read128_xmm_xmm(ctx, "instr_660FF3", r1, r2);
  7101. }
  7102. pub fn instr_660FF4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7103. sse_read128_xmm_mem(ctx, "instr_660FF4", modrm_byte, r);
  7104. }
  7105. pub fn instr_660FF4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7106. sse_read128_xmm_xmm(ctx, "instr_660FF4", r1, r2);
  7107. }
  7108. pub fn instr_660FF5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7109. sse_read128_xmm_mem(ctx, "instr_660FF5", modrm_byte, r);
  7110. }
  7111. pub fn instr_660FF5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7112. sse_read128_xmm_xmm(ctx, "instr_660FF5", r1, r2);
  7113. }
  7114. pub fn instr_660FF6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7115. sse_read128_xmm_mem(ctx, "instr_660FF6", modrm_byte, r);
  7116. }
  7117. pub fn instr_660FF6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7118. sse_read128_xmm_xmm(ctx, "instr_660FF6", r1, r2);
  7119. }
  7120. pub fn instr_660FF7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
  7121. codegen::gen_trigger_ud(ctx)
  7122. }
  7123. pub fn instr_660FF7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7124. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  7125. ctx.builder,
  7126. ctx.start_of_current_instruction as i32 & 0xFFF,
  7127. );
  7128. codegen::gen_move_registers_from_locals_to_memory(ctx);
  7129. ctx.builder.const_i32(r1 as i32);
  7130. ctx.builder.const_i32(r2 as i32);
  7131. if ctx.cpu.asize_32() {
  7132. codegen::gen_get_reg32(ctx, regs::EDI);
  7133. }
  7134. else {
  7135. codegen::gen_get_reg16(ctx, regs::DI);
  7136. }
  7137. jit_add_seg_offset(ctx, regs::DS);
  7138. ctx.builder.call_fn3("maskmovdqu");
  7139. codegen::gen_move_registers_from_memory_to_locals(ctx);
  7140. codegen::gen_get_page_fault(ctx.builder);
  7141. ctx.builder.if_void();
  7142. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  7143. ctx.builder.br(ctx.exit_label);
  7144. ctx.builder.block_end();
  7145. }
  7146. pub fn instr_660FF8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7147. sse_read128_xmm_mem(ctx, "instr_660FF8", modrm_byte, r);
  7148. }
  7149. pub fn instr_660FF8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7150. sse_read128_xmm_xmm(ctx, "instr_660FF8", r1, r2);
  7151. }
  7152. pub fn instr_660FF9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7153. sse_read128_xmm_mem(ctx, "instr_660FF9", modrm_byte, r);
  7154. }
  7155. pub fn instr_660FF9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7156. sse_read128_xmm_xmm(ctx, "instr_660FF9", r1, r2);
  7157. }
  7158. pub fn instr_660FFA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7159. sse_read128_xmm_mem(ctx, "instr_660FFA", modrm_byte, r);
  7160. }
  7161. pub fn instr_660FFA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7162. sse_read128_xmm_xmm(ctx, "instr_660FFA", r1, r2);
  7163. }
  7164. pub fn instr_660FFB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7165. sse_read128_xmm_mem(ctx, "instr_660FFB", modrm_byte, r);
  7166. }
  7167. pub fn instr_660FFB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7168. sse_read128_xmm_xmm(ctx, "instr_660FFB", r1, r2);
  7169. }
  7170. pub fn instr_660FFC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7171. sse_read128_xmm_mem(ctx, "instr_660FFC", modrm_byte, r);
  7172. }
  7173. pub fn instr_660FFC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7174. sse_read128_xmm_xmm(ctx, "instr_660FFC", r1, r2);
  7175. }
  7176. pub fn instr_660FFD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7177. sse_read128_xmm_mem(ctx, "instr_660FFD", modrm_byte, r);
  7178. }
  7179. pub fn instr_660FFD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7180. sse_read128_xmm_xmm(ctx, "instr_660FFD", r1, r2);
  7181. }
  7182. pub fn instr_660FFE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7183. sse_read128_xmm_mem(ctx, "instr_660FFE", modrm_byte, r);
  7184. }
  7185. pub fn instr_660FFE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7186. sse_read128_xmm_xmm(ctx, "instr_660FFE", r1, r2);
  7187. }