jit_instructions.rs 291 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702
  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) {
  2260. codegen::gen_get_sreg(ctx, regs::ES);
  2261. let sreg = ctx.builder.set_new_local();
  2262. codegen::gen_push32(ctx, &sreg);
  2263. ctx.builder.free_local(sreg);
  2264. }
  2265. pub fn instr16_0E_jit(ctx: &mut JitContext) {
  2266. codegen::gen_get_sreg(ctx, regs::CS);
  2267. let sreg = ctx.builder.set_new_local();
  2268. codegen::gen_push16(ctx, &sreg);
  2269. ctx.builder.free_local(sreg);
  2270. }
  2271. pub fn instr32_0E_jit(ctx: &mut JitContext) {
  2272. codegen::gen_get_sreg(ctx, regs::CS);
  2273. let sreg = ctx.builder.set_new_local();
  2274. codegen::gen_push32(ctx, &sreg);
  2275. ctx.builder.free_local(sreg);
  2276. }
  2277. pub fn instr16_16_jit(ctx: &mut JitContext) {
  2278. codegen::gen_get_sreg(ctx, regs::SS);
  2279. let sreg = ctx.builder.set_new_local();
  2280. codegen::gen_push16(ctx, &sreg);
  2281. ctx.builder.free_local(sreg);
  2282. }
  2283. pub fn instr32_16_jit(ctx: &mut JitContext) {
  2284. codegen::gen_get_sreg(ctx, regs::SS);
  2285. let sreg = ctx.builder.set_new_local();
  2286. codegen::gen_push32(ctx, &sreg);
  2287. ctx.builder.free_local(sreg);
  2288. }
  2289. pub fn instr16_1E_jit(ctx: &mut JitContext) {
  2290. codegen::gen_get_sreg(ctx, regs::DS);
  2291. let sreg = ctx.builder.set_new_local();
  2292. codegen::gen_push16(ctx, &sreg);
  2293. ctx.builder.free_local(sreg);
  2294. }
  2295. pub fn instr32_1E_jit(ctx: &mut JitContext) {
  2296. codegen::gen_get_sreg(ctx, regs::DS);
  2297. let sreg = ctx.builder.set_new_local();
  2298. codegen::gen_push32(ctx, &sreg);
  2299. ctx.builder.free_local(sreg);
  2300. }
  2301. pub fn instr16_40_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, AX); }
  2302. pub fn instr32_40_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EAX); }
  2303. pub fn instr16_41_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, CX); }
  2304. pub fn instr32_41_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, ECX); }
  2305. pub fn instr16_42_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, DX); }
  2306. pub fn instr32_42_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EDX); }
  2307. pub fn instr16_43_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, BX); }
  2308. pub fn instr32_43_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EBX); }
  2309. pub fn instr16_44_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, SP); }
  2310. pub fn instr32_44_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, ESP); }
  2311. pub fn instr16_45_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, BP); }
  2312. pub fn instr32_45_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EBP); }
  2313. pub fn instr16_46_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, SI); }
  2314. pub fn instr32_46_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, ESI); }
  2315. pub fn instr16_47_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, DI); }
  2316. pub fn instr32_47_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EDI); }
  2317. pub fn instr16_48_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, AX); }
  2318. pub fn instr32_48_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EAX); }
  2319. pub fn instr16_49_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, CX); }
  2320. pub fn instr32_49_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, ECX); }
  2321. pub fn instr16_4A_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, DX); }
  2322. pub fn instr32_4A_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EDX); }
  2323. pub fn instr16_4B_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, BX); }
  2324. pub fn instr32_4B_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EBX); }
  2325. pub fn instr16_4C_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, SP); }
  2326. pub fn instr32_4C_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, ESP); }
  2327. pub fn instr16_4D_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, BP); }
  2328. pub fn instr32_4D_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EBP); }
  2329. pub fn instr16_4E_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, SI); }
  2330. pub fn instr32_4E_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, ESI); }
  2331. pub fn instr16_4F_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, DI); }
  2332. pub fn instr32_4F_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EDI); }
  2333. pub fn instr16_50_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, AX); }
  2334. pub fn instr32_50_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EAX); }
  2335. pub fn instr16_51_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, CX); }
  2336. pub fn instr32_51_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, ECX); }
  2337. pub fn instr16_52_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, DX); }
  2338. pub fn instr32_52_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EDX); }
  2339. pub fn instr16_53_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, BX); }
  2340. pub fn instr32_53_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EBX); }
  2341. pub fn instr16_54_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, SP); }
  2342. pub fn instr32_54_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, ESP); }
  2343. pub fn instr16_55_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, BP); }
  2344. pub fn instr32_55_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EBP); }
  2345. pub fn instr16_56_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, SI); }
  2346. pub fn instr32_56_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, ESI); }
  2347. pub fn instr16_57_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, DI); }
  2348. pub fn instr32_57_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EDI); }
  2349. pub fn instr16_58_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, AX); }
  2350. pub fn instr32_58_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EAX); }
  2351. pub fn instr16_59_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, CX); }
  2352. pub fn instr32_59_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, ECX); }
  2353. pub fn instr16_5A_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, DX); }
  2354. pub fn instr32_5A_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EDX); }
  2355. pub fn instr16_5B_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, BX); }
  2356. pub fn instr32_5B_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EBX); }
  2357. pub fn instr16_5C_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, SP); }
  2358. pub fn instr32_5C_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, ESP); }
  2359. pub fn instr16_5D_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, BP); }
  2360. pub fn instr32_5D_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EBP); }
  2361. pub fn instr16_5E_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, SI); }
  2362. pub fn instr32_5E_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, ESI); }
  2363. pub fn instr16_5F_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, DI); }
  2364. pub fn instr32_5F_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EDI); }
  2365. pub fn instr16_68_jit(ctx: &mut JitContext, imm16: u32) { push16_imm_jit(ctx, imm16) }
  2366. pub fn instr32_68_jit(ctx: &mut JitContext, imm32: u32) { push32_imm_jit(ctx, imm32) }
  2367. pub fn instr16_6A_jit(ctx: &mut JitContext, imm16: u32) { push16_imm_jit(ctx, imm16) }
  2368. pub fn instr32_6A_jit(ctx: &mut JitContext, imm32: u32) { push32_imm_jit(ctx, imm32) }
  2369. pub fn instr16_69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm16: u32) {
  2370. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  2371. ctx.builder.const_i32(imm16 as i32);
  2372. ctx.builder.call_fn2_ret("imul_reg16");
  2373. codegen::gen_set_reg16(ctx, r);
  2374. }
  2375. pub fn instr16_69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm16: u32) {
  2376. codegen::gen_get_reg16(ctx, r1);
  2377. ctx.builder.const_i32(imm16 as i32);
  2378. ctx.builder.call_fn2_ret("imul_reg16");
  2379. codegen::gen_set_reg16(ctx, r2);
  2380. }
  2381. pub fn instr32_69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm32: u32) {
  2382. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  2383. let value_local = ctx.builder.set_new_local();
  2384. gen_imul3_reg32(
  2385. ctx.builder,
  2386. &ctx.register_locals[r as usize],
  2387. &value_local,
  2388. &LocalOrImmediate::Immediate(imm32 as i32),
  2389. );
  2390. ctx.builder.free_local(value_local);
  2391. }
  2392. pub fn instr32_69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm32: u32) {
  2393. gen_imul3_reg32(
  2394. ctx.builder,
  2395. &ctx.register_locals[r2 as usize],
  2396. &ctx.register_locals[r1 as usize],
  2397. &LocalOrImmediate::Immediate(imm32 as i32),
  2398. );
  2399. }
  2400. pub fn instr16_6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8s: u32) {
  2401. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  2402. ctx.builder.const_i32(imm8s as i32);
  2403. ctx.builder.call_fn2_ret("imul_reg16");
  2404. codegen::gen_set_reg16(ctx, r);
  2405. }
  2406. pub fn instr16_6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8s: u32) {
  2407. codegen::gen_get_reg16(ctx, r1);
  2408. ctx.builder.const_i32(imm8s as i32);
  2409. ctx.builder.call_fn2_ret("imul_reg16");
  2410. codegen::gen_set_reg16(ctx, r2);
  2411. }
  2412. pub fn instr32_6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8s: u32) {
  2413. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  2414. let value_local = ctx.builder.set_new_local();
  2415. gen_imul3_reg32(
  2416. ctx.builder,
  2417. &ctx.register_locals[r as usize],
  2418. &value_local,
  2419. &LocalOrImmediate::Immediate(imm8s as i32),
  2420. );
  2421. ctx.builder.free_local(value_local);
  2422. }
  2423. pub fn instr32_6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8s: u32) {
  2424. gen_imul3_reg32(
  2425. ctx.builder,
  2426. &ctx.register_locals[r2 as usize],
  2427. &ctx.register_locals[r1 as usize],
  2428. &LocalOrImmediate::Immediate(imm8s as i32),
  2429. );
  2430. }
  2431. // Code for conditional jumps is generated automatically by the basic block codegen
  2432. pub fn instr16_70_jit(_ctx: &mut JitContext, _imm: u32) {}
  2433. pub fn instr32_70_jit(_ctx: &mut JitContext, _imm: u32) {}
  2434. pub fn instr16_71_jit(_ctx: &mut JitContext, _imm: u32) {}
  2435. pub fn instr32_71_jit(_ctx: &mut JitContext, _imm: u32) {}
  2436. pub fn instr16_72_jit(_ctx: &mut JitContext, _imm: u32) {}
  2437. pub fn instr32_72_jit(_ctx: &mut JitContext, _imm: u32) {}
  2438. pub fn instr16_73_jit(_ctx: &mut JitContext, _imm: u32) {}
  2439. pub fn instr32_73_jit(_ctx: &mut JitContext, _imm: u32) {}
  2440. pub fn instr16_74_jit(_ctx: &mut JitContext, _imm: u32) {}
  2441. pub fn instr32_74_jit(_ctx: &mut JitContext, _imm: u32) {}
  2442. pub fn instr16_75_jit(_ctx: &mut JitContext, _imm: u32) {}
  2443. pub fn instr32_75_jit(_ctx: &mut JitContext, _imm: u32) {}
  2444. pub fn instr16_76_jit(_ctx: &mut JitContext, _imm: u32) {}
  2445. pub fn instr32_76_jit(_ctx: &mut JitContext, _imm: u32) {}
  2446. pub fn instr16_77_jit(_ctx: &mut JitContext, _imm: u32) {}
  2447. pub fn instr32_77_jit(_ctx: &mut JitContext, _imm: u32) {}
  2448. pub fn instr16_78_jit(_ctx: &mut JitContext, _imm: u32) {}
  2449. pub fn instr32_78_jit(_ctx: &mut JitContext, _imm: u32) {}
  2450. pub fn instr16_79_jit(_ctx: &mut JitContext, _imm: u32) {}
  2451. pub fn instr32_79_jit(_ctx: &mut JitContext, _imm: u32) {}
  2452. pub fn instr16_7A_jit(_ctx: &mut JitContext, _imm: u32) {}
  2453. pub fn instr32_7A_jit(_ctx: &mut JitContext, _imm: u32) {}
  2454. pub fn instr16_7B_jit(_ctx: &mut JitContext, _imm: u32) {}
  2455. pub fn instr32_7B_jit(_ctx: &mut JitContext, _imm: u32) {}
  2456. pub fn instr16_7C_jit(_ctx: &mut JitContext, _imm: u32) {}
  2457. pub fn instr32_7C_jit(_ctx: &mut JitContext, _imm: u32) {}
  2458. pub fn instr16_7D_jit(_ctx: &mut JitContext, _imm: u32) {}
  2459. pub fn instr32_7D_jit(_ctx: &mut JitContext, _imm: u32) {}
  2460. pub fn instr16_7E_jit(_ctx: &mut JitContext, _imm: u32) {}
  2461. pub fn instr32_7E_jit(_ctx: &mut JitContext, _imm: u32) {}
  2462. pub fn instr16_7F_jit(_ctx: &mut JitContext, _imm: u32) {}
  2463. pub fn instr32_7F_jit(_ctx: &mut JitContext, _imm: u32) {}
  2464. // loop/loopz/loopnz/jcxz: Conditional jump is generated in main loop
  2465. pub fn instr16_E0_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2466. pub fn instr32_E0_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2467. pub fn instr16_E1_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2468. pub fn instr32_E1_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2469. pub fn instr16_E2_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2470. pub fn instr32_E2_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
  2471. pub fn instr16_E3_jit(_ctx: &mut JitContext, _imm: u32) {}
  2472. pub fn instr32_E3_jit(_ctx: &mut JitContext, _imm: u32) {}
  2473. define_instruction_read_write_mem8!(gen_add8, instr_80_0_mem_jit, instr_80_0_reg_jit, ximm8);
  2474. define_instruction_read_write_mem8!(gen_or8, instr_80_1_mem_jit, instr_80_1_reg_jit, ximm8);
  2475. define_instruction_read_write_mem8!(gen_adc8, instr_80_2_mem_jit, instr_80_2_reg_jit, ximm8);
  2476. define_instruction_read_write_mem8!(gen_sbb8, instr_80_3_mem_jit, instr_80_3_reg_jit, ximm8);
  2477. define_instruction_read_write_mem8!(gen_and8, instr_80_4_mem_jit, instr_80_4_reg_jit, ximm8);
  2478. define_instruction_read_write_mem8!(gen_sub8, instr_80_5_mem_jit, instr_80_5_reg_jit, ximm8);
  2479. define_instruction_read_write_mem8!(gen_xor8, instr_80_6_mem_jit, instr_80_6_reg_jit, ximm8);
  2480. define_instruction_read_write_mem8!(gen_add8, instr_82_0_mem_jit, instr_82_0_reg_jit, ximm8);
  2481. define_instruction_read_write_mem8!(gen_or8, instr_82_1_mem_jit, instr_82_1_reg_jit, ximm8);
  2482. define_instruction_read_write_mem8!(gen_adc8, instr_82_2_mem_jit, instr_82_2_reg_jit, ximm8);
  2483. define_instruction_read_write_mem8!(gen_sbb8, instr_82_3_mem_jit, instr_82_3_reg_jit, ximm8);
  2484. define_instruction_read_write_mem8!(gen_and8, instr_82_4_mem_jit, instr_82_4_reg_jit, ximm8);
  2485. define_instruction_read_write_mem8!(gen_sub8, instr_82_5_mem_jit, instr_82_5_reg_jit, ximm8);
  2486. define_instruction_read_write_mem8!(gen_xor8, instr_82_6_mem_jit, instr_82_6_reg_jit, ximm8);
  2487. define_instruction_read_write_mem16!("add16", instr16_81_0_mem_jit, instr16_81_0_reg_jit, imm16);
  2488. define_instruction_read_write_mem32!(gen_add32, instr32_81_0_mem_jit, instr32_81_0_reg_jit, imm32);
  2489. define_instruction_read_write_mem16!("or16", instr16_81_1_mem_jit, instr16_81_1_reg_jit, imm16);
  2490. define_instruction_read_write_mem32!(gen_or32, instr32_81_1_mem_jit, instr32_81_1_reg_jit, imm32);
  2491. define_instruction_read_write_mem16!("adc16", instr16_81_2_mem_jit, instr16_81_2_reg_jit, imm16);
  2492. define_instruction_read_write_mem32!(gen_adc32, instr32_81_2_mem_jit, instr32_81_2_reg_jit, imm32);
  2493. define_instruction_read_write_mem16!("sbb16", instr16_81_3_mem_jit, instr16_81_3_reg_jit, imm16);
  2494. define_instruction_read_write_mem32!(gen_sbb32, instr32_81_3_mem_jit, instr32_81_3_reg_jit, imm32);
  2495. define_instruction_read_write_mem16!("and16", instr16_81_4_mem_jit, instr16_81_4_reg_jit, imm16);
  2496. define_instruction_read_write_mem32!(gen_and32, instr32_81_4_mem_jit, instr32_81_4_reg_jit, imm32);
  2497. define_instruction_read_write_mem16!("sub16", instr16_81_5_mem_jit, instr16_81_5_reg_jit, imm16);
  2498. define_instruction_read_write_mem32!(gen_sub32, instr32_81_5_mem_jit, instr32_81_5_reg_jit, imm32);
  2499. define_instruction_read_write_mem16!("xor16", instr16_81_6_mem_jit, instr16_81_6_reg_jit, imm16);
  2500. define_instruction_read_write_mem32!(gen_xor32, instr32_81_6_mem_jit, instr32_81_6_reg_jit, imm32);
  2501. define_instruction_read_write_mem16!(
  2502. "add16",
  2503. instr16_83_0_mem_jit,
  2504. instr16_83_0_reg_jit,
  2505. imm8s_16bits
  2506. );
  2507. define_instruction_read_write_mem32!(gen_add32, instr32_83_0_mem_jit, instr32_83_0_reg_jit, imm8s);
  2508. define_instruction_read_write_mem16!(
  2509. "or16",
  2510. instr16_83_1_mem_jit,
  2511. instr16_83_1_reg_jit,
  2512. imm8s_16bits
  2513. );
  2514. define_instruction_read_write_mem32!(gen_or32, instr32_83_1_mem_jit, instr32_83_1_reg_jit, imm8s);
  2515. define_instruction_read_write_mem16!(
  2516. "adc16",
  2517. instr16_83_2_mem_jit,
  2518. instr16_83_2_reg_jit,
  2519. imm8s_16bits
  2520. );
  2521. define_instruction_read_write_mem32!(gen_adc32, instr32_83_2_mem_jit, instr32_83_2_reg_jit, imm8s);
  2522. define_instruction_read_write_mem16!(
  2523. "sbb16",
  2524. instr16_83_3_mem_jit,
  2525. instr16_83_3_reg_jit,
  2526. imm8s_16bits
  2527. );
  2528. define_instruction_read_write_mem32!(gen_sbb32, instr32_83_3_mem_jit, instr32_83_3_reg_jit, imm8s);
  2529. define_instruction_read_write_mem16!(
  2530. "and16",
  2531. instr16_83_4_mem_jit,
  2532. instr16_83_4_reg_jit,
  2533. imm8s_16bits
  2534. );
  2535. define_instruction_read_write_mem32!(gen_and32, instr32_83_4_mem_jit, instr32_83_4_reg_jit, imm8s);
  2536. define_instruction_read_write_mem16!(
  2537. "sub16",
  2538. instr16_83_5_mem_jit,
  2539. instr16_83_5_reg_jit,
  2540. imm8s_16bits
  2541. );
  2542. define_instruction_read_write_mem32!(gen_sub32, instr32_83_5_mem_jit, instr32_83_5_reg_jit, imm8s);
  2543. define_instruction_read_write_mem16!(
  2544. "xor16",
  2545. instr16_83_6_mem_jit,
  2546. instr16_83_6_reg_jit,
  2547. imm8s_16bits
  2548. );
  2549. define_instruction_read_write_mem32!(gen_xor32, instr32_83_6_mem_jit, instr32_83_6_reg_jit, imm8s);
  2550. define_instruction_read8!(gen_cmp8, instr_80_7_mem_jit, instr_80_7_reg_jit, imm8);
  2551. define_instruction_read16!(gen_cmp16, instr16_81_7_mem_jit, instr16_81_7_reg_jit, imm16);
  2552. define_instruction_read32!(gen_cmp32, instr32_81_7_mem_jit, instr32_81_7_reg_jit, imm32);
  2553. define_instruction_read8!(gen_cmp8, instr_82_7_mem_jit, instr_82_7_reg_jit, imm8);
  2554. define_instruction_read16!(
  2555. gen_cmp16,
  2556. instr16_83_7_mem_jit,
  2557. instr16_83_7_reg_jit,
  2558. imm8s_16bits
  2559. );
  2560. define_instruction_read32!(gen_cmp32, instr32_83_7_mem_jit, instr32_83_7_reg_jit, imm8s);
  2561. define_instruction_read8!(gen_test8, instr_84_mem_jit, instr_84_reg_jit);
  2562. define_instruction_read16!(gen_test16, instr16_85_mem_jit, instr16_85_reg_jit);
  2563. define_instruction_read32!(gen_test32, instr32_85_mem_jit, instr32_85_reg_jit);
  2564. pub fn instr_86_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::BYTE, &addr, &|ref mut ctx| {
  2567. codegen::gen_get_reg8(ctx, r);
  2568. let tmp = ctx.builder.set_new_local();
  2569. codegen::gen_set_reg8(ctx, r);
  2570. ctx.builder.get_local(&tmp);
  2571. ctx.builder.free_local(tmp);
  2572. });
  2573. });
  2574. }
  2575. pub fn instr_86_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2576. codegen::gen_get_reg8(ctx, r2);
  2577. let tmp = ctx.builder.set_new_local();
  2578. codegen::gen_get_reg8(ctx, r1);
  2579. codegen::gen_set_reg8(ctx, r2);
  2580. ctx.builder.get_local(&tmp);
  2581. codegen::gen_set_reg8(ctx, r1);
  2582. ctx.builder.free_local(tmp);
  2583. }
  2584. pub fn instr16_87_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2585. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  2586. codegen::gen_safe_read_write(ctx, BitSize::WORD, &addr, &|ref mut ctx| {
  2587. codegen::gen_get_reg16(ctx, r);
  2588. let tmp = ctx.builder.set_new_local();
  2589. codegen::gen_set_reg16(ctx, r);
  2590. ctx.builder.get_local(&tmp);
  2591. ctx.builder.free_local(tmp);
  2592. });
  2593. });
  2594. }
  2595. pub fn instr32_87_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2596. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  2597. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &addr, &|ref mut ctx| {
  2598. codegen::gen_get_reg32(ctx, r);
  2599. let tmp = ctx.builder.set_new_local();
  2600. codegen::gen_set_reg32(ctx, r);
  2601. ctx.builder.get_local(&tmp);
  2602. ctx.builder.free_local(tmp);
  2603. });
  2604. });
  2605. }
  2606. pub fn instr16_87_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2607. codegen::gen_get_reg16(ctx, r2);
  2608. let tmp = ctx.builder.set_new_local();
  2609. codegen::gen_get_reg16(ctx, r1);
  2610. codegen::gen_set_reg16(ctx, r2);
  2611. ctx.builder.get_local(&tmp);
  2612. codegen::gen_set_reg16(ctx, r1);
  2613. ctx.builder.free_local(tmp);
  2614. }
  2615. pub fn instr32_87_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2616. codegen::gen_get_reg32(ctx, r2);
  2617. let tmp = ctx.builder.set_new_local();
  2618. codegen::gen_get_reg32(ctx, r1);
  2619. codegen::gen_set_reg32(ctx, r2);
  2620. ctx.builder.get_local(&tmp);
  2621. codegen::gen_set_reg32(ctx, r1);
  2622. ctx.builder.free_local(tmp);
  2623. }
  2624. pub fn instr_88_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2625. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  2626. codegen::gen_get_reg8(ctx, r);
  2627. let value_local = ctx.builder.set_new_local();
  2628. codegen::gen_safe_write8(ctx, &addr, &value_local);
  2629. ctx.builder.free_local(value_local);
  2630. });
  2631. }
  2632. pub fn instr_88_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2633. codegen::gen_set_reg8_r(ctx, r1, r2);
  2634. }
  2635. pub fn instr16_89_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2636. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  2637. codegen::gen_safe_write16(ctx, addr, &ctx.reg(r));
  2638. });
  2639. }
  2640. pub fn instr16_89_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2641. codegen::gen_set_reg16_r(ctx, r1, r2);
  2642. }
  2643. pub fn instr32_89_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2644. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  2645. codegen::gen_safe_write32(ctx, &addr, &ctx.reg(r));
  2646. });
  2647. }
  2648. pub fn instr32_89_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2649. codegen::gen_set_reg32_r(ctx, r1, r2);
  2650. }
  2651. pub fn instr_8A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2652. // Pseudo: reg8[r] = safe_read8(modrm_resolve(modrm_byte));
  2653. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
  2654. codegen::gen_set_reg8_unmasked(ctx, r);
  2655. }
  2656. pub fn instr_8A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2657. codegen::gen_set_reg8_r(ctx, r2, r1);
  2658. }
  2659. pub fn instr16_8B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2660. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  2661. codegen::gen_set_reg16_unmasked(ctx, r);
  2662. }
  2663. pub fn instr16_8B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2664. codegen::gen_set_reg16_r(ctx, r2, r1);
  2665. }
  2666. pub fn instr32_8B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2667. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  2668. codegen::gen_set_reg32(ctx, r);
  2669. }
  2670. pub fn instr32_8B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2671. codegen::gen_set_reg32_r(ctx, r2, r1);
  2672. }
  2673. pub fn instr16_8C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2674. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2675. let address_local = ctx.builder.set_new_local();
  2676. if r >= 6 {
  2677. codegen::gen_trigger_ud(ctx);
  2678. }
  2679. else {
  2680. codegen::gen_get_sreg(ctx, r);
  2681. let value_local = ctx.builder.set_new_local();
  2682. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  2683. ctx.builder.free_local(value_local);
  2684. }
  2685. ctx.builder.free_local(address_local);
  2686. }
  2687. pub fn instr32_8C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  2688. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2689. let address_local = ctx.builder.set_new_local();
  2690. if r >= 6 {
  2691. codegen::gen_trigger_ud(ctx);
  2692. }
  2693. else {
  2694. codegen::gen_get_sreg(ctx, r);
  2695. let value_local = ctx.builder.set_new_local();
  2696. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  2697. ctx.builder.free_local(value_local);
  2698. }
  2699. ctx.builder.free_local(address_local);
  2700. }
  2701. pub fn instr16_8C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2702. if r2 >= 6 {
  2703. codegen::gen_trigger_ud(ctx);
  2704. }
  2705. else {
  2706. codegen::gen_get_sreg(ctx, r2);
  2707. codegen::gen_set_reg16(ctx, r1);
  2708. }
  2709. }
  2710. pub fn instr32_8C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  2711. if r2 >= 6 {
  2712. codegen::gen_trigger_ud(ctx);
  2713. }
  2714. else {
  2715. codegen::gen_get_sreg(ctx, r2);
  2716. codegen::gen_set_reg32(ctx, r1);
  2717. }
  2718. }
  2719. pub fn instr16_8D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, reg: u32) {
  2720. ctx.cpu.prefixes |= SEG_PREFIX_ZERO;
  2721. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2722. codegen::gen_set_reg16(ctx, reg);
  2723. }
  2724. pub fn instr32_8D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, reg: u32) {
  2725. if !modrm_byte.is_nop(reg) {
  2726. ctx.cpu.prefixes |= SEG_PREFIX_ZERO;
  2727. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2728. codegen::gen_set_reg32(ctx, reg);
  2729. }
  2730. }
  2731. pub fn instr16_8D_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  2732. codegen::gen_trigger_ud(ctx);
  2733. }
  2734. pub fn instr32_8D_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  2735. codegen::gen_trigger_ud(ctx);
  2736. }
  2737. pub fn instr16_8F_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  2738. // before gen_modrm_resolve, update esp to the new value
  2739. codegen::gen_adjust_stack_reg(ctx, 2);
  2740. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2741. let address_local = ctx.builder.set_new_local();
  2742. // pop takes care of updating esp, so undo the previous change
  2743. codegen::gen_adjust_stack_reg(ctx, (-2i32) as u32);
  2744. codegen::gen_pop16(ctx);
  2745. let value_local = ctx.builder.set_new_local();
  2746. // undo the esp change of pop, as safe_write16 can fail
  2747. codegen::gen_adjust_stack_reg(ctx, (-2i32) as u32);
  2748. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  2749. ctx.builder.free_local(address_local);
  2750. ctx.builder.free_local(value_local);
  2751. // finally, actually update esp
  2752. codegen::gen_adjust_stack_reg(ctx, 2);
  2753. }
  2754. pub fn instr16_8F_0_reg_jit(ctx: &mut JitContext, r: u32) { pop16_reg_jit(ctx, r); }
  2755. pub fn instr32_8F_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  2756. codegen::gen_adjust_stack_reg(ctx, 4);
  2757. codegen::gen_modrm_resolve(ctx, modrm_byte);
  2758. let address_local = ctx.builder.set_new_local();
  2759. codegen::gen_adjust_stack_reg(ctx, (-4i32) as u32);
  2760. codegen::gen_pop32s(ctx);
  2761. let value_local = ctx.builder.set_new_local();
  2762. codegen::gen_adjust_stack_reg(ctx, (-4i32) as u32);
  2763. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  2764. ctx.builder.free_local(address_local);
  2765. ctx.builder.free_local(value_local);
  2766. codegen::gen_adjust_stack_reg(ctx, 4);
  2767. }
  2768. pub fn instr32_8F_0_reg_jit(ctx: &mut JitContext, r: u32) { pop32_reg_jit(ctx, r); }
  2769. define_instruction_read_write_mem16!(
  2770. "rol16",
  2771. instr16_C1_0_mem_jit,
  2772. instr16_C1_0_reg_jit,
  2773. imm8_5bits
  2774. );
  2775. define_instruction_read_write_mem32!(
  2776. gen_rol32,
  2777. instr32_C1_0_mem_jit,
  2778. instr32_C1_0_reg_jit,
  2779. imm8_5bits
  2780. );
  2781. define_instruction_read_write_mem16!(
  2782. "ror16",
  2783. instr16_C1_1_mem_jit,
  2784. instr16_C1_1_reg_jit,
  2785. imm8_5bits
  2786. );
  2787. define_instruction_read_write_mem32!(
  2788. gen_ror32,
  2789. instr32_C1_1_mem_jit,
  2790. instr32_C1_1_reg_jit,
  2791. imm8_5bits
  2792. );
  2793. define_instruction_read_write_mem16!(
  2794. "rcl16",
  2795. instr16_C1_2_mem_jit,
  2796. instr16_C1_2_reg_jit,
  2797. imm8_5bits
  2798. );
  2799. define_instruction_read_write_mem32!(
  2800. gen_rcl32,
  2801. instr32_C1_2_mem_jit,
  2802. instr32_C1_2_reg_jit,
  2803. imm8_5bits
  2804. );
  2805. define_instruction_read_write_mem16!(
  2806. "rcr16",
  2807. instr16_C1_3_mem_jit,
  2808. instr16_C1_3_reg_jit,
  2809. imm8_5bits
  2810. );
  2811. define_instruction_read_write_mem32!(
  2812. gen_rcr32,
  2813. instr32_C1_3_mem_jit,
  2814. instr32_C1_3_reg_jit,
  2815. imm8_5bits
  2816. );
  2817. define_instruction_read_write_mem16!(
  2818. "shl16",
  2819. instr16_C1_4_mem_jit,
  2820. instr16_C1_4_reg_jit,
  2821. imm8_5bits
  2822. );
  2823. define_instruction_read_write_mem32!(
  2824. gen_shl32,
  2825. instr32_C1_4_mem_jit,
  2826. instr32_C1_4_reg_jit,
  2827. imm8_5bits
  2828. );
  2829. define_instruction_read_write_mem16!(
  2830. "shr16",
  2831. instr16_C1_5_mem_jit,
  2832. instr16_C1_5_reg_jit,
  2833. imm8_5bits
  2834. );
  2835. define_instruction_read_write_mem32!(
  2836. gen_shr32,
  2837. instr32_C1_5_mem_jit,
  2838. instr32_C1_5_reg_jit,
  2839. imm8_5bits
  2840. );
  2841. define_instruction_read_write_mem16!(
  2842. "shl16",
  2843. instr16_C1_6_mem_jit,
  2844. instr16_C1_6_reg_jit,
  2845. imm8_5bits
  2846. );
  2847. define_instruction_read_write_mem32!(
  2848. gen_shl32,
  2849. instr32_C1_6_mem_jit,
  2850. instr32_C1_6_reg_jit,
  2851. imm8_5bits
  2852. );
  2853. define_instruction_read_write_mem16!(
  2854. "sar16",
  2855. instr16_C1_7_mem_jit,
  2856. instr16_C1_7_reg_jit,
  2857. imm8_5bits
  2858. );
  2859. define_instruction_read_write_mem32!(
  2860. gen_sar32,
  2861. instr32_C1_7_mem_jit,
  2862. instr32_C1_7_reg_jit,
  2863. imm8_5bits
  2864. );
  2865. pub fn instr16_E8_jit(ctx: &mut JitContext, _imm: u32) {
  2866. codegen::gen_get_real_eip(ctx);
  2867. let value_local = ctx.builder.set_new_local();
  2868. codegen::gen_push16(ctx, &value_local);
  2869. ctx.builder.free_local(value_local);
  2870. }
  2871. pub fn instr32_E8_jit(ctx: &mut JitContext, _imm: u32) {
  2872. codegen::gen_get_real_eip(ctx);
  2873. let value_local = ctx.builder.set_new_local();
  2874. codegen::gen_push32(ctx, &value_local);
  2875. ctx.builder.free_local(value_local);
  2876. }
  2877. pub fn instr16_E9_jit(_ctx: &mut JitContext, _imm: u32) {
  2878. //
  2879. }
  2880. pub fn instr32_E9_jit(_ctx: &mut JitContext, _imm: u32) {
  2881. //
  2882. }
  2883. pub fn instr16_C2_jit(ctx: &mut JitContext, imm16: u32) {
  2884. ctx.builder.const_i32(0);
  2885. codegen::gen_pop16(ctx);
  2886. codegen::gen_add_cs_offset(ctx);
  2887. ctx.builder
  2888. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  2889. codegen::gen_adjust_stack_reg(ctx, imm16);
  2890. }
  2891. pub fn instr32_C2_jit(ctx: &mut JitContext, imm16: u32) {
  2892. ctx.builder.const_i32(0);
  2893. codegen::gen_pop32s(ctx);
  2894. codegen::gen_add_cs_offset(ctx);
  2895. ctx.builder
  2896. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  2897. codegen::gen_adjust_stack_reg(ctx, imm16);
  2898. }
  2899. pub fn instr16_C3_jit(ctx: &mut JitContext) {
  2900. ctx.builder.const_i32(0);
  2901. codegen::gen_pop16(ctx);
  2902. codegen::gen_add_cs_offset(ctx);
  2903. ctx.builder
  2904. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  2905. }
  2906. pub fn instr32_C3_jit(ctx: &mut JitContext) {
  2907. ctx.builder.const_i32(0);
  2908. codegen::gen_pop32s(ctx);
  2909. codegen::gen_add_cs_offset(ctx);
  2910. ctx.builder
  2911. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  2912. }
  2913. pub fn instr16_C9_jit(ctx: &mut JitContext) { codegen::gen_leave(ctx, false); }
  2914. pub fn instr32_C9_jit(ctx: &mut JitContext) { codegen::gen_leave(ctx, true); }
  2915. pub fn gen_mov_reg8_imm(ctx: &mut JitContext, r: u32, imm: u32) {
  2916. ctx.builder.const_i32(imm as i32);
  2917. codegen::gen_set_reg8_unmasked(ctx, r);
  2918. }
  2919. pub fn instr_B0_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 0, imm) }
  2920. pub fn instr_B1_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 1, imm) }
  2921. pub fn instr_B2_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 2, imm) }
  2922. pub fn instr_B3_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 3, imm) }
  2923. pub fn instr_B4_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 4, imm) }
  2924. pub fn instr_B5_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 5, imm) }
  2925. pub fn instr_B6_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 6, imm) }
  2926. pub fn instr_B7_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 7, imm) }
  2927. pub fn gen_mov_reg16_imm(ctx: &mut JitContext, r: u32, imm: u32) {
  2928. ctx.builder.const_i32(imm as i32);
  2929. codegen::gen_set_reg16_unmasked(ctx, r);
  2930. }
  2931. pub fn instr16_B8_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 0, imm) }
  2932. pub fn instr16_B9_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 1, imm) }
  2933. pub fn instr16_BA_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 2, imm) }
  2934. pub fn instr16_BB_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 3, imm) }
  2935. pub fn instr16_BC_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 4, imm) }
  2936. pub fn instr16_BD_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 5, imm) }
  2937. pub fn instr16_BE_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 6, imm) }
  2938. pub fn instr16_BF_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 7, imm) }
  2939. pub fn gen_mov_reg32_imm(ctx: &mut JitContext, r: u32, imm: u32) {
  2940. ctx.builder.const_i32(imm as i32);
  2941. codegen::gen_set_reg32(ctx, r);
  2942. }
  2943. pub fn instr32_B8_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 0, imm) }
  2944. pub fn instr32_B9_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 1, imm) }
  2945. pub fn instr32_BA_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 2, imm) }
  2946. pub fn instr32_BB_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 3, imm) }
  2947. pub fn instr32_BC_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 4, imm) }
  2948. pub fn instr32_BD_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 5, imm) }
  2949. pub fn instr32_BE_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 6, imm) }
  2950. pub fn instr32_BF_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 7, imm) }
  2951. define_instruction_read_write_mem8!("rol8", instr_C0_0_mem_jit, instr_C0_0_reg_jit, imm8_5bits);
  2952. define_instruction_read_write_mem8!("ror8", instr_C0_1_mem_jit, instr_C0_1_reg_jit, imm8_5bits);
  2953. define_instruction_read_write_mem8!("rcl8", instr_C0_2_mem_jit, instr_C0_2_reg_jit, imm8_5bits);
  2954. define_instruction_read_write_mem8!("rcr8", instr_C0_3_mem_jit, instr_C0_3_reg_jit, imm8_5bits);
  2955. define_instruction_read_write_mem8!("shl8", instr_C0_4_mem_jit, instr_C0_4_reg_jit, imm8_5bits);
  2956. define_instruction_read_write_mem8!("shr8", instr_C0_5_mem_jit, instr_C0_5_reg_jit, imm8_5bits);
  2957. define_instruction_read_write_mem8!("shl8", instr_C0_6_mem_jit, instr_C0_6_reg_jit, imm8_5bits);
  2958. define_instruction_read_write_mem8!("sar8", instr_C0_7_mem_jit, instr_C0_7_reg_jit, imm8_5bits);
  2959. define_instruction_read_write_mem8!("rol8", instr_D0_0_mem_jit, instr_D0_0_reg_jit, constant_one);
  2960. define_instruction_read_write_mem8!("ror8", instr_D0_1_mem_jit, instr_D0_1_reg_jit, constant_one);
  2961. define_instruction_read_write_mem8!("rcl8", instr_D0_2_mem_jit, instr_D0_2_reg_jit, constant_one);
  2962. define_instruction_read_write_mem8!("rcr8", instr_D0_3_mem_jit, instr_D0_3_reg_jit, constant_one);
  2963. define_instruction_read_write_mem8!("shl8", instr_D0_4_mem_jit, instr_D0_4_reg_jit, constant_one);
  2964. define_instruction_read_write_mem8!("shr8", instr_D0_5_mem_jit, instr_D0_5_reg_jit, constant_one);
  2965. define_instruction_read_write_mem8!("shl8", instr_D0_6_mem_jit, instr_D0_6_reg_jit, constant_one);
  2966. define_instruction_read_write_mem8!("sar8", instr_D0_7_mem_jit, instr_D0_7_reg_jit, constant_one);
  2967. define_instruction_read_write_mem16!(
  2968. "rol16",
  2969. instr16_D1_0_mem_jit,
  2970. instr16_D1_0_reg_jit,
  2971. constant_one
  2972. );
  2973. define_instruction_read_write_mem32!(
  2974. gen_rol32,
  2975. instr32_D1_0_mem_jit,
  2976. instr32_D1_0_reg_jit,
  2977. constant_one
  2978. );
  2979. define_instruction_read_write_mem16!(
  2980. "ror16",
  2981. instr16_D1_1_mem_jit,
  2982. instr16_D1_1_reg_jit,
  2983. constant_one
  2984. );
  2985. define_instruction_read_write_mem32!(
  2986. gen_ror32,
  2987. instr32_D1_1_mem_jit,
  2988. instr32_D1_1_reg_jit,
  2989. constant_one
  2990. );
  2991. define_instruction_read_write_mem16!(
  2992. "rcl16",
  2993. instr16_D1_2_mem_jit,
  2994. instr16_D1_2_reg_jit,
  2995. constant_one
  2996. );
  2997. define_instruction_read_write_mem32!(
  2998. gen_rcl32,
  2999. instr32_D1_2_mem_jit,
  3000. instr32_D1_2_reg_jit,
  3001. constant_one
  3002. );
  3003. define_instruction_read_write_mem16!(
  3004. "rcr16",
  3005. instr16_D1_3_mem_jit,
  3006. instr16_D1_3_reg_jit,
  3007. constant_one
  3008. );
  3009. define_instruction_read_write_mem32!(
  3010. gen_rcr32,
  3011. instr32_D1_3_mem_jit,
  3012. instr32_D1_3_reg_jit,
  3013. constant_one
  3014. );
  3015. define_instruction_read_write_mem16!(
  3016. "shl16",
  3017. instr16_D1_4_mem_jit,
  3018. instr16_D1_4_reg_jit,
  3019. constant_one
  3020. );
  3021. define_instruction_read_write_mem32!(
  3022. gen_shl32,
  3023. instr32_D1_4_mem_jit,
  3024. instr32_D1_4_reg_jit,
  3025. constant_one
  3026. );
  3027. define_instruction_read_write_mem16!(
  3028. "shr16",
  3029. instr16_D1_5_mem_jit,
  3030. instr16_D1_5_reg_jit,
  3031. constant_one
  3032. );
  3033. define_instruction_read_write_mem32!(
  3034. gen_shr32,
  3035. instr32_D1_5_mem_jit,
  3036. instr32_D1_5_reg_jit,
  3037. constant_one
  3038. );
  3039. define_instruction_read_write_mem16!(
  3040. "shl16",
  3041. instr16_D1_6_mem_jit,
  3042. instr16_D1_6_reg_jit,
  3043. constant_one
  3044. );
  3045. define_instruction_read_write_mem32!(
  3046. gen_shl32,
  3047. instr32_D1_6_mem_jit,
  3048. instr32_D1_6_reg_jit,
  3049. constant_one
  3050. );
  3051. define_instruction_read_write_mem16!(
  3052. "sar16",
  3053. instr16_D1_7_mem_jit,
  3054. instr16_D1_7_reg_jit,
  3055. constant_one
  3056. );
  3057. define_instruction_read_write_mem32!(
  3058. gen_sar32,
  3059. instr32_D1_7_mem_jit,
  3060. instr32_D1_7_reg_jit,
  3061. constant_one
  3062. );
  3063. define_instruction_read_write_mem8!("rol8", instr_D2_0_mem_jit, instr_D2_0_reg_jit, cl);
  3064. define_instruction_read_write_mem8!("ror8", instr_D2_1_mem_jit, instr_D2_1_reg_jit, cl);
  3065. define_instruction_read_write_mem8!("rcl8", instr_D2_2_mem_jit, instr_D2_2_reg_jit, cl);
  3066. define_instruction_read_write_mem8!("rcr8", instr_D2_3_mem_jit, instr_D2_3_reg_jit, cl);
  3067. define_instruction_read_write_mem8!("shl8", instr_D2_4_mem_jit, instr_D2_4_reg_jit, cl);
  3068. define_instruction_read_write_mem8!("shr8", instr_D2_5_mem_jit, instr_D2_5_reg_jit, cl);
  3069. define_instruction_read_write_mem8!("shl8", instr_D2_6_mem_jit, instr_D2_6_reg_jit, cl);
  3070. define_instruction_read_write_mem8!("sar8", instr_D2_7_mem_jit, instr_D2_7_reg_jit, cl);
  3071. define_instruction_read_write_mem16!("rol16", instr16_D3_0_mem_jit, instr16_D3_0_reg_jit, cl);
  3072. define_instruction_read_write_mem32!(gen_rol32, instr32_D3_0_mem_jit, instr32_D3_0_reg_jit, cl);
  3073. define_instruction_read_write_mem16!("ror16", instr16_D3_1_mem_jit, instr16_D3_1_reg_jit, cl);
  3074. define_instruction_read_write_mem32!(gen_ror32, instr32_D3_1_mem_jit, instr32_D3_1_reg_jit, cl);
  3075. define_instruction_read_write_mem16!("rcl16", instr16_D3_2_mem_jit, instr16_D3_2_reg_jit, cl);
  3076. define_instruction_read_write_mem32!(gen_rcl32, instr32_D3_2_mem_jit, instr32_D3_2_reg_jit, cl);
  3077. define_instruction_read_write_mem16!("rcr16", instr16_D3_3_mem_jit, instr16_D3_3_reg_jit, cl);
  3078. define_instruction_read_write_mem32!(gen_rcr32, instr32_D3_3_mem_jit, instr32_D3_3_reg_jit, cl);
  3079. define_instruction_read_write_mem16!("shl16", instr16_D3_4_mem_jit, instr16_D3_4_reg_jit, cl);
  3080. define_instruction_read_write_mem32!(gen_shl32, instr32_D3_4_mem_jit, instr32_D3_4_reg_jit, cl);
  3081. define_instruction_read_write_mem16!("shr16", instr16_D3_5_mem_jit, instr16_D3_5_reg_jit, cl);
  3082. define_instruction_read_write_mem32!(gen_shr32, instr32_D3_5_mem_jit, instr32_D3_5_reg_jit, cl);
  3083. define_instruction_read_write_mem16!("shl16", instr16_D3_6_mem_jit, instr16_D3_6_reg_jit, cl);
  3084. define_instruction_read_write_mem32!(gen_shl32, instr32_D3_6_mem_jit, instr32_D3_6_reg_jit, cl);
  3085. define_instruction_read_write_mem16!("sar16", instr16_D3_7_mem_jit, instr16_D3_7_reg_jit, cl);
  3086. define_instruction_read_write_mem32!(gen_sar32, instr32_D3_7_mem_jit, instr32_D3_7_reg_jit, cl);
  3087. pub fn instr_D7_jit(ctx: &mut JitContext) {
  3088. if ctx.cpu.asize_32() {
  3089. codegen::gen_get_reg32(ctx, regs::EBX);
  3090. }
  3091. else {
  3092. codegen::gen_get_reg16(ctx, regs::BX);
  3093. }
  3094. codegen::gen_get_reg8(ctx, regs::AL);
  3095. ctx.builder.add_i32();
  3096. if !ctx.cpu.asize_32() {
  3097. ctx.builder.const_i32(0xFFFF);
  3098. ctx.builder.and_i32();
  3099. }
  3100. jit_add_seg_offset(ctx, regs::DS);
  3101. let address_local = ctx.builder.set_new_local();
  3102. codegen::gen_safe_read8(ctx, &address_local);
  3103. ctx.builder.free_local(address_local);
  3104. codegen::gen_set_reg8(ctx, regs::AL);
  3105. }
  3106. fn instr_group_D8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) {
  3107. ctx.builder.const_i32(0);
  3108. codegen::gen_fpu_load_m32(ctx, modrm_byte);
  3109. ctx.builder.call_fn3_i32_i64_i32(op)
  3110. }
  3111. fn instr_group_D8_reg_jit(ctx: &mut JitContext, r: u32, op: &str) {
  3112. ctx.builder.const_i32(0);
  3113. codegen::gen_fpu_get_sti(ctx, r);
  3114. ctx.builder.call_fn3_i32_i64_i32(op)
  3115. }
  3116. pub fn instr_D8_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3117. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fadd")
  3118. }
  3119. pub fn instr_D8_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3120. instr_group_D8_reg_jit(ctx, r, "fpu_fadd")
  3121. }
  3122. pub fn instr_D8_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3123. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fmul")
  3124. }
  3125. pub fn instr_D8_1_reg_jit(ctx: &mut JitContext, r: u32) {
  3126. instr_group_D8_reg_jit(ctx, r, "fpu_fmul")
  3127. }
  3128. pub fn instr_D8_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3129. codegen::gen_fpu_load_m32(ctx, modrm_byte);
  3130. ctx.builder.call_fn2_i64_i32("fpu_fcom")
  3131. }
  3132. pub fn instr_D8_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3133. codegen::gen_fpu_get_sti(ctx, r);
  3134. ctx.builder.call_fn2_i64_i32("fpu_fcom")
  3135. }
  3136. pub fn instr_D8_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3137. codegen::gen_fpu_load_m32(ctx, modrm_byte);
  3138. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3139. }
  3140. pub fn instr_D8_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3141. codegen::gen_fpu_get_sti(ctx, r);
  3142. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3143. }
  3144. pub fn instr_D8_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3145. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fsub")
  3146. }
  3147. pub fn instr_D8_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3148. instr_group_D8_reg_jit(ctx, r, "fpu_fsub")
  3149. }
  3150. pub fn instr_D8_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3151. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fsubr")
  3152. }
  3153. pub fn instr_D8_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3154. instr_group_D8_reg_jit(ctx, r, "fpu_fsubr")
  3155. }
  3156. pub fn instr_D8_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3157. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fdiv")
  3158. }
  3159. pub fn instr_D8_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3160. instr_group_D8_reg_jit(ctx, r, "fpu_fdiv")
  3161. }
  3162. pub fn instr_D8_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3163. instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fdivr")
  3164. }
  3165. pub fn instr_D8_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3166. instr_group_D8_reg_jit(ctx, r, "fpu_fdivr")
  3167. }
  3168. pub fn instr16_D9_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3169. codegen::gen_fpu_load_m32(ctx, modrm_byte);
  3170. ctx.builder.call_fn2_i64_i32("fpu_push");
  3171. }
  3172. pub fn instr16_D9_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3173. codegen::gen_fpu_get_sti(ctx, r);
  3174. ctx.builder.call_fn2_i64_i32("fpu_push");
  3175. }
  3176. pub fn instr32_D9_0_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_0_reg_jit(ctx, r) }
  3177. pub fn instr32_D9_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3178. instr16_D9_0_mem_jit(ctx, modrm_byte)
  3179. }
  3180. pub fn instr16_D9_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3181. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3182. codegen::gen_trigger_ud(ctx);
  3183. }
  3184. pub fn instr16_D9_1_reg_jit(ctx: &mut JitContext, r: u32) {
  3185. ctx.builder.const_i32(r as i32);
  3186. ctx.builder.call_fn1("fpu_fxch");
  3187. }
  3188. pub fn instr32_D9_1_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_1_reg_jit(ctx, r) }
  3189. pub fn instr32_D9_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3190. instr16_D9_1_mem_jit(ctx, modrm_byte)
  3191. }
  3192. pub fn instr16_D9_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3193. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3194. let address_local = ctx.builder.set_new_local();
  3195. codegen::gen_fpu_get_sti(ctx, 0);
  3196. ctx.builder.call_fn2_i64_i32_ret("f80_to_f32");
  3197. let value_local = ctx.builder.set_new_local();
  3198. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  3199. ctx.builder.free_local(address_local);
  3200. ctx.builder.free_local(value_local);
  3201. }
  3202. pub fn instr16_D9_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3203. if r != 0 {
  3204. codegen::gen_trigger_ud(ctx);
  3205. }
  3206. }
  3207. pub fn instr32_D9_2_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_2_reg_jit(ctx, r) }
  3208. pub fn instr32_D9_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3209. instr16_D9_2_mem_jit(ctx, modrm_byte)
  3210. }
  3211. pub fn instr16_D9_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3212. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3213. let address_local = ctx.builder.set_new_local();
  3214. codegen::gen_fpu_get_sti(ctx, 0);
  3215. ctx.builder.call_fn2_i64_i32_ret("f80_to_f32");
  3216. let value_local = ctx.builder.set_new_local();
  3217. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  3218. ctx.builder.free_local(address_local);
  3219. ctx.builder.free_local(value_local);
  3220. codegen::gen_fn0_const(ctx.builder, "fpu_pop");
  3221. }
  3222. pub fn instr16_D9_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3223. codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
  3224. }
  3225. pub fn instr32_D9_3_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_3_reg_jit(ctx, r) }
  3226. pub fn instr32_D9_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3227. instr16_D9_3_mem_jit(ctx, modrm_byte)
  3228. }
  3229. pub fn instr16_D9_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3230. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3231. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  3232. ctx.builder,
  3233. ctx.start_of_current_instruction as i32 & 0xFFF,
  3234. );
  3235. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3236. ctx.builder.call_fn1("fpu_fldenv32");
  3237. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3238. codegen::gen_get_page_fault(ctx.builder);
  3239. ctx.builder.if_void();
  3240. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  3241. ctx.builder.br(ctx.exit_label);
  3242. ctx.builder.block_end();
  3243. }
  3244. pub fn instr16_D9_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3245. match r {
  3246. 0 | 1 | 4 | 5 => {
  3247. ctx.builder.const_i32(r as i32);
  3248. ctx.builder.call_fn1("instr16_D9_4_reg");
  3249. },
  3250. _ => codegen::gen_trigger_ud(ctx),
  3251. }
  3252. }
  3253. pub fn instr32_D9_4_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_4_reg_jit(ctx, r) }
  3254. pub fn instr32_D9_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3255. instr16_D9_4_mem_jit(ctx, modrm_byte)
  3256. }
  3257. pub fn instr16_D9_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3258. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3259. ctx.builder.call_fn1("set_control_word");
  3260. }
  3261. pub fn instr16_D9_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3262. if r == 7 {
  3263. codegen::gen_trigger_ud(ctx);
  3264. }
  3265. else {
  3266. codegen::gen_fn1_const(ctx.builder, "instr16_D9_5_reg", r);
  3267. }
  3268. }
  3269. pub fn instr32_D9_5_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_5_reg_jit(ctx, r) }
  3270. pub fn instr32_D9_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3271. instr16_D9_5_mem_jit(ctx, modrm_byte)
  3272. }
  3273. pub fn instr16_D9_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3274. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3275. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  3276. ctx.builder,
  3277. ctx.start_of_current_instruction as i32 & 0xFFF,
  3278. );
  3279. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3280. ctx.builder.call_fn1("fpu_fstenv32");
  3281. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3282. codegen::gen_get_page_fault(ctx.builder);
  3283. ctx.builder.if_void();
  3284. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  3285. ctx.builder.br(ctx.exit_label);
  3286. ctx.builder.block_end();
  3287. }
  3288. pub fn instr16_D9_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3289. codegen::gen_fn1_const(ctx.builder, "instr16_D9_6_reg", r);
  3290. }
  3291. pub fn instr32_D9_6_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_6_reg_jit(ctx, r) }
  3292. pub fn instr32_D9_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3293. instr16_D9_6_mem_jit(ctx, modrm_byte)
  3294. }
  3295. pub fn instr16_D9_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3296. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3297. let address_local = ctx.builder.set_new_local();
  3298. ctx.builder
  3299. .const_i32(global_pointers::fpu_control_word as i32);
  3300. ctx.builder.load_aligned_u16(0);
  3301. let value_local = ctx.builder.set_new_local();
  3302. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  3303. ctx.builder.free_local(address_local);
  3304. ctx.builder.free_local(value_local);
  3305. }
  3306. pub fn instr16_D9_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3307. codegen::gen_fn1_const(ctx.builder, "instr16_D9_7_reg", r);
  3308. }
  3309. pub fn instr32_D9_7_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_7_reg_jit(ctx, r) }
  3310. pub fn instr32_D9_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3311. instr16_D9_7_mem_jit(ctx, modrm_byte)
  3312. }
  3313. pub fn instr_DA_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3314. codegen::gen_fn1_const(ctx.builder, "instr_DA_0_reg", r);
  3315. }
  3316. pub fn instr_DA_1_reg_jit(ctx: &mut JitContext, r: u32) {
  3317. codegen::gen_fn1_const(ctx.builder, "instr_DA_1_reg", r);
  3318. }
  3319. pub fn instr_DA_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3320. codegen::gen_fn1_const(ctx.builder, "instr_DA_2_reg", r);
  3321. }
  3322. pub fn instr_DA_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3323. codegen::gen_fn1_const(ctx.builder, "instr_DA_3_reg", r);
  3324. }
  3325. pub fn instr_DA_4_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx) }
  3326. pub fn instr_DA_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3327. if r == 1 {
  3328. codegen::gen_fn0_const(ctx.builder, "fpu_fucompp")
  3329. }
  3330. else {
  3331. codegen::gen_trigger_ud(ctx)
  3332. }
  3333. }
  3334. pub fn instr_DA_6_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx) }
  3335. pub fn instr_DA_7_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx) }
  3336. pub fn instr_group_DA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) {
  3337. ctx.builder.const_i32(0);
  3338. codegen::gen_fpu_load_i32(ctx, modrm_byte);
  3339. ctx.builder.call_fn3_i32_i64_i32(op)
  3340. }
  3341. pub fn instr_DA_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3342. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fadd")
  3343. }
  3344. pub fn instr_DA_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3345. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fmul")
  3346. }
  3347. pub fn instr_DA_2_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_fcom")
  3350. }
  3351. pub fn instr_DA_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3352. codegen::gen_fpu_load_i32(ctx, modrm_byte);
  3353. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3354. }
  3355. pub fn instr_DA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3356. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fsub")
  3357. }
  3358. pub fn instr_DA_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3359. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fsubr")
  3360. }
  3361. pub fn instr_DA_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3362. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fdiv")
  3363. }
  3364. pub fn instr_DA_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3365. instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fdivr")
  3366. }
  3367. pub fn instr_DB_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3368. codegen::gen_fpu_load_i32(ctx, modrm_byte);
  3369. ctx.builder.call_fn2_i64_i32("fpu_push");
  3370. }
  3371. pub fn instr_DB_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3372. codegen::gen_fn1_const(ctx.builder, "instr_DB_0_reg", r);
  3373. }
  3374. pub fn instr_DB_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3375. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3376. let address_local = ctx.builder.set_new_local();
  3377. codegen::gen_fpu_get_sti(ctx, 0);
  3378. ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i32");
  3379. let value_local = ctx.builder.set_new_local();
  3380. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  3381. ctx.builder.free_local(address_local);
  3382. ctx.builder.free_local(value_local);
  3383. }
  3384. pub fn instr_DB_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3385. codegen::gen_fn1_const(ctx.builder, "instr_DB_2_reg", r);
  3386. }
  3387. pub fn instr_DB_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3388. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3389. let address_local = ctx.builder.set_new_local();
  3390. codegen::gen_fpu_get_sti(ctx, 0);
  3391. ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i32");
  3392. let value_local = ctx.builder.set_new_local();
  3393. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  3394. ctx.builder.free_local(address_local);
  3395. ctx.builder.free_local(value_local);
  3396. codegen::gen_fn0_const(ctx.builder, "fpu_pop");
  3397. }
  3398. pub fn instr_DB_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3399. codegen::gen_fn1_const(ctx.builder, "instr_DB_3_reg", r);
  3400. }
  3401. pub fn instr_DB_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3402. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3403. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  3404. ctx.builder,
  3405. ctx.start_of_current_instruction as i32 & 0xFFF,
  3406. );
  3407. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3408. ctx.builder.call_fn1("fpu_fldm80");
  3409. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3410. codegen::gen_get_page_fault(ctx.builder);
  3411. ctx.builder.if_void();
  3412. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  3413. ctx.builder.br(ctx.exit_label);
  3414. ctx.builder.block_end();
  3415. }
  3416. pub fn instr_DB_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3417. ctx.builder.const_i32(r as i32);
  3418. ctx.builder.call_fn1("fpu_fucomi");
  3419. }
  3420. pub fn instr_DB_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte) {
  3421. codegen::gen_trigger_ud(ctx);
  3422. }
  3423. pub fn instr_DB_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3424. ctx.builder.const_i32(r as i32);
  3425. ctx.builder.call_fn1("fpu_fcomi");
  3426. }
  3427. fn instr_group_DC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) {
  3428. ctx.builder.const_i32(0);
  3429. codegen::gen_fpu_load_m64(ctx, modrm_byte);
  3430. ctx.builder.call_fn3_i32_i64_i32(op)
  3431. }
  3432. fn instr_group_DC_reg_jit(ctx: &mut JitContext, r: u32, op: &str) {
  3433. ctx.builder.const_i32(r as i32);
  3434. codegen::gen_fpu_get_sti(ctx, r);
  3435. ctx.builder.call_fn3_i32_i64_i32(op)
  3436. }
  3437. pub fn instr_DC_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3438. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fadd")
  3439. }
  3440. pub fn instr_DC_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3441. instr_group_DC_reg_jit(ctx, r, "fpu_fadd")
  3442. }
  3443. pub fn instr_DC_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3444. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fmul")
  3445. }
  3446. pub fn instr_DC_1_reg_jit(ctx: &mut JitContext, r: u32) {
  3447. instr_group_DC_reg_jit(ctx, r, "fpu_fmul")
  3448. }
  3449. pub fn instr_DC_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3450. codegen::gen_fpu_load_m64(ctx, modrm_byte);
  3451. ctx.builder.call_fn2_i64_i32("fpu_fcom")
  3452. }
  3453. pub fn instr_DC_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3454. codegen::gen_fpu_get_sti(ctx, r);
  3455. ctx.builder.call_fn2_i64_i32("fpu_fcom")
  3456. }
  3457. pub fn instr_DC_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3458. codegen::gen_fpu_load_m64(ctx, modrm_byte);
  3459. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3460. }
  3461. pub fn instr_DC_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3462. codegen::gen_fpu_get_sti(ctx, r);
  3463. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3464. }
  3465. pub fn instr_DC_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3466. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fsub")
  3467. }
  3468. pub fn instr_DC_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3469. instr_group_DC_reg_jit(ctx, r, "fpu_fsub")
  3470. }
  3471. pub fn instr_DC_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3472. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fsubr")
  3473. }
  3474. pub fn instr_DC_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3475. instr_group_DC_reg_jit(ctx, r, "fpu_fsubr")
  3476. }
  3477. pub fn instr_DC_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3478. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fdiv")
  3479. }
  3480. pub fn instr_DC_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3481. instr_group_DC_reg_jit(ctx, r, "fpu_fdiv")
  3482. }
  3483. pub fn instr_DC_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3484. instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fdivr")
  3485. }
  3486. pub fn instr_DC_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3487. instr_group_DC_reg_jit(ctx, r, "fpu_fdivr")
  3488. }
  3489. pub fn instr16_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3490. codegen::gen_fpu_load_m64(ctx, modrm_byte);
  3491. ctx.builder.call_fn2_i64_i32("fpu_push");
  3492. }
  3493. pub fn instr16_DD_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3494. codegen::gen_fn1_const(ctx.builder, "fpu_ffree", r);
  3495. }
  3496. pub fn instr32_DD_0_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_0_reg_jit(ctx, r) }
  3497. pub fn instr32_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3498. instr16_DD_0_mem_jit(ctx, modrm_byte)
  3499. }
  3500. pub fn instr16_DD_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3501. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3502. let address_local = ctx.builder.set_new_local();
  3503. codegen::gen_fpu_get_sti(ctx, 0);
  3504. ctx.builder.call_fn2_i64_i32_ret_i64("f80_to_f64");
  3505. let value_local = ctx.builder.set_new_local_i64();
  3506. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  3507. ctx.builder.free_local(address_local);
  3508. ctx.builder.free_local_i64(value_local);
  3509. }
  3510. pub fn instr16_DD_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3511. codegen::gen_fn1_const(ctx.builder, "fpu_fst", r);
  3512. }
  3513. pub fn instr32_DD_2_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_2_reg_jit(ctx, r) }
  3514. pub fn instr32_DD_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3515. instr16_DD_2_mem_jit(ctx, modrm_byte)
  3516. }
  3517. pub fn instr16_DD_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3518. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3519. let address_local = ctx.builder.set_new_local();
  3520. codegen::gen_fpu_get_sti(ctx, 0);
  3521. ctx.builder.call_fn2_i64_i32_ret_i64("f80_to_f64");
  3522. let value_local = ctx.builder.set_new_local_i64();
  3523. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  3524. codegen::gen_fn0_const(ctx.builder, "fpu_pop");
  3525. ctx.builder.free_local(address_local);
  3526. ctx.builder.free_local_i64(value_local);
  3527. }
  3528. pub fn instr16_DD_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3529. codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
  3530. }
  3531. pub fn instr32_DD_3_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_3_reg_jit(ctx, r) }
  3532. pub fn instr32_DD_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3533. instr16_DD_3_mem_jit(ctx, modrm_byte)
  3534. }
  3535. pub fn instr16_DD_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3536. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3537. codegen::gen_trigger_ud(ctx);
  3538. }
  3539. pub fn instr16_DD_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3540. ctx.builder.const_i32(r as i32);
  3541. ctx.builder.call_fn1("fpu_fucomp");
  3542. }
  3543. pub fn instr32_DD_5_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_5_reg_jit(ctx, r) }
  3544. pub fn instr32_DD_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3545. instr16_DD_5_mem_jit(ctx, modrm_byte)
  3546. }
  3547. fn instr_group_DE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) {
  3548. ctx.builder.const_i32(0);
  3549. codegen::gen_fpu_load_i16(ctx, modrm_byte);
  3550. ctx.builder.call_fn3_i32_i64_i32(op)
  3551. }
  3552. fn instr_group_DE_reg_jit(ctx: &mut JitContext, r: u32, op: &str) {
  3553. ctx.builder.const_i32(r as i32);
  3554. codegen::gen_fpu_get_sti(ctx, r);
  3555. ctx.builder.call_fn3_i32_i64_i32(op);
  3556. codegen::gen_fn0_const(ctx.builder, "fpu_pop")
  3557. }
  3558. pub fn instr_DE_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3559. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fadd")
  3560. }
  3561. pub fn instr_DE_0_reg_jit(ctx: &mut JitContext, r: u32) {
  3562. instr_group_DE_reg_jit(ctx, r, "fpu_fadd")
  3563. }
  3564. pub fn instr_DE_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3565. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fmul")
  3566. }
  3567. pub fn instr_DE_1_reg_jit(ctx: &mut JitContext, r: u32) {
  3568. instr_group_DE_reg_jit(ctx, r, "fpu_fmul")
  3569. }
  3570. pub fn instr_DE_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3571. codegen::gen_fpu_load_i16(ctx, modrm_byte);
  3572. ctx.builder.call_fn2_i64_i32("fpu_fcom")
  3573. }
  3574. pub fn instr_DE_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3575. codegen::gen_fpu_get_sti(ctx, r);
  3576. ctx.builder.call_fn2_i64_i32("fpu_fcom");
  3577. codegen::gen_fn0_const(ctx.builder, "fpu_pop")
  3578. }
  3579. pub fn instr_DE_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3580. codegen::gen_fpu_load_i16(ctx, modrm_byte);
  3581. ctx.builder.call_fn2_i64_i32("fpu_fcomp")
  3582. }
  3583. pub fn instr_DE_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3584. if r == 1 {
  3585. codegen::gen_fpu_get_sti(ctx, r);
  3586. ctx.builder.call_fn2_i64_i32("fpu_fcomp");
  3587. codegen::gen_fn0_const(ctx.builder, "fpu_pop")
  3588. }
  3589. else {
  3590. codegen::gen_trigger_ud(ctx);
  3591. }
  3592. }
  3593. pub fn instr_DE_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3594. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fsub")
  3595. }
  3596. pub fn instr_DE_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3597. instr_group_DE_reg_jit(ctx, r, "fpu_fsub")
  3598. }
  3599. pub fn instr_DE_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3600. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fsubr")
  3601. }
  3602. pub fn instr_DE_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3603. instr_group_DE_reg_jit(ctx, r, "fpu_fsubr")
  3604. }
  3605. pub fn instr_DE_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3606. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fdiv")
  3607. }
  3608. pub fn instr_DE_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3609. instr_group_DE_reg_jit(ctx, r, "fpu_fdiv")
  3610. }
  3611. pub fn instr_DE_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3612. instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fdivr")
  3613. }
  3614. pub fn instr_DE_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3615. instr_group_DE_reg_jit(ctx, r, "fpu_fdivr")
  3616. }
  3617. pub fn instr_DF_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3618. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3619. let address_local = ctx.builder.set_new_local();
  3620. codegen::gen_fpu_get_sti(ctx, 0);
  3621. ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i16");
  3622. let value_local = ctx.builder.set_new_local();
  3623. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  3624. ctx.builder.free_local(address_local);
  3625. ctx.builder.free_local(value_local);
  3626. }
  3627. pub fn instr_DF_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3628. codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
  3629. }
  3630. pub fn instr_DF_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3631. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3632. let address_local = ctx.builder.set_new_local();
  3633. codegen::gen_fpu_get_sti(ctx, 0);
  3634. ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i16");
  3635. let value_local = ctx.builder.set_new_local();
  3636. codegen::gen_safe_write16(ctx, &address_local, &value_local);
  3637. ctx.builder.free_local(address_local);
  3638. ctx.builder.free_local(value_local);
  3639. codegen::gen_fn0_const(ctx.builder, "fpu_pop");
  3640. }
  3641. pub fn instr_DF_3_reg_jit(ctx: &mut JitContext, r: u32) {
  3642. codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
  3643. }
  3644. pub fn instr_DF_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3645. dbg_log!("fbld");
  3646. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3647. codegen::gen_trigger_ud(ctx);
  3648. }
  3649. pub fn instr_DF_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3650. if r == 0 {
  3651. ctx.builder.call_fn0_ret("fpu_load_status_word");
  3652. codegen::gen_set_reg16(ctx, regs::AX);
  3653. }
  3654. else {
  3655. codegen::gen_trigger_ud(ctx);
  3656. };
  3657. }
  3658. pub fn instr_DF_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3659. codegen::gen_fpu_load_i64(ctx, modrm_byte);
  3660. ctx.builder.call_fn2_i64_i32("fpu_push");
  3661. }
  3662. pub fn instr_DF_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3663. codegen::gen_fn1_const(ctx.builder, "fpu_fucomip", r);
  3664. }
  3665. pub fn instr_DF_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3666. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3667. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  3668. ctx.builder,
  3669. ctx.start_of_current_instruction as i32 & 0xFFF,
  3670. );
  3671. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3672. ctx.builder.call_fn1("fpu_fbstp");
  3673. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3674. codegen::gen_get_page_fault(ctx.builder);
  3675. ctx.builder.if_void();
  3676. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  3677. ctx.builder.br(ctx.exit_label);
  3678. ctx.builder.block_end();
  3679. }
  3680. pub fn instr_DF_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3681. ctx.builder.const_i32(r as i32);
  3682. ctx.builder.call_fn1("fpu_fcomip");
  3683. }
  3684. pub fn instr_DF_7_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx); }
  3685. pub fn instr_DF_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3686. codegen::gen_modrm_resolve(ctx, modrm_byte);
  3687. let address_local = ctx.builder.set_new_local();
  3688. codegen::gen_fpu_get_sti(ctx, 0);
  3689. ctx.builder.call_fn2_i64_i32_ret_i64("fpu_convert_to_i64");
  3690. let value_local = ctx.builder.set_new_local_i64();
  3691. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  3692. ctx.builder.free_local(address_local);
  3693. ctx.builder.free_local_i64(value_local);
  3694. codegen::gen_fn0_const(ctx.builder, "fpu_pop");
  3695. }
  3696. pub fn instr16_EB_jit(_ctx: &mut JitContext, _imm8: u32) {
  3697. //
  3698. }
  3699. pub fn instr32_EB_jit(_ctx: &mut JitContext, _imm8: u32) {
  3700. // jmp near
  3701. }
  3702. define_instruction_read8!(gen_test8, instr_F6_0_mem_jit, instr_F6_0_reg_jit, imm8);
  3703. define_instruction_read16!(
  3704. gen_test16,
  3705. instr16_F7_0_mem_jit,
  3706. instr16_F7_0_reg_jit,
  3707. imm16
  3708. );
  3709. define_instruction_read32!(
  3710. gen_test32,
  3711. instr32_F7_0_mem_jit,
  3712. instr32_F7_0_reg_jit,
  3713. imm32
  3714. );
  3715. pub fn instr_F6_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  3716. instr_F6_0_mem_jit(ctx, modrm_byte, imm)
  3717. }
  3718. pub fn instr_F6_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  3719. instr_F6_0_reg_jit(ctx, r, imm)
  3720. }
  3721. pub fn instr16_F7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  3722. instr16_F7_0_mem_jit(ctx, modrm_byte, imm)
  3723. }
  3724. pub fn instr16_F7_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  3725. instr16_F7_0_reg_jit(ctx, r, imm)
  3726. }
  3727. pub fn instr32_F7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  3728. instr32_F7_0_mem_jit(ctx, modrm_byte, imm)
  3729. }
  3730. pub fn instr32_F7_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  3731. instr32_F7_0_reg_jit(ctx, r, imm)
  3732. }
  3733. define_instruction_read_write_mem8!("not8", instr_F6_2_mem_jit, instr_F6_2_reg_jit, none);
  3734. define_instruction_read_write_mem8!("neg8", instr_F6_3_mem_jit, instr_F6_3_reg_jit, none);
  3735. define_instruction_read_write_mem16!(gen_not16, instr16_F7_2_mem_jit, instr16_F7_2_reg_jit, none);
  3736. define_instruction_read_write_mem32!(gen_not32, instr32_F7_2_mem_jit, instr32_F7_2_reg_jit, none);
  3737. define_instruction_read_write_mem16!(gen_neg16, instr16_F7_3_mem_jit, instr16_F7_3_reg_jit, none);
  3738. define_instruction_read_write_mem32!(gen_neg32, instr32_F7_3_mem_jit, instr32_F7_3_reg_jit, none);
  3739. pub fn instr16_F7_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3740. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3741. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3742. ctx.builder.call_fn1("mul16");
  3743. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3744. }
  3745. pub fn instr16_F7_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3746. codegen::gen_get_reg16(ctx, r);
  3747. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3748. ctx.builder.call_fn1("mul16");
  3749. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3750. }
  3751. pub fn instr32_F7_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3752. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3753. gen_mul32(ctx);
  3754. }
  3755. pub fn instr32_F7_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3756. codegen::gen_get_reg32(ctx, r);
  3757. gen_mul32(ctx);
  3758. }
  3759. pub fn instr16_F7_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3760. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3761. codegen::sign_extend_i16(ctx.builder);
  3762. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3763. ctx.builder.call_fn1("imul16");
  3764. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3765. }
  3766. pub fn instr16_F7_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3767. codegen::gen_get_reg16(ctx, r);
  3768. codegen::sign_extend_i16(ctx.builder);
  3769. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3770. ctx.builder.call_fn1("imul16");
  3771. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3772. }
  3773. pub fn instr32_F7_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3774. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3775. gen_imul32(ctx);
  3776. }
  3777. pub fn instr32_F7_5_reg_jit(ctx: &mut JitContext, r: u32) {
  3778. codegen::gen_get_reg32(ctx, r);
  3779. gen_imul32(ctx);
  3780. }
  3781. pub fn instr16_F7_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3782. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3783. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3784. ctx.builder.call_fn1_ret("div16_without_fault");
  3785. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3786. ctx.builder.eqz_i32();
  3787. ctx.builder.if_void();
  3788. codegen::gen_trigger_de(ctx);
  3789. ctx.builder.block_end();
  3790. }
  3791. pub fn instr16_F7_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3792. codegen::gen_get_reg16(ctx, r);
  3793. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3794. ctx.builder.call_fn1_ret("div16_without_fault");
  3795. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3796. ctx.builder.eqz_i32();
  3797. ctx.builder.if_void();
  3798. codegen::gen_trigger_de(ctx);
  3799. ctx.builder.block_end();
  3800. }
  3801. pub fn instr32_F7_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3802. if false {
  3803. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3804. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3805. ctx.builder.call_fn1_ret("div32_without_fault");
  3806. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3807. ctx.builder.eqz_i32();
  3808. ctx.builder.if_void();
  3809. codegen::gen_trigger_de(ctx);
  3810. ctx.builder.block_end();
  3811. }
  3812. else {
  3813. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3814. let source_operand = ctx.builder.set_new_local();
  3815. gen_div32(ctx, &source_operand);
  3816. ctx.builder.free_local(source_operand);
  3817. }
  3818. }
  3819. pub fn instr32_F7_6_reg_jit(ctx: &mut JitContext, r: u32) {
  3820. if false {
  3821. codegen::gen_get_reg32(ctx, r);
  3822. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3823. ctx.builder.call_fn1_ret("div32_without_fault");
  3824. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3825. ctx.builder.eqz_i32();
  3826. ctx.builder.if_void();
  3827. codegen::gen_trigger_de(ctx);
  3828. ctx.builder.block_end();
  3829. }
  3830. else {
  3831. gen_div32(ctx, &ctx.reg(r));
  3832. }
  3833. }
  3834. pub fn instr16_F7_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3835. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3836. codegen::sign_extend_i16(ctx.builder);
  3837. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3838. ctx.builder.call_fn1_ret("idiv16_without_fault");
  3839. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3840. ctx.builder.eqz_i32();
  3841. ctx.builder.if_void();
  3842. codegen::gen_trigger_de(ctx);
  3843. ctx.builder.block_end();
  3844. }
  3845. pub fn instr16_F7_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3846. codegen::gen_get_reg16(ctx, r);
  3847. codegen::sign_extend_i16(ctx.builder);
  3848. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3849. ctx.builder.call_fn1_ret("idiv16_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 instr32_F7_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3857. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3858. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3859. ctx.builder.call_fn1_ret("idiv32_without_fault");
  3860. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3861. ctx.builder.eqz_i32();
  3862. ctx.builder.if_void();
  3863. codegen::gen_trigger_de(ctx);
  3864. ctx.builder.block_end();
  3865. }
  3866. pub fn instr32_F7_7_reg_jit(ctx: &mut JitContext, r: u32) {
  3867. codegen::gen_get_reg32(ctx, r);
  3868. codegen::gen_move_registers_from_locals_to_memory(ctx);
  3869. ctx.builder.call_fn1_ret("idiv32_without_fault");
  3870. codegen::gen_move_registers_from_memory_to_locals(ctx);
  3871. ctx.builder.eqz_i32();
  3872. ctx.builder.if_void();
  3873. codegen::gen_trigger_de(ctx);
  3874. ctx.builder.block_end();
  3875. }
  3876. pub fn instr_F8_jit(ctx: &mut JitContext) {
  3877. codegen::gen_clear_flags_changed_bits(ctx.builder, 1);
  3878. codegen::gen_clear_flags_bits(ctx.builder, 1);
  3879. }
  3880. pub fn instr_F9_jit(ctx: &mut JitContext) {
  3881. codegen::gen_clear_flags_changed_bits(ctx.builder, 1);
  3882. codegen::gen_set_flags_bits(ctx.builder, 1);
  3883. }
  3884. pub fn instr_FA_jit(ctx: &mut JitContext) {
  3885. ctx.builder.call_fn0_ret("instr_FA_without_fault");
  3886. ctx.builder.eqz_i32();
  3887. ctx.builder.if_void();
  3888. codegen::gen_trigger_gp(ctx, 0);
  3889. ctx.builder.block_end();
  3890. }
  3891. pub fn instr_FB_jit(ctx: &mut JitContext) {
  3892. ctx.builder.call_fn0_ret("instr_FB_without_fault");
  3893. ctx.builder.eqz_i32();
  3894. ctx.builder.if_void();
  3895. codegen::gen_trigger_gp(ctx, 0);
  3896. ctx.builder.block_end();
  3897. // handle_irqs is specially handled in jit to be called one instruction after this one
  3898. }
  3899. pub fn instr_FC_jit(ctx: &mut JitContext) {
  3900. ctx.builder.const_i32(global_pointers::flags as i32);
  3901. codegen::gen_get_flags(ctx.builder);
  3902. ctx.builder.const_i32(!FLAG_DIRECTION);
  3903. ctx.builder.and_i32();
  3904. ctx.builder.store_aligned_i32(0);
  3905. }
  3906. pub fn instr_FD_jit(ctx: &mut JitContext) {
  3907. ctx.builder.const_i32(global_pointers::flags as i32);
  3908. codegen::gen_get_flags(ctx.builder);
  3909. ctx.builder.const_i32(FLAG_DIRECTION);
  3910. ctx.builder.or_i32();
  3911. ctx.builder.store_aligned_i32(0);
  3912. }
  3913. define_instruction_read_write_mem8!("inc8", instr_FE_0_mem_jit, instr_FE_0_reg_jit, none);
  3914. define_instruction_read_write_mem8!("dec8", instr_FE_1_mem_jit, instr_FE_1_reg_jit, none);
  3915. define_instruction_read_write_mem16!(gen_inc16, instr16_FF_0_mem_jit, instr16_FF_0_reg_jit, none);
  3916. define_instruction_read_write_mem32!(gen_inc32, instr32_FF_0_mem_jit, instr32_FF_0_reg_jit, none);
  3917. define_instruction_read_write_mem16!(gen_dec16, instr16_FF_1_mem_jit, instr16_FF_1_reg_jit, none);
  3918. define_instruction_read_write_mem32!(gen_dec32, instr32_FF_1_mem_jit, instr32_FF_1_reg_jit, none);
  3919. pub fn instr16_FF_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3920. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3921. codegen::gen_add_cs_offset(ctx);
  3922. let new_eip = ctx.builder.set_new_local();
  3923. codegen::gen_get_real_eip(ctx);
  3924. let value_local = ctx.builder.set_new_local();
  3925. codegen::gen_push16(ctx, &value_local);
  3926. ctx.builder.free_local(value_local);
  3927. ctx.builder.const_i32(0);
  3928. ctx.builder.get_local(&new_eip);
  3929. ctx.builder
  3930. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3931. ctx.builder.free_local(new_eip);
  3932. }
  3933. pub fn instr16_FF_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3934. codegen::gen_get_real_eip(ctx);
  3935. let value_local = ctx.builder.set_new_local();
  3936. codegen::gen_push16(ctx, &value_local);
  3937. ctx.builder.free_local(value_local);
  3938. ctx.builder.const_i32(0);
  3939. codegen::gen_get_reg16(ctx, r);
  3940. codegen::gen_add_cs_offset(ctx);
  3941. ctx.builder
  3942. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3943. }
  3944. pub fn instr32_FF_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3945. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3946. codegen::gen_add_cs_offset(ctx);
  3947. let new_eip = ctx.builder.set_new_local();
  3948. codegen::gen_get_real_eip(ctx);
  3949. let value_local = ctx.builder.set_new_local();
  3950. codegen::gen_push32(ctx, &value_local);
  3951. ctx.builder.free_local(value_local);
  3952. ctx.builder.const_i32(0);
  3953. ctx.builder.get_local(&new_eip);
  3954. ctx.builder
  3955. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3956. ctx.builder.free_local(new_eip);
  3957. }
  3958. pub fn instr32_FF_2_reg_jit(ctx: &mut JitContext, r: u32) {
  3959. codegen::gen_get_real_eip(ctx);
  3960. let value_local = ctx.builder.set_new_local();
  3961. codegen::gen_push32(ctx, &value_local);
  3962. ctx.builder.free_local(value_local);
  3963. ctx.builder.const_i32(0);
  3964. codegen::gen_get_reg32(ctx, r);
  3965. codegen::gen_add_cs_offset(ctx);
  3966. ctx.builder
  3967. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3968. }
  3969. pub fn instr16_FF_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3970. ctx.builder.const_i32(0);
  3971. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  3972. codegen::gen_add_cs_offset(ctx);
  3973. ctx.builder
  3974. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3975. }
  3976. pub fn instr16_FF_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3977. ctx.builder.const_i32(0);
  3978. codegen::gen_get_reg16(ctx, r);
  3979. codegen::gen_add_cs_offset(ctx);
  3980. ctx.builder
  3981. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3982. }
  3983. pub fn instr32_FF_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3984. ctx.builder.const_i32(0);
  3985. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  3986. codegen::gen_add_cs_offset(ctx);
  3987. ctx.builder
  3988. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3989. }
  3990. pub fn instr32_FF_4_reg_jit(ctx: &mut JitContext, r: u32) {
  3991. ctx.builder.const_i32(0);
  3992. codegen::gen_get_reg32(ctx, r);
  3993. codegen::gen_add_cs_offset(ctx);
  3994. ctx.builder
  3995. .store_aligned_i32(global_pointers::instruction_pointer as u32);
  3996. }
  3997. pub fn instr16_FF_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  3998. push16_mem_jit(ctx, modrm_byte)
  3999. }
  4000. pub fn instr16_FF_6_reg_jit(ctx: &mut JitContext, r: u32) { push16_reg_jit(ctx, r) }
  4001. pub fn instr32_FF_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  4002. push32_mem_jit(ctx, modrm_byte)
  4003. }
  4004. pub fn instr32_FF_6_reg_jit(ctx: &mut JitContext, r: u32) { push32_reg_jit(ctx, r) }
  4005. // Code for conditional jumps is generated automatically by the basic block codegen
  4006. pub fn instr16_0F80_jit(_ctx: &mut JitContext, _imm: u32) {}
  4007. pub fn instr16_0F81_jit(_ctx: &mut JitContext, _imm: u32) {}
  4008. pub fn instr16_0F82_jit(_ctx: &mut JitContext, _imm: u32) {}
  4009. pub fn instr16_0F83_jit(_ctx: &mut JitContext, _imm: u32) {}
  4010. pub fn instr16_0F84_jit(_ctx: &mut JitContext, _imm: u32) {}
  4011. pub fn instr16_0F85_jit(_ctx: &mut JitContext, _imm: u32) {}
  4012. pub fn instr16_0F86_jit(_ctx: &mut JitContext, _imm: u32) {}
  4013. pub fn instr16_0F87_jit(_ctx: &mut JitContext, _imm: u32) {}
  4014. pub fn instr16_0F88_jit(_ctx: &mut JitContext, _imm: u32) {}
  4015. pub fn instr16_0F89_jit(_ctx: &mut JitContext, _imm: u32) {}
  4016. pub fn instr16_0F8A_jit(_ctx: &mut JitContext, _imm: u32) {}
  4017. pub fn instr16_0F8B_jit(_ctx: &mut JitContext, _imm: u32) {}
  4018. pub fn instr16_0F8C_jit(_ctx: &mut JitContext, _imm: u32) {}
  4019. pub fn instr16_0F8D_jit(_ctx: &mut JitContext, _imm: u32) {}
  4020. pub fn instr16_0F8E_jit(_ctx: &mut JitContext, _imm: u32) {}
  4021. pub fn instr16_0F8F_jit(_ctx: &mut JitContext, _imm: u32) {}
  4022. pub fn instr32_0F80_jit(_ctx: &mut JitContext, _imm: u32) {}
  4023. pub fn instr32_0F81_jit(_ctx: &mut JitContext, _imm: u32) {}
  4024. pub fn instr32_0F82_jit(_ctx: &mut JitContext, _imm: u32) {}
  4025. pub fn instr32_0F83_jit(_ctx: &mut JitContext, _imm: u32) {}
  4026. pub fn instr32_0F84_jit(_ctx: &mut JitContext, _imm: u32) {}
  4027. pub fn instr32_0F85_jit(_ctx: &mut JitContext, _imm: u32) {}
  4028. pub fn instr32_0F86_jit(_ctx: &mut JitContext, _imm: u32) {}
  4029. pub fn instr32_0F87_jit(_ctx: &mut JitContext, _imm: u32) {}
  4030. pub fn instr32_0F88_jit(_ctx: &mut JitContext, _imm: u32) {}
  4031. pub fn instr32_0F89_jit(_ctx: &mut JitContext, _imm: u32) {}
  4032. pub fn instr32_0F8A_jit(_ctx: &mut JitContext, _imm: u32) {}
  4033. pub fn instr32_0F8B_jit(_ctx: &mut JitContext, _imm: u32) {}
  4034. pub fn instr32_0F8C_jit(_ctx: &mut JitContext, _imm: u32) {}
  4035. pub fn instr32_0F8D_jit(_ctx: &mut JitContext, _imm: u32) {}
  4036. pub fn instr32_0F8E_jit(_ctx: &mut JitContext, _imm: u32) {}
  4037. pub fn instr32_0F8F_jit(_ctx: &mut JitContext, _imm: u32) {}
  4038. pub fn instr_90_jit(_ctx: &mut JitContext) {}
  4039. fn gen_xchg_reg16(ctx: &mut JitContext, r: u32) {
  4040. codegen::gen_get_reg16(ctx, r);
  4041. let tmp = ctx.builder.set_new_local();
  4042. codegen::gen_get_reg16(ctx, regs::AX);
  4043. codegen::gen_set_reg16(ctx, r);
  4044. ctx.builder.get_local(&tmp);
  4045. codegen::gen_set_reg16(ctx, regs::AX);
  4046. ctx.builder.free_local(tmp);
  4047. }
  4048. fn gen_xchg_reg32(ctx: &mut JitContext, r: u32) {
  4049. codegen::gen_get_reg32(ctx, r);
  4050. let tmp = ctx.builder.set_new_local();
  4051. codegen::gen_get_reg32(ctx, regs::EAX);
  4052. codegen::gen_set_reg32(ctx, r);
  4053. ctx.builder.get_local(&tmp);
  4054. codegen::gen_set_reg32(ctx, regs::EAX);
  4055. ctx.builder.free_local(tmp);
  4056. }
  4057. pub fn instr16_91_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::CX); }
  4058. pub fn instr16_92_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::DX); }
  4059. pub fn instr16_93_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::BX); }
  4060. pub fn instr16_94_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::SP); }
  4061. pub fn instr16_95_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::BP); }
  4062. pub fn instr16_96_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::SI); }
  4063. pub fn instr16_97_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::DI); }
  4064. pub fn instr32_91_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::CX); }
  4065. pub fn instr32_92_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::DX); }
  4066. pub fn instr32_93_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::BX); }
  4067. pub fn instr32_94_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::SP); }
  4068. pub fn instr32_95_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::BP); }
  4069. pub fn instr32_96_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::SI); }
  4070. pub fn instr32_97_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::DI); }
  4071. pub fn instr16_98_jit(ctx: &mut JitContext) {
  4072. codegen::gen_get_reg32(ctx, regs::EAX);
  4073. codegen::sign_extend_i8(ctx.builder);
  4074. codegen::gen_set_reg16(ctx, regs::AX);
  4075. }
  4076. pub fn instr32_98_jit(ctx: &mut JitContext) {
  4077. codegen::gen_get_reg32(ctx, regs::EAX);
  4078. codegen::sign_extend_i16(ctx.builder);
  4079. codegen::gen_set_reg32(ctx, regs::EAX);
  4080. }
  4081. pub fn instr16_99_jit(ctx: &mut JitContext) {
  4082. codegen::gen_get_reg16(ctx, regs::AX);
  4083. ctx.builder.const_i32(16);
  4084. ctx.builder.shl_i32();
  4085. ctx.builder.const_i32(31);
  4086. ctx.builder.shr_s_i32();
  4087. codegen::gen_set_reg16(ctx, regs::DX);
  4088. }
  4089. pub fn instr32_99_jit(ctx: &mut JitContext) {
  4090. codegen::gen_get_reg32(ctx, regs::EAX);
  4091. ctx.builder.const_i32(31);
  4092. ctx.builder.shr_s_i32();
  4093. codegen::gen_set_reg32(ctx, regs::EDX);
  4094. }
  4095. fn gen_pushf_popf_check(ctx: &mut JitContext) {
  4096. // 0 != *flags & FLAG_VM && getiopl() < 3
  4097. codegen::gen_get_flags(ctx.builder);
  4098. ctx.builder.const_i32(FLAG_VM);
  4099. ctx.builder.and_i32();
  4100. ctx.builder.const_i32(FLAG_VM);
  4101. ctx.builder.eq_i32();
  4102. codegen::gen_get_flags(ctx.builder);
  4103. ctx.builder.const_i32(FLAG_IOPL);
  4104. ctx.builder.and_i32();
  4105. ctx.builder.const_i32(FLAG_IOPL);
  4106. ctx.builder.ne_i32();
  4107. ctx.builder.and_i32();
  4108. }
  4109. pub fn instr16_9C_jit(ctx: &mut JitContext) {
  4110. gen_pushf_popf_check(ctx);
  4111. ctx.builder.if_void();
  4112. codegen::gen_trigger_gp(ctx, 0);
  4113. ctx.builder.else_();
  4114. ctx.builder.call_fn0_ret("get_eflags");
  4115. let value = ctx.builder.set_new_local();
  4116. codegen::gen_push16(ctx, &value);
  4117. ctx.builder.block_end();
  4118. ctx.builder.free_local(value);
  4119. }
  4120. pub fn instr32_9C_jit(ctx: &mut JitContext) {
  4121. gen_pushf_popf_check(ctx);
  4122. ctx.builder.if_void();
  4123. codegen::gen_trigger_gp(ctx, 0);
  4124. ctx.builder.else_();
  4125. ctx.builder.call_fn0_ret("get_eflags");
  4126. ctx.builder.const_i32(0xFCFFFF);
  4127. ctx.builder.and_i32();
  4128. let value = ctx.builder.set_new_local();
  4129. codegen::gen_push32(ctx, &value);
  4130. ctx.builder.block_end();
  4131. ctx.builder.free_local(value);
  4132. }
  4133. fn gen_popf(ctx: &mut JitContext, is_32: bool) {
  4134. gen_pushf_popf_check(ctx);
  4135. ctx.builder.if_void();
  4136. codegen::gen_trigger_gp(ctx, 0);
  4137. ctx.builder.else_();
  4138. codegen::gen_get_flags(ctx.builder);
  4139. let old_eflags = ctx.builder.set_new_local();
  4140. if is_32 {
  4141. codegen::gen_pop32s(ctx);
  4142. }
  4143. else {
  4144. ctx.builder.get_local(&old_eflags);
  4145. ctx.builder.const_i32(!0xFFFF);
  4146. ctx.builder.and_i32();
  4147. codegen::gen_pop16(ctx);
  4148. ctx.builder.or_i32();
  4149. }
  4150. ctx.builder.call_fn1("update_eflags");
  4151. ctx.builder.get_local(&old_eflags);
  4152. ctx.builder.free_local(old_eflags);
  4153. ctx.builder.const_i32(FLAG_INTERRUPT);
  4154. ctx.builder.and_i32();
  4155. ctx.builder.eqz_i32();
  4156. codegen::gen_get_flags(ctx.builder);
  4157. ctx.builder.const_i32(FLAG_INTERRUPT);
  4158. ctx.builder.and_i32();
  4159. ctx.builder.eqz_i32();
  4160. ctx.builder.eqz_i32();
  4161. ctx.builder.and_i32();
  4162. ctx.builder.if_void();
  4163. {
  4164. codegen::gen_set_eip_to_after_current_instruction(ctx);
  4165. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  4166. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4167. codegen::gen_fn0_const(ctx.builder, "handle_irqs");
  4168. codegen::gen_update_instruction_counter(ctx);
  4169. ctx.builder.return_();
  4170. }
  4171. ctx.builder.block_end();
  4172. ctx.builder.block_end();
  4173. }
  4174. pub fn instr16_9D_jit(ctx: &mut JitContext) { gen_popf(ctx, false) }
  4175. pub fn instr32_9D_jit(ctx: &mut JitContext) { gen_popf(ctx, true) }
  4176. pub fn instr_9E_jit(ctx: &mut JitContext) {
  4177. ctx.builder.const_i32(global_pointers::flags as i32);
  4178. codegen::gen_get_flags(ctx.builder);
  4179. ctx.builder.const_i32(!0xFF);
  4180. ctx.builder.and_i32();
  4181. codegen::gen_get_reg8(ctx, regs::AH);
  4182. ctx.builder.or_i32();
  4183. ctx.builder.const_i32(FLAGS_MASK);
  4184. ctx.builder.and_i32();
  4185. ctx.builder.const_i32(FLAGS_DEFAULT);
  4186. ctx.builder.or_i32();
  4187. ctx.builder.store_aligned_i32(0);
  4188. codegen::gen_clear_flags_changed_bits(ctx.builder, 0xFF);
  4189. }
  4190. pub fn instr_9F_jit(ctx: &mut JitContext) {
  4191. ctx.builder.call_fn0_ret("get_eflags");
  4192. codegen::gen_set_reg8(ctx, regs::AH);
  4193. }
  4194. pub fn instr_A0_jit(ctx: &mut JitContext, immaddr: u32) {
  4195. ctx.builder.const_i32(immaddr as i32);
  4196. jit_add_seg_offset(ctx, regs::DS);
  4197. let address_local = ctx.builder.set_new_local();
  4198. codegen::gen_safe_read8(ctx, &address_local);
  4199. ctx.builder.free_local(address_local);
  4200. codegen::gen_set_reg8(ctx, regs::AL);
  4201. }
  4202. pub fn instr16_A1_jit(ctx: &mut JitContext, immaddr: u32) {
  4203. ctx.builder.const_i32(immaddr as i32);
  4204. jit_add_seg_offset(ctx, regs::DS);
  4205. let address_local = ctx.builder.set_new_local();
  4206. codegen::gen_safe_read16(ctx, &address_local);
  4207. ctx.builder.free_local(address_local);
  4208. codegen::gen_set_reg16(ctx, regs::AX);
  4209. }
  4210. pub fn instr32_A1_jit(ctx: &mut JitContext, immaddr: u32) {
  4211. ctx.builder.const_i32(immaddr as i32);
  4212. jit_add_seg_offset(ctx, regs::DS);
  4213. let address_local = ctx.builder.set_new_local();
  4214. codegen::gen_safe_read32(ctx, &address_local);
  4215. ctx.builder.free_local(address_local);
  4216. codegen::gen_set_reg32(ctx, regs::EAX);
  4217. }
  4218. pub fn instr_A2_jit(ctx: &mut JitContext, immaddr: u32) {
  4219. ctx.builder.const_i32(immaddr as i32);
  4220. jit_add_seg_offset(ctx, regs::DS);
  4221. let address_local = ctx.builder.set_new_local();
  4222. codegen::gen_safe_write8(ctx, &address_local, &ctx.reg(regs::EAX));
  4223. ctx.builder.free_local(address_local);
  4224. }
  4225. pub fn instr16_A3_jit(ctx: &mut JitContext, immaddr: u32) {
  4226. ctx.builder.const_i32(immaddr as i32);
  4227. jit_add_seg_offset(ctx, regs::DS);
  4228. let address_local = ctx.builder.set_new_local();
  4229. codegen::gen_safe_write16(ctx, &address_local, &ctx.reg(regs::EAX));
  4230. ctx.builder.free_local(address_local);
  4231. }
  4232. pub fn instr32_A3_jit(ctx: &mut JitContext, immaddr: u32) {
  4233. ctx.builder.const_i32(immaddr as i32);
  4234. jit_add_seg_offset(ctx, regs::DS);
  4235. let address_local = ctx.builder.set_new_local();
  4236. codegen::gen_safe_write32(ctx, &address_local, &ctx.reg(regs::EAX));
  4237. ctx.builder.free_local(address_local);
  4238. }
  4239. pub fn instr_A8_jit(ctx: &mut JitContext, imm8: u32) {
  4240. gen_test8(ctx, &ctx.reg(0), &LocalOrImmediate::Immediate(imm8 as i32));
  4241. }
  4242. pub fn instr16_A9_jit(ctx: &mut JitContext, imm16: u32) {
  4243. gen_test16(ctx, &ctx.reg(0), &LocalOrImmediate::Immediate(imm16 as i32));
  4244. }
  4245. pub fn instr32_A9_jit(ctx: &mut JitContext, imm32: u32) {
  4246. gen_test32(ctx, &ctx.reg(0), &LocalOrImmediate::Immediate(imm32 as i32));
  4247. }
  4248. #[derive(PartialEq)]
  4249. enum String {
  4250. INS,
  4251. OUTS,
  4252. MOVS,
  4253. CMPS,
  4254. STOS,
  4255. LODS,
  4256. SCAS,
  4257. }
  4258. fn gen_string_ins(ctx: &mut JitContext, ins: String, size: u8, prefix: u8) {
  4259. dbg_assert!(prefix == 0 || prefix == 0xF2 || prefix == 0xF3);
  4260. dbg_assert!(size == 8 || size == 16 || size == 32);
  4261. if prefix == 0 {
  4262. fn get_direction(ctx: &mut JitContext, size: u8) {
  4263. let bytes: i32 = (size / 8).into();
  4264. dbg_assert!(bytes == 1 || bytes == 2 || bytes == 4);
  4265. ctx.builder.const_i32(-bytes);
  4266. ctx.builder.const_i32(bytes);
  4267. codegen::gen_get_flags(ctx.builder);
  4268. ctx.builder.const_i32(FLAG_DIRECTION);
  4269. ctx.builder.and_i32();
  4270. ctx.builder.select();
  4271. }
  4272. match &ins {
  4273. String::LODS => {
  4274. if ctx.cpu.asize_32() {
  4275. codegen::gen_get_reg32(ctx, regs::ESI);
  4276. }
  4277. else {
  4278. codegen::gen_get_reg16(ctx, regs::ESI);
  4279. }
  4280. jit_add_seg_offset(ctx, regs::DS);
  4281. let address_local = ctx.builder.set_new_local();
  4282. if size == 8 {
  4283. codegen::gen_safe_read8(ctx, &address_local);
  4284. ctx.builder.free_local(address_local);
  4285. codegen::gen_set_reg8_unmasked(ctx, regs::AL);
  4286. }
  4287. else if size == 16 {
  4288. codegen::gen_safe_read16(ctx, &address_local);
  4289. ctx.builder.free_local(address_local);
  4290. codegen::gen_set_reg16(ctx, regs::AX);
  4291. }
  4292. else {
  4293. codegen::gen_safe_read32(ctx, &address_local);
  4294. ctx.builder.free_local(address_local);
  4295. codegen::gen_set_reg32(ctx, regs::EAX);
  4296. }
  4297. codegen::gen_get_reg32(ctx, regs::ESI);
  4298. get_direction(ctx, size);
  4299. ctx.builder.add_i32();
  4300. if ctx.cpu.asize_32() {
  4301. codegen::gen_set_reg32(ctx, regs::ESI);
  4302. }
  4303. else {
  4304. codegen::gen_set_reg16(ctx, regs::ESI);
  4305. }
  4306. return;
  4307. },
  4308. String::SCAS => {
  4309. if ctx.cpu.asize_32() {
  4310. codegen::gen_get_reg32(ctx, regs::EDI);
  4311. }
  4312. else {
  4313. codegen::gen_get_reg16(ctx, regs::EDI);
  4314. }
  4315. jit_add_seg_offset_no_override(ctx, regs::ES);
  4316. let address_local = ctx.builder.set_new_local();
  4317. if size == 8 {
  4318. codegen::gen_safe_read8(ctx, &address_local);
  4319. ctx.builder.free_local(address_local);
  4320. let value = ctx.builder.set_new_local();
  4321. gen_cmp8(
  4322. ctx,
  4323. &ctx.reg(regs::EAX),
  4324. &LocalOrImmediate::WasmLocal(&value),
  4325. );
  4326. ctx.builder.free_local(value);
  4327. }
  4328. else if size == 16 {
  4329. codegen::gen_safe_read16(ctx, &address_local);
  4330. ctx.builder.free_local(address_local);
  4331. let value = ctx.builder.set_new_local();
  4332. gen_cmp16(
  4333. ctx,
  4334. &ctx.reg(regs::EAX),
  4335. &LocalOrImmediate::WasmLocal(&value),
  4336. );
  4337. ctx.builder.free_local(value);
  4338. }
  4339. else {
  4340. codegen::gen_safe_read32(ctx, &address_local);
  4341. ctx.builder.free_local(address_local);
  4342. let value = ctx.builder.set_new_local();
  4343. gen_cmp32(
  4344. ctx,
  4345. &ctx.reg(regs::EAX),
  4346. &LocalOrImmediate::WasmLocal(&value),
  4347. );
  4348. ctx.builder.free_local(value);
  4349. }
  4350. codegen::gen_get_reg32(ctx, regs::EDI);
  4351. get_direction(ctx, size);
  4352. ctx.builder.add_i32();
  4353. if ctx.cpu.asize_32() {
  4354. codegen::gen_set_reg32(ctx, regs::EDI);
  4355. }
  4356. else {
  4357. codegen::gen_set_reg16(ctx, regs::EDI);
  4358. }
  4359. return;
  4360. },
  4361. String::STOS => {
  4362. if ctx.cpu.asize_32() {
  4363. codegen::gen_get_reg32(ctx, regs::EDI);
  4364. }
  4365. else {
  4366. codegen::gen_get_reg16(ctx, regs::EDI);
  4367. }
  4368. jit_add_seg_offset_no_override(ctx, regs::ES);
  4369. let address_local = ctx.builder.set_new_local();
  4370. if size == 8 {
  4371. codegen::gen_safe_write8(ctx, &address_local, &ctx.reg(regs::AL));
  4372. ctx.builder.free_local(address_local);
  4373. }
  4374. else if size == 16 {
  4375. codegen::gen_safe_write16(ctx, &address_local, &ctx.reg(regs::AX));
  4376. ctx.builder.free_local(address_local);
  4377. }
  4378. else {
  4379. codegen::gen_safe_write32(ctx, &address_local, &ctx.reg(regs::EAX));
  4380. ctx.builder.free_local(address_local);
  4381. }
  4382. codegen::gen_get_reg32(ctx, regs::EDI);
  4383. get_direction(ctx, size);
  4384. ctx.builder.add_i32();
  4385. if ctx.cpu.asize_32() {
  4386. codegen::gen_set_reg32(ctx, regs::EDI);
  4387. }
  4388. else {
  4389. codegen::gen_set_reg16(ctx, regs::EDI);
  4390. }
  4391. return;
  4392. },
  4393. String::MOVS => {
  4394. if ctx.cpu.asize_32() {
  4395. codegen::gen_get_reg32(ctx, regs::EDI);
  4396. }
  4397. else {
  4398. codegen::gen_get_reg16(ctx, regs::EDI);
  4399. }
  4400. jit_add_seg_offset_no_override(ctx, regs::ES);
  4401. let dest_address = ctx.builder.set_new_local();
  4402. if ctx.cpu.asize_32() {
  4403. codegen::gen_get_reg32(ctx, regs::ESI);
  4404. }
  4405. else {
  4406. codegen::gen_get_reg16(ctx, regs::ESI);
  4407. }
  4408. jit_add_seg_offset(ctx, regs::DS);
  4409. let source_address = ctx.builder.set_new_local();
  4410. if size == 8 {
  4411. codegen::gen_safe_read8(ctx, &source_address);
  4412. ctx.builder.free_local(source_address);
  4413. let value = ctx.builder.set_new_local();
  4414. codegen::gen_safe_write8(ctx, &dest_address, &value);
  4415. ctx.builder.free_local(value);
  4416. }
  4417. else if size == 16 {
  4418. codegen::gen_safe_read16(ctx, &source_address);
  4419. ctx.builder.free_local(source_address);
  4420. let value = ctx.builder.set_new_local();
  4421. codegen::gen_safe_write16(ctx, &dest_address, &value);
  4422. ctx.builder.free_local(value);
  4423. }
  4424. else {
  4425. codegen::gen_safe_read32(ctx, &source_address);
  4426. ctx.builder.free_local(source_address);
  4427. let value = ctx.builder.set_new_local();
  4428. codegen::gen_safe_write32(ctx, &dest_address, &value);
  4429. ctx.builder.free_local(value);
  4430. }
  4431. ctx.builder.free_local(dest_address);
  4432. codegen::gen_get_reg32(ctx, regs::EDI);
  4433. get_direction(ctx, size);
  4434. ctx.builder.add_i32();
  4435. if ctx.cpu.asize_32() {
  4436. codegen::gen_set_reg32(ctx, regs::EDI);
  4437. }
  4438. else {
  4439. codegen::gen_set_reg16(ctx, regs::EDI);
  4440. }
  4441. codegen::gen_get_reg32(ctx, regs::ESI);
  4442. get_direction(ctx, size);
  4443. ctx.builder.add_i32();
  4444. if ctx.cpu.asize_32() {
  4445. codegen::gen_set_reg32(ctx, regs::ESI);
  4446. }
  4447. else {
  4448. codegen::gen_set_reg16(ctx, regs::ESI);
  4449. }
  4450. return;
  4451. },
  4452. _ => {},
  4453. }
  4454. }
  4455. let mut args = 0;
  4456. args += 1;
  4457. ctx.builder.const_i32(ctx.cpu.asize_32() as i32);
  4458. if ins == String::OUTS || ins == String::CMPS || ins == String::LODS || ins == String::MOVS {
  4459. args += 1;
  4460. ctx.builder.const_i32(0);
  4461. jit_add_seg_offset(ctx, regs::DS);
  4462. }
  4463. let name = format!(
  4464. "{}{}{}",
  4465. match ins {
  4466. String::INS => "ins",
  4467. String::OUTS => "outs",
  4468. String::MOVS => "movs",
  4469. String::CMPS => "cmps",
  4470. String::STOS => "stos",
  4471. String::LODS => "lods",
  4472. String::SCAS => "scas",
  4473. },
  4474. if size == 8 {
  4475. "b"
  4476. }
  4477. else if size == 16 {
  4478. "w"
  4479. }
  4480. else {
  4481. "d"
  4482. },
  4483. if prefix == 0xF2 || prefix == 0xF3 {
  4484. match ins {
  4485. String::CMPS | String::SCAS => {
  4486. if prefix == 0xF2 {
  4487. "_repnz"
  4488. }
  4489. else {
  4490. "_repz"
  4491. }
  4492. },
  4493. _ => "_rep",
  4494. }
  4495. }
  4496. else {
  4497. "_no_rep"
  4498. }
  4499. );
  4500. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4501. if args == 1 {
  4502. ctx.builder.call_fn1(&name)
  4503. }
  4504. else if args == 2 {
  4505. ctx.builder.call_fn2(&name)
  4506. }
  4507. else {
  4508. dbg_assert!(false);
  4509. }
  4510. codegen::gen_move_registers_from_memory_to_locals(ctx);
  4511. }
  4512. pub fn instr_6C_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 8, 0) }
  4513. pub fn instr_F26C_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 8, 0xF2) }
  4514. pub fn instr_F36C_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 8, 0xF3) }
  4515. pub fn instr16_6D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 16, 0) }
  4516. pub fn instr16_F26D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 16, 0xF2) }
  4517. pub fn instr16_F36D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 16, 0xF3) }
  4518. pub fn instr32_6D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 32, 0) }
  4519. pub fn instr32_F26D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 32, 0xF2) }
  4520. pub fn instr32_F36D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 32, 0xF3) }
  4521. pub fn instr_6E_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 8, 0) }
  4522. pub fn instr_F26E_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 8, 0xF2) }
  4523. pub fn instr_F36E_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 8, 0xF3) }
  4524. pub fn instr16_6F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 16, 0) }
  4525. pub fn instr16_F26F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 16, 0xF2) }
  4526. pub fn instr16_F36F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 16, 0xF3) }
  4527. pub fn instr32_6F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 32, 0) }
  4528. pub fn instr32_F26F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 32, 0xF2) }
  4529. pub fn instr32_F36F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 32, 0xF3) }
  4530. pub fn instr_A4_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 8, 0) }
  4531. pub fn instr_F2A4_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 8, 0xF2) }
  4532. pub fn instr_F3A4_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 8, 0xF3) }
  4533. pub fn instr16_A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 16, 0) }
  4534. pub fn instr16_F2A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 16, 0xF2) }
  4535. pub fn instr16_F3A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 16, 0xF3) }
  4536. pub fn instr32_A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 32, 0) }
  4537. pub fn instr32_F2A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 32, 0xF2) }
  4538. pub fn instr32_F3A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 32, 0xF3) }
  4539. pub fn instr_A6_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 8, 0) }
  4540. pub fn instr_F2A6_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 8, 0xF2) }
  4541. pub fn instr_F3A6_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 8, 0xF3) }
  4542. pub fn instr16_A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 16, 0) }
  4543. pub fn instr16_F2A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 16, 0xF2) }
  4544. pub fn instr16_F3A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 16, 0xF3) }
  4545. pub fn instr32_A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 32, 0) }
  4546. pub fn instr32_F2A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 32, 0xF2) }
  4547. pub fn instr32_F3A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 32, 0xF3) }
  4548. pub fn instr_AA_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 8, 0) }
  4549. pub fn instr_F2AA_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 8, 0xF2) }
  4550. pub fn instr_F3AA_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 8, 0xF3) }
  4551. pub fn instr16_AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 16, 0) }
  4552. pub fn instr16_F2AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 16, 0xF2) }
  4553. pub fn instr16_F3AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 16, 0xF3) }
  4554. pub fn instr32_AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 32, 0) }
  4555. pub fn instr32_F2AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 32, 0xF2) }
  4556. pub fn instr32_F3AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 32, 0xF3) }
  4557. pub fn instr_AC_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 8, 0) }
  4558. pub fn instr_F2AC_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 8, 0xF2) }
  4559. pub fn instr_F3AC_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 8, 0xF3) }
  4560. pub fn instr16_AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 16, 0) }
  4561. pub fn instr16_F2AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 16, 0xF2) }
  4562. pub fn instr16_F3AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 16, 0xF3) }
  4563. pub fn instr32_AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 32, 0) }
  4564. pub fn instr32_F2AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 32, 0xF2) }
  4565. pub fn instr32_F3AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 32, 0xF3) }
  4566. pub fn instr_AE_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 8, 0) }
  4567. pub fn instr_F2AE_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 8, 0xF2) }
  4568. pub fn instr_F3AE_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 8, 0xF3) }
  4569. pub fn instr16_AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 16, 0) }
  4570. pub fn instr16_F2AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 16, 0xF2) }
  4571. pub fn instr16_F3AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 16, 0xF3) }
  4572. pub fn instr32_AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 32, 0) }
  4573. pub fn instr32_F2AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 32, 0xF2) }
  4574. pub fn instr32_F3AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 32, 0xF3) }
  4575. pub fn instr_0F31_jit(ctx: &mut JitContext) {
  4576. ctx.builder.load_fixed_u8(global_pointers::cpl as u32);
  4577. ctx.builder.eqz_i32();
  4578. dbg_assert!(regs::CR4_TSD < 0x100);
  4579. ctx.builder
  4580. .load_fixed_u8(global_pointers::get_creg_offset(4));
  4581. ctx.builder.const_i32(regs::CR4_TSD as i32);
  4582. ctx.builder.and_i32();
  4583. ctx.builder.eqz_i32();
  4584. ctx.builder.or_i32();
  4585. ctx.builder.if_void();
  4586. ctx.builder.call_fn0_ret_i64("read_tsc");
  4587. let tsc = ctx.builder.tee_new_local_i64();
  4588. ctx.builder.wrap_i64_to_i32();
  4589. codegen::gen_set_reg32(ctx, regs::EAX);
  4590. ctx.builder.get_local_i64(&tsc);
  4591. ctx.builder.const_i64(32);
  4592. ctx.builder.shr_u_i64();
  4593. ctx.builder.wrap_i64_to_i32();
  4594. codegen::gen_set_reg32(ctx, regs::EDX);
  4595. ctx.builder.free_local_i64(tsc);
  4596. ctx.builder.else_();
  4597. codegen::gen_trigger_gp(ctx, 0);
  4598. ctx.builder.block_end();
  4599. }
  4600. pub fn instr_0F18_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4601. pub fn instr_0F18_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4602. pub fn instr_0F19_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4603. pub fn instr_0F19_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4604. pub fn instr_0F1C_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4605. pub fn instr_0F1C_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4606. pub fn instr_0F1D_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4607. pub fn instr_0F1D_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4608. pub fn instr_0F1E_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4609. pub fn instr_0F1E_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4610. pub fn instr_0F1F_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
  4611. pub fn instr_0F1F_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
  4612. define_instruction_read_write_mem16!(
  4613. "shld16",
  4614. instr16_0FA4_mem_jit,
  4615. instr16_0FA4_reg_jit,
  4616. reg,
  4617. imm8_5bits
  4618. );
  4619. define_instruction_read_write_mem32!(
  4620. "shld32",
  4621. instr32_0FA4_mem_jit,
  4622. instr32_0FA4_reg_jit,
  4623. reg,
  4624. imm8_5bits
  4625. );
  4626. define_instruction_read_write_mem16!(
  4627. "shld16",
  4628. instr16_0FA5_mem_jit,
  4629. instr16_0FA5_reg_jit,
  4630. reg,
  4631. cl
  4632. );
  4633. define_instruction_read_write_mem32!(
  4634. "shld32",
  4635. instr32_0FA5_mem_jit,
  4636. instr32_0FA5_reg_jit,
  4637. reg,
  4638. cl
  4639. );
  4640. define_instruction_read_write_mem16!(
  4641. "shrd16",
  4642. instr16_0FAC_mem_jit,
  4643. instr16_0FAC_reg_jit,
  4644. reg,
  4645. imm8_5bits
  4646. );
  4647. define_instruction_read_write_mem32!(
  4648. "shrd32",
  4649. instr32_0FAC_mem_jit,
  4650. instr32_0FAC_reg_jit,
  4651. reg,
  4652. imm8_5bits
  4653. );
  4654. define_instruction_read_write_mem16!(
  4655. "shrd16",
  4656. instr16_0FAD_mem_jit,
  4657. instr16_0FAD_reg_jit,
  4658. reg,
  4659. cl
  4660. );
  4661. define_instruction_read_write_mem32!(
  4662. "shrd32",
  4663. instr32_0FAD_mem_jit,
  4664. instr32_0FAD_reg_jit,
  4665. reg,
  4666. cl
  4667. );
  4668. pub fn instr16_0FB1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4669. codegen::gen_get_reg16(ctx, r1);
  4670. ctx.builder.const_i32(r2 as i32);
  4671. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4672. ctx.builder.call_fn2_ret("cmpxchg16");
  4673. codegen::gen_move_registers_from_memory_to_locals(ctx);
  4674. codegen::gen_set_reg16(ctx, r1);
  4675. }
  4676. pub fn instr16_0FB1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4677. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4678. let address_local = ctx.builder.set_new_local();
  4679. codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
  4680. ctx.builder.const_i32(r as i32);
  4681. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4682. ctx.builder.call_fn2_ret("cmpxchg16");
  4683. codegen::gen_move_registers_from_memory_to_locals(ctx);
  4684. });
  4685. ctx.builder.free_local(address_local);
  4686. }
  4687. pub fn instr32_0FB1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4688. codegen::gen_get_reg32(ctx, r1);
  4689. gen_cmpxchg32(ctx, r2);
  4690. codegen::gen_set_reg32(ctx, r1);
  4691. }
  4692. pub fn instr32_0FB1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4693. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4694. let address_local = ctx.builder.set_new_local();
  4695. codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
  4696. gen_cmpxchg32(ctx, r);
  4697. });
  4698. ctx.builder.free_local(address_local);
  4699. }
  4700. pub fn instr16_0FB6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4701. codegen::gen_get_reg8(ctx, r1);
  4702. codegen::gen_set_reg16_unmasked(ctx, r2);
  4703. }
  4704. pub fn instr16_0FB6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4705. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
  4706. codegen::gen_set_reg16_unmasked(ctx, r);
  4707. }
  4708. pub fn instr32_0FB6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4709. codegen::gen_get_reg8(ctx, r1);
  4710. codegen::gen_set_reg32(ctx, r2);
  4711. }
  4712. pub fn instr32_0FB6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4713. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
  4714. codegen::gen_set_reg32(ctx, r);
  4715. }
  4716. pub fn instr16_0FB7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4717. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  4718. codegen::gen_set_reg16(ctx, r);
  4719. }
  4720. pub fn instr16_0FB7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4721. codegen::gen_get_reg16(ctx, r1);
  4722. codegen::gen_set_reg16(ctx, r2);
  4723. }
  4724. pub fn instr32_0FB7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4725. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  4726. codegen::gen_set_reg32(ctx, r);
  4727. }
  4728. pub fn instr32_0FB7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4729. codegen::gen_get_reg16(ctx, r1);
  4730. codegen::gen_set_reg32(ctx, r2);
  4731. }
  4732. pub fn instr16_F30FB8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4733. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  4734. ctx.builder.call_fn1_ret("popcnt");
  4735. codegen::gen_set_reg16(ctx, r);
  4736. }
  4737. pub fn instr16_F30FB8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4738. codegen::gen_get_reg16(ctx, r1);
  4739. ctx.builder.call_fn1_ret("popcnt");
  4740. codegen::gen_set_reg16(ctx, r2);
  4741. }
  4742. pub fn instr32_F30FB8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4743. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  4744. ctx.builder.call_fn1_ret("popcnt");
  4745. codegen::gen_set_reg32(ctx, r);
  4746. }
  4747. pub fn instr32_F30FB8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4748. codegen::gen_get_reg32(ctx, r1);
  4749. ctx.builder.call_fn1_ret("popcnt");
  4750. codegen::gen_set_reg32(ctx, r2);
  4751. }
  4752. define_instruction_write_reg16!("bsf16", instr16_0FBC_mem_jit, instr16_0FBC_reg_jit);
  4753. define_instruction_write_reg32!(gen_bsf32, instr32_0FBC_mem_jit, instr32_0FBC_reg_jit);
  4754. define_instruction_write_reg16!("bsr16", instr16_0FBD_mem_jit, instr16_0FBD_reg_jit);
  4755. define_instruction_write_reg32!(gen_bsr32, instr32_0FBD_mem_jit, instr32_0FBD_reg_jit);
  4756. pub fn instr16_0FBE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4757. codegen::gen_get_reg8(ctx, r1);
  4758. codegen::sign_extend_i8(ctx.builder);
  4759. codegen::gen_set_reg16(ctx, r2);
  4760. }
  4761. pub fn instr16_0FBE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4762. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte); // TODO: Could use sign-extended read
  4763. codegen::sign_extend_i8(ctx.builder);
  4764. codegen::gen_set_reg16(ctx, r);
  4765. }
  4766. pub fn instr32_0FBE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4767. match r1 {
  4768. regs::AL | regs::CL | regs::DL | regs::BL => {
  4769. ctx.builder.get_local(&ctx.register_locals[r1 as usize]);
  4770. ctx.builder.const_i32(24);
  4771. ctx.builder.shl_i32();
  4772. },
  4773. regs::AH | regs::CH | regs::DH | regs::BH => {
  4774. ctx.builder
  4775. .get_local(&ctx.register_locals[(r1 - 4) as usize]);
  4776. ctx.builder.const_i32(16);
  4777. ctx.builder.shl_i32();
  4778. },
  4779. _ => assert!(false),
  4780. }
  4781. ctx.builder.const_i32(24);
  4782. ctx.builder.shr_s_i32();
  4783. codegen::gen_set_reg32(ctx, r2);
  4784. }
  4785. pub fn instr32_0FBE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4786. codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte); // TODO: Could use sign-extended read
  4787. codegen::sign_extend_i8(ctx.builder);
  4788. codegen::gen_set_reg32(ctx, r);
  4789. }
  4790. pub fn instr16_0FBF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4791. codegen::gen_get_reg16(ctx, r1);
  4792. codegen::gen_set_reg16_unmasked(ctx, r2);
  4793. }
  4794. pub fn instr16_0FBF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4795. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  4796. codegen::gen_set_reg16_unmasked(ctx, r);
  4797. }
  4798. pub fn instr32_0FBF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4799. codegen::gen_get_reg32(ctx, r1);
  4800. codegen::sign_extend_i16(ctx.builder);
  4801. codegen::gen_set_reg32(ctx, r2);
  4802. }
  4803. pub fn instr32_0FBF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4804. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte); // TODO: Could use sign-extended read
  4805. codegen::sign_extend_i16(ctx.builder);
  4806. codegen::gen_set_reg32(ctx, r);
  4807. }
  4808. pub fn instr16_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::WORD, &address_local, &|ref mut ctx| {
  4812. ctx.builder.const_i32(r as i32);
  4813. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4814. ctx.builder.call_fn2_ret("xadd16");
  4815. codegen::gen_move_registers_from_memory_to_locals(ctx);
  4816. });
  4817. ctx.builder.free_local(address_local);
  4818. }
  4819. pub fn instr16_0FC1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4820. codegen::gen_get_reg16(ctx, r1);
  4821. ctx.builder.const_i32(r2 as i32);
  4822. codegen::gen_move_registers_from_locals_to_memory(ctx);
  4823. ctx.builder.call_fn2_ret("xadd16");
  4824. codegen::gen_move_registers_from_memory_to_locals(ctx);
  4825. codegen::gen_set_reg16(ctx, r1);
  4826. }
  4827. pub fn instr32_0FC1_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_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
  4831. let dest_operand = ctx.builder.set_new_local();
  4832. gen_xadd32(ctx, &dest_operand, r);
  4833. ctx.builder.get_local(&dest_operand);
  4834. ctx.builder.free_local(dest_operand);
  4835. });
  4836. ctx.builder.free_local(address_local);
  4837. }
  4838. pub fn instr32_0FC1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  4839. codegen::gen_get_reg32(ctx, r1);
  4840. let dest_operand = ctx.builder.set_new_local();
  4841. gen_xadd32(ctx, &dest_operand, r2);
  4842. ctx.builder.get_local(&dest_operand);
  4843. codegen::gen_set_reg32(ctx, r1);
  4844. ctx.builder.free_local(dest_operand);
  4845. }
  4846. pub fn instr_0FC3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  4847. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4848. let address_local = ctx.builder.set_new_local();
  4849. codegen::gen_safe_write32(ctx, &address_local, &ctx.reg(r));
  4850. ctx.builder.free_local(address_local);
  4851. }
  4852. pub fn instr_0FC3_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) { codegen::gen_trigger_ud(ctx) }
  4853. pub fn instr16_0FC7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  4854. // cmpxchg8b
  4855. codegen::gen_modrm_resolve(ctx, modrm_byte);
  4856. let address_local = ctx.builder.set_new_local();
  4857. codegen::gen_safe_read_write(ctx, BitSize::QWORD, &address_local, &|ref mut ctx| {
  4858. let dest_operand = ctx.builder.tee_new_local_i64();
  4859. codegen::gen_get_reg32(ctx, regs::EDX);
  4860. ctx.builder.extend_unsigned_i32_to_i64();
  4861. ctx.builder.const_i64(32);
  4862. ctx.builder.shl_i64();
  4863. codegen::gen_get_reg32(ctx, regs::EAX);
  4864. ctx.builder.extend_unsigned_i32_to_i64();
  4865. ctx.builder.or_i64();
  4866. ctx.builder.eq_i64();
  4867. ctx.builder.if_i64();
  4868. {
  4869. codegen::gen_set_flags_bits(ctx.builder, FLAG_ZERO);
  4870. codegen::gen_get_reg32(ctx, regs::ECX);
  4871. ctx.builder.extend_unsigned_i32_to_i64();
  4872. ctx.builder.const_i64(32);
  4873. ctx.builder.shl_i64();
  4874. codegen::gen_get_reg32(ctx, regs::EBX);
  4875. ctx.builder.extend_unsigned_i32_to_i64();
  4876. ctx.builder.or_i64();
  4877. }
  4878. ctx.builder.else_();
  4879. {
  4880. codegen::gen_clear_flags_bits(ctx.builder, FLAG_ZERO);
  4881. ctx.builder.get_local_i64(&dest_operand);
  4882. ctx.builder.wrap_i64_to_i32();
  4883. codegen::gen_set_reg32(ctx, regs::EAX);
  4884. ctx.builder.get_local_i64(&dest_operand);
  4885. ctx.builder.const_i64(32);
  4886. ctx.builder.shr_u_i64();
  4887. ctx.builder.wrap_i64_to_i32();
  4888. codegen::gen_set_reg32(ctx, regs::EDX);
  4889. ctx.builder.get_local_i64(&dest_operand);
  4890. }
  4891. ctx.builder.block_end();
  4892. codegen::gen_clear_flags_changed_bits(ctx.builder, FLAG_ZERO);
  4893. ctx.builder.free_local_i64(dest_operand);
  4894. });
  4895. ctx.builder.free_local(address_local);
  4896. }
  4897. pub fn instr16_0FC7_1_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx); }
  4898. pub fn instr32_0FC7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
  4899. instr16_0FC7_1_mem_jit(ctx, modrm_byte);
  4900. }
  4901. pub fn instr32_0FC7_1_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx); }
  4902. pub fn instr_0FC2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4903. sse_read128_xmm_xmm_imm(ctx, "instr_0FC2", r1, r2, imm8)
  4904. }
  4905. pub fn instr_0FC2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4906. sse_read128_xmm_mem_imm(ctx, "instr_0FC2", modrm_byte, r, imm8)
  4907. }
  4908. pub fn instr_660FC2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4909. sse_read128_xmm_xmm_imm(ctx, "instr_660FC2", r1, r2, imm8)
  4910. }
  4911. pub fn instr_660FC2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4912. sse_read128_xmm_mem_imm(ctx, "instr_660FC2", modrm_byte, r, imm8)
  4913. }
  4914. pub fn instr_F20FC2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4915. ctx.builder
  4916. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  4917. ctx.builder.load_aligned_i64(0);
  4918. ctx.builder.const_i32(r2 as i32);
  4919. ctx.builder.const_i32(imm8 as i32);
  4920. ctx.builder.call_fn3_i64_i32_i32("instr_F20FC2");
  4921. }
  4922. pub fn instr_F20FC2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4923. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  4924. ctx.builder.const_i32(r as i32);
  4925. ctx.builder.const_i32(imm8 as i32);
  4926. ctx.builder.call_fn3_i64_i32_i32("instr_F20FC2");
  4927. }
  4928. pub fn instr_F30FC2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4929. ctx.builder
  4930. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  4931. ctx.builder.load_aligned_i32(0);
  4932. ctx.builder.const_i32(r2 as i32);
  4933. ctx.builder.const_i32(imm8 as i32);
  4934. ctx.builder.call_fn3("instr_F30FC2");
  4935. }
  4936. pub fn instr_F30FC2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4937. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  4938. ctx.builder.const_i32(r as i32);
  4939. ctx.builder.const_i32(imm8 as i32);
  4940. ctx.builder.call_fn3("instr_F30FC2");
  4941. }
  4942. pub fn instr_0FC6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4943. sse_read128_xmm_xmm_imm(ctx, "instr_0FC6", r1, r2, imm8)
  4944. }
  4945. pub fn instr_0FC6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4946. sse_read128_xmm_mem_imm(ctx, "instr_0FC6", modrm_byte, r, imm8)
  4947. }
  4948. pub fn instr_660FC6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  4949. sse_read128_xmm_xmm_imm(ctx, "instr_660FC6", r1, r2, imm8)
  4950. }
  4951. pub fn instr_660FC6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  4952. sse_read128_xmm_mem_imm(ctx, "instr_660FC6", modrm_byte, r, imm8)
  4953. }
  4954. pub fn instr_C6_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  4955. // reg8[r] = imm;
  4956. ctx.builder.const_i32(imm as i32);
  4957. codegen::gen_set_reg8_unmasked(ctx, r);
  4958. }
  4959. pub fn instr_C6_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  4960. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  4961. ctx.builder.const_i32(imm as i32);
  4962. let value_local = ctx.builder.set_new_local();
  4963. codegen::gen_safe_write8(ctx, &addr, &value_local);
  4964. ctx.builder.free_local(value_local);
  4965. });
  4966. }
  4967. pub fn instr16_C7_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  4968. // reg16[r] = imm;
  4969. ctx.builder.const_i32(imm as i32);
  4970. codegen::gen_set_reg16_unmasked(ctx, r);
  4971. }
  4972. pub fn instr16_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  4973. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  4974. ctx.builder.const_i32(imm as i32);
  4975. let value_local = ctx.builder.set_new_local();
  4976. codegen::gen_safe_write16(ctx, &addr, &value_local);
  4977. ctx.builder.free_local(value_local);
  4978. });
  4979. }
  4980. pub fn instr32_C7_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
  4981. // reg32[r] = imm;
  4982. ctx.builder.const_i32(imm as i32);
  4983. codegen::gen_set_reg32(ctx, r);
  4984. }
  4985. pub fn instr32_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
  4986. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  4987. ctx.builder.const_i32(imm as i32);
  4988. let value_local = ctx.builder.set_new_local();
  4989. codegen::gen_safe_write32(ctx, &addr, &value_local);
  4990. ctx.builder.free_local(value_local);
  4991. });
  4992. }
  4993. pub fn instr_0FC8_jit(ctx: &mut JitContext) { gen_bswap(ctx, 0) }
  4994. pub fn instr_0FC9_jit(ctx: &mut JitContext) { gen_bswap(ctx, 1) }
  4995. pub fn instr_0FCA_jit(ctx: &mut JitContext) { gen_bswap(ctx, 2) }
  4996. pub fn instr_0FCB_jit(ctx: &mut JitContext) { gen_bswap(ctx, 3) }
  4997. pub fn instr_0FCC_jit(ctx: &mut JitContext) { gen_bswap(ctx, 4) }
  4998. pub fn instr_0FCD_jit(ctx: &mut JitContext) { gen_bswap(ctx, 5) }
  4999. pub fn instr_0FCE_jit(ctx: &mut JitContext) { gen_bswap(ctx, 6) }
  5000. pub fn instr_0FCF_jit(ctx: &mut JitContext) { gen_bswap(ctx, 7) }
  5001. define_instruction_write_reg16!("imul_reg16", instr16_0FAF_mem_jit, instr16_0FAF_reg_jit);
  5002. define_instruction_write_reg32!(gen_imul_reg32, instr32_0FAF_mem_jit, instr32_0FAF_reg_jit);
  5003. macro_rules! define_cmovcc16(
  5004. ($cond:expr, $name_mem:ident, $name_reg:ident) => (
  5005. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5006. codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
  5007. let value = ctx.builder.set_new_local();
  5008. codegen::gen_condition_fn(ctx, $cond);
  5009. ctx.builder.if_void();
  5010. ctx.builder.get_local(&value);
  5011. codegen::gen_set_reg16(ctx, r);
  5012. ctx.builder.block_end();
  5013. ctx.builder.free_local(value);
  5014. }
  5015. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  5016. codegen::gen_condition_fn(ctx, $cond);
  5017. ctx.builder.if_void();
  5018. codegen::gen_get_reg16(ctx, r1);
  5019. codegen::gen_set_reg16(ctx, r2);
  5020. ctx.builder.block_end();
  5021. }
  5022. );
  5023. );
  5024. macro_rules! define_cmovcc32(
  5025. ($cond:expr, $name_mem:ident, $name_reg:ident) => (
  5026. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5027. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5028. let value = ctx.builder.set_new_local();
  5029. codegen::gen_condition_fn(ctx, $cond);
  5030. ctx.builder.if_void();
  5031. ctx.builder.get_local(&value);
  5032. codegen::gen_set_reg32(ctx, r);
  5033. ctx.builder.block_end();
  5034. ctx.builder.free_local(value);
  5035. }
  5036. pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
  5037. codegen::gen_condition_fn(ctx, $cond);
  5038. ctx.builder.if_void();
  5039. codegen::gen_get_reg32(ctx, r1);
  5040. codegen::gen_set_reg32(ctx, r2);
  5041. ctx.builder.block_end();
  5042. }
  5043. );
  5044. );
  5045. define_cmovcc16!(0x0, instr16_0F40_mem_jit, instr16_0F40_reg_jit);
  5046. define_cmovcc16!(0x1, instr16_0F41_mem_jit, instr16_0F41_reg_jit);
  5047. define_cmovcc16!(0x2, instr16_0F42_mem_jit, instr16_0F42_reg_jit);
  5048. define_cmovcc16!(0x3, instr16_0F43_mem_jit, instr16_0F43_reg_jit);
  5049. define_cmovcc16!(0x4, instr16_0F44_mem_jit, instr16_0F44_reg_jit);
  5050. define_cmovcc16!(0x5, instr16_0F45_mem_jit, instr16_0F45_reg_jit);
  5051. define_cmovcc16!(0x6, instr16_0F46_mem_jit, instr16_0F46_reg_jit);
  5052. define_cmovcc16!(0x7, instr16_0F47_mem_jit, instr16_0F47_reg_jit);
  5053. define_cmovcc16!(0x8, instr16_0F48_mem_jit, instr16_0F48_reg_jit);
  5054. define_cmovcc16!(0x9, instr16_0F49_mem_jit, instr16_0F49_reg_jit);
  5055. define_cmovcc16!(0xA, instr16_0F4A_mem_jit, instr16_0F4A_reg_jit);
  5056. define_cmovcc16!(0xB, instr16_0F4B_mem_jit, instr16_0F4B_reg_jit);
  5057. define_cmovcc16!(0xC, instr16_0F4C_mem_jit, instr16_0F4C_reg_jit);
  5058. define_cmovcc16!(0xD, instr16_0F4D_mem_jit, instr16_0F4D_reg_jit);
  5059. define_cmovcc16!(0xE, instr16_0F4E_mem_jit, instr16_0F4E_reg_jit);
  5060. define_cmovcc16!(0xF, instr16_0F4F_mem_jit, instr16_0F4F_reg_jit);
  5061. define_cmovcc32!(0x0, instr32_0F40_mem_jit, instr32_0F40_reg_jit);
  5062. define_cmovcc32!(0x1, instr32_0F41_mem_jit, instr32_0F41_reg_jit);
  5063. define_cmovcc32!(0x2, instr32_0F42_mem_jit, instr32_0F42_reg_jit);
  5064. define_cmovcc32!(0x3, instr32_0F43_mem_jit, instr32_0F43_reg_jit);
  5065. define_cmovcc32!(0x4, instr32_0F44_mem_jit, instr32_0F44_reg_jit);
  5066. define_cmovcc32!(0x5, instr32_0F45_mem_jit, instr32_0F45_reg_jit);
  5067. define_cmovcc32!(0x6, instr32_0F46_mem_jit, instr32_0F46_reg_jit);
  5068. define_cmovcc32!(0x7, instr32_0F47_mem_jit, instr32_0F47_reg_jit);
  5069. define_cmovcc32!(0x8, instr32_0F48_mem_jit, instr32_0F48_reg_jit);
  5070. define_cmovcc32!(0x9, instr32_0F49_mem_jit, instr32_0F49_reg_jit);
  5071. define_cmovcc32!(0xA, instr32_0F4A_mem_jit, instr32_0F4A_reg_jit);
  5072. define_cmovcc32!(0xB, instr32_0F4B_mem_jit, instr32_0F4B_reg_jit);
  5073. define_cmovcc32!(0xC, instr32_0F4C_mem_jit, instr32_0F4C_reg_jit);
  5074. define_cmovcc32!(0xD, instr32_0F4D_mem_jit, instr32_0F4D_reg_jit);
  5075. define_cmovcc32!(0xE, instr32_0F4E_mem_jit, instr32_0F4E_reg_jit);
  5076. define_cmovcc32!(0xF, instr32_0F4F_mem_jit, instr32_0F4F_reg_jit);
  5077. macro_rules! define_setcc(
  5078. ($cond:expr, $name_mem:ident, $name_reg:ident) => (
  5079. pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, _r: u32) {
  5080. codegen::gen_modrm_resolve_with_local(ctx, modrm_byte, &|ctx, addr| {
  5081. codegen::gen_condition_fn(ctx, $cond);
  5082. ctx.builder.const_i32(0);
  5083. ctx.builder.ne_i32();
  5084. let value_local = ctx.builder.set_new_local();
  5085. codegen::gen_safe_write8(ctx, &addr, &value_local);
  5086. ctx.builder.free_local(value_local);
  5087. });
  5088. }
  5089. pub fn $name_reg(ctx: &mut JitContext, r1: u32, _r2: u32) {
  5090. codegen::gen_condition_fn(ctx, $cond);
  5091. ctx.builder.const_i32(0);
  5092. ctx.builder.ne_i32();
  5093. codegen::gen_set_reg8_unmasked(ctx, r1);
  5094. }
  5095. );
  5096. );
  5097. define_setcc!(0x0, instr_0F90_mem_jit, instr_0F90_reg_jit);
  5098. define_setcc!(0x1, instr_0F91_mem_jit, instr_0F91_reg_jit);
  5099. define_setcc!(0x2, instr_0F92_mem_jit, instr_0F92_reg_jit);
  5100. define_setcc!(0x3, instr_0F93_mem_jit, instr_0F93_reg_jit);
  5101. define_setcc!(0x4, instr_0F94_mem_jit, instr_0F94_reg_jit);
  5102. define_setcc!(0x5, instr_0F95_mem_jit, instr_0F95_reg_jit);
  5103. define_setcc!(0x6, instr_0F96_mem_jit, instr_0F96_reg_jit);
  5104. define_setcc!(0x7, instr_0F97_mem_jit, instr_0F97_reg_jit);
  5105. define_setcc!(0x8, instr_0F98_mem_jit, instr_0F98_reg_jit);
  5106. define_setcc!(0x9, instr_0F99_mem_jit, instr_0F99_reg_jit);
  5107. define_setcc!(0xA, instr_0F9A_mem_jit, instr_0F9A_reg_jit);
  5108. define_setcc!(0xB, instr_0F9B_mem_jit, instr_0F9B_reg_jit);
  5109. define_setcc!(0xC, instr_0F9C_mem_jit, instr_0F9C_reg_jit);
  5110. define_setcc!(0xD, instr_0F9D_mem_jit, instr_0F9D_reg_jit);
  5111. define_setcc!(0xE, instr_0F9E_mem_jit, instr_0F9E_reg_jit);
  5112. define_setcc!(0xF, instr_0F9F_mem_jit, instr_0F9F_reg_jit);
  5113. pub fn instr_0F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5114. let dest = global_pointers::get_reg_xmm_offset(r);
  5115. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5116. }
  5117. pub fn instr_0F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5118. pub fn instr_660F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5119. let dest = global_pointers::get_reg_xmm_offset(r);
  5120. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5121. }
  5122. pub fn instr_660F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5123. pub fn instr_F20F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5124. instr_F30F7E_mem_jit(ctx, modrm_byte, r)
  5125. }
  5126. pub fn instr_F20F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5127. ctx.builder.const_i32(r1 as i32);
  5128. ctx.builder.const_i32(r2 as i32);
  5129. ctx.builder.call_fn2("instr_F20F10_reg");
  5130. }
  5131. pub fn instr_F30F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5132. instr_660F6E_mem_jit(ctx, modrm_byte, r)
  5133. }
  5134. pub fn instr_F30F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5135. ctx.builder.const_i32(0);
  5136. ctx.builder
  5137. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r1));
  5138. ctx.builder
  5139. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2));
  5140. }
  5141. pub fn instr_0F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5142. instr_0F29_mem_jit(ctx, modrm_byte, r)
  5143. }
  5144. pub fn instr_0F11_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  5145. pub fn instr_660F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5146. instr_660F29_mem_jit(ctx, modrm_byte, r)
  5147. }
  5148. pub fn instr_660F11_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  5149. pub fn instr_F20F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5150. instr_660FD6_mem_jit(ctx, modrm_byte, r)
  5151. }
  5152. pub fn instr_F20F11_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5153. ctx.builder.const_i32(r1 as i32);
  5154. ctx.builder.const_i32(r2 as i32);
  5155. ctx.builder.call_fn2("instr_F20F11_reg");
  5156. }
  5157. pub fn instr_F30F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5158. instr_660F7E_mem_jit(ctx, modrm_byte, r)
  5159. }
  5160. pub fn instr_F30F11_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5161. ctx.builder.const_i32(0);
  5162. ctx.builder
  5163. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r2));
  5164. ctx.builder
  5165. .store_aligned_i32(global_pointers::get_reg_xmm_offset(r1));
  5166. }
  5167. pub fn instr_0F12_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5168. ctx.builder
  5169. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
  5170. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5171. ctx.builder.store_aligned_i64(0);
  5172. }
  5173. pub fn instr_0F12_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5174. ctx.builder
  5175. .const_i32(global_pointers::get_reg_xmm_offset(r2) as i32);
  5176. ctx.builder
  5177. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32 + 8);
  5178. ctx.builder.load_aligned_i64(0);
  5179. ctx.builder.store_aligned_i64(0);
  5180. }
  5181. pub fn instr_660F12_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5182. ctx.builder
  5183. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
  5184. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5185. ctx.builder.store_aligned_i64(0);
  5186. }
  5187. pub fn instr_660F12_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5188. codegen::gen_trigger_ud(ctx);
  5189. }
  5190. pub fn instr_0F13_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5191. instr_660FD6_mem_jit(ctx, modrm_byte, r)
  5192. }
  5193. pub fn instr_0F13_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5194. codegen::gen_trigger_ud(ctx);
  5195. }
  5196. pub fn instr_660F13_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5197. instr_660FD6_mem_jit(ctx, modrm_byte, r)
  5198. }
  5199. pub fn instr_660F13_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5200. codegen::gen_trigger_ud(ctx);
  5201. }
  5202. pub fn instr_0F14_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5203. sse_read64_xmm_mem(ctx, "instr_0F14", modrm_byte, r);
  5204. }
  5205. pub fn instr_0F14_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5206. sse_read64_xmm_xmm(ctx, "instr_0F14", r1, r2);
  5207. }
  5208. pub fn instr_660F14_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5209. sse_read64_xmm_mem(ctx, "instr_660F14", modrm_byte, r);
  5210. }
  5211. pub fn instr_660F14_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5212. sse_read64_xmm_xmm(ctx, "instr_660F14", r1, r2);
  5213. }
  5214. pub fn instr_0F15_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5215. sse_read128_xmm_mem(ctx, "instr_0F15", modrm_byte, r);
  5216. }
  5217. pub fn instr_0F15_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5218. sse_read128_xmm_xmm(ctx, "instr_0F15", r1, r2);
  5219. }
  5220. pub fn instr_660F15_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5221. sse_read128_xmm_mem(ctx, "instr_660F15", modrm_byte, r);
  5222. }
  5223. pub fn instr_660F15_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5224. sse_read128_xmm_xmm(ctx, "instr_660F15", r1, r2);
  5225. }
  5226. pub fn instr_0F16_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5227. sse_read64_xmm_mem(ctx, "instr_0F16", modrm_byte, r);
  5228. }
  5229. pub fn instr_0F16_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5230. sse_read64_xmm_xmm(ctx, "instr_0F16", r1, r2);
  5231. }
  5232. pub fn instr_660F16_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5233. sse_read64_xmm_mem(ctx, "instr_0F16", modrm_byte, r);
  5234. }
  5235. pub fn instr_660F16_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5236. codegen::gen_trigger_ud(ctx);
  5237. }
  5238. pub fn instr_0F17_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5239. codegen::gen_modrm_resolve(ctx, modrm_byte);
  5240. let address_local = ctx.builder.set_new_local();
  5241. ctx.builder
  5242. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
  5243. ctx.builder.load_aligned_i64(8);
  5244. let value_local = ctx.builder.set_new_local_i64();
  5245. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  5246. ctx.builder.free_local(address_local);
  5247. ctx.builder.free_local_i64(value_local);
  5248. }
  5249. pub fn instr_0F17_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5250. codegen::gen_trigger_ud(ctx);
  5251. }
  5252. pub fn instr_660F17_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5253. instr_0F17_mem_jit(ctx, modrm_byte, r);
  5254. }
  5255. pub fn instr_660F17_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5256. codegen::gen_trigger_ud(ctx);
  5257. }
  5258. pub fn instr_0F28_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5259. let dest = global_pointers::get_reg_xmm_offset(r);
  5260. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5261. }
  5262. pub fn instr_0F28_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5263. pub fn instr_660F28_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5264. let dest = global_pointers::get_reg_xmm_offset(r);
  5265. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5266. }
  5267. pub fn instr_660F28_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5268. pub fn instr_0F29_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5269. // XXX: Aligned write or #gp
  5270. codegen::gen_modrm_resolve(ctx, modrm_byte);
  5271. let address_local = ctx.builder.set_new_local();
  5272. ctx.builder
  5273. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
  5274. ctx.builder.load_aligned_i64(0);
  5275. let value_local_low = ctx.builder.set_new_local_i64();
  5276. ctx.builder
  5277. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32 + 8);
  5278. ctx.builder.load_aligned_i64(0);
  5279. let value_local_high = ctx.builder.set_new_local_i64();
  5280. codegen::gen_safe_write128(ctx, &address_local, &value_local_low, &value_local_high);
  5281. ctx.builder.free_local(address_local);
  5282. ctx.builder.free_local_i64(value_local_low);
  5283. ctx.builder.free_local_i64(value_local_high);
  5284. }
  5285. pub fn instr_0F29_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  5286. pub fn instr_660F29_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5287. instr_0F29_mem_jit(ctx, modrm_byte, r);
  5288. }
  5289. pub fn instr_660F29_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  5290. pub fn instr_0F2A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5291. mmx_read64_mm_mem(ctx, "instr_0F2A", modrm_byte, r);
  5292. }
  5293. pub fn instr_0F2A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5294. mmx_read64_mm_mm(ctx, "instr_0F2A", r1, r2);
  5295. }
  5296. pub fn instr_660F2A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5297. mmx_read64_mm_mem(ctx, "instr_660F2A", modrm_byte, r);
  5298. }
  5299. pub fn instr_660F2A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5300. mmx_read64_mm_mm(ctx, "instr_660F2A", r1, r2);
  5301. }
  5302. pub fn instr_F20F2A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5303. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5304. ctx.builder.const_i32(r as i32);
  5305. ctx.builder.call_fn2("instr_F20F2A")
  5306. }
  5307. pub fn instr_F20F2A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5308. codegen::gen_get_reg32(ctx, r1);
  5309. ctx.builder.const_i32(r2 as i32);
  5310. ctx.builder.call_fn2("instr_F20F2A")
  5311. }
  5312. pub fn instr_F30F2A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5313. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5314. ctx.builder.const_i32(r as i32);
  5315. ctx.builder.call_fn2("instr_F30F2A")
  5316. }
  5317. pub fn instr_F30F2A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5318. codegen::gen_get_reg32(ctx, r1);
  5319. ctx.builder.const_i32(r2 as i32);
  5320. ctx.builder.call_fn2("instr_F30F2A")
  5321. }
  5322. pub fn instr_0F2B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5323. instr_0F29_mem_jit(ctx, modrm_byte, r)
  5324. }
  5325. pub fn instr_0F2B_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5326. codegen::gen_trigger_ud(ctx);
  5327. }
  5328. pub fn instr_660F2B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5329. instr_0F29_mem_jit(ctx, modrm_byte, r)
  5330. }
  5331. pub fn instr_660F2B_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  5332. codegen::gen_trigger_ud(ctx);
  5333. }
  5334. pub fn instr_F20F2C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5335. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5336. ctx.builder.reinterpret_i64_as_f64();
  5337. ctx.builder
  5338. .call_fn1_f64_ret("sse_convert_with_truncation_f64_to_i32");
  5339. codegen::gen_set_reg32(ctx, r);
  5340. }
  5341. pub fn instr_F20F2C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5342. ctx.builder
  5343. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  5344. ctx.builder.load_aligned_f64(0);
  5345. ctx.builder
  5346. .call_fn1_f64_ret("sse_convert_with_truncation_f64_to_i32");
  5347. codegen::gen_set_reg32(ctx, r2);
  5348. }
  5349. pub fn instr_F30F2C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5350. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5351. ctx.builder.reinterpret_i32_as_f32();
  5352. ctx.builder
  5353. .call_fn1_f32_ret("sse_convert_with_truncation_f32_to_i32");
  5354. codegen::gen_set_reg32(ctx, r);
  5355. }
  5356. pub fn instr_F30F2C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5357. ctx.builder
  5358. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  5359. ctx.builder.load_aligned_f32(0);
  5360. ctx.builder
  5361. .call_fn1_f32_ret("sse_convert_with_truncation_f32_to_i32");
  5362. codegen::gen_set_reg32(ctx, r2);
  5363. }
  5364. pub fn instr_F20F2D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5365. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5366. ctx.builder.reinterpret_i64_as_f64();
  5367. ctx.builder.call_fn1_f64_ret("sse_convert_f64_to_i32");
  5368. codegen::gen_set_reg32(ctx, r);
  5369. }
  5370. pub fn instr_F20F2D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5371. ctx.builder
  5372. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  5373. ctx.builder.load_aligned_f64(0);
  5374. ctx.builder.call_fn1_f64_ret("sse_convert_f64_to_i32");
  5375. codegen::gen_set_reg32(ctx, r2);
  5376. }
  5377. pub fn instr_F30F2D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5378. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5379. ctx.builder.reinterpret_i32_as_f32();
  5380. ctx.builder.call_fn1_f32_ret("sse_convert_f32_to_i32");
  5381. codegen::gen_set_reg32(ctx, r);
  5382. }
  5383. pub fn instr_F30F2D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5384. ctx.builder
  5385. .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
  5386. ctx.builder.load_aligned_f32(0);
  5387. ctx.builder.call_fn1_f32_ret("sse_convert_f32_to_i32");
  5388. codegen::gen_set_reg32(ctx, r2);
  5389. }
  5390. pub fn instr_0F2E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5391. sse_read_f32_xmm_mem(ctx, "instr_0F2E", modrm_byte, r);
  5392. }
  5393. pub fn instr_0F2E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5394. sse_read_f32_xmm_xmm(ctx, "instr_0F2E", r1, r2);
  5395. }
  5396. pub fn instr_660F2E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5397. sse_read64_xmm_mem(ctx, "instr_660F2E", modrm_byte, r);
  5398. }
  5399. pub fn instr_660F2E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5400. sse_read64_xmm_xmm(ctx, "instr_660F2E", r1, r2);
  5401. }
  5402. pub fn instr_0F2F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5403. sse_read_f32_xmm_mem(ctx, "instr_0F2F", modrm_byte, r);
  5404. }
  5405. pub fn instr_0F2F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5406. sse_read_f32_xmm_xmm(ctx, "instr_0F2F", r1, r2);
  5407. }
  5408. pub fn instr_660F2F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5409. sse_read64_xmm_mem(ctx, "instr_660F2F", modrm_byte, r);
  5410. }
  5411. pub fn instr_660F2F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5412. sse_read64_xmm_xmm(ctx, "instr_660F2F", r1, r2);
  5413. }
  5414. pub fn instr_0F51_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5415. sse_read128_xmm_mem(ctx, "instr_0F51", modrm_byte, r);
  5416. }
  5417. pub fn instr_0F51_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5418. sse_read128_xmm_xmm(ctx, "instr_0F51", r1, r2);
  5419. }
  5420. pub fn instr_660F51_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5421. sse_read128_xmm_mem(ctx, "instr_660F51", modrm_byte, r);
  5422. }
  5423. pub fn instr_660F51_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5424. sse_read128_xmm_xmm(ctx, "instr_660F51", r1, r2);
  5425. }
  5426. pub fn instr_F20F51_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5427. sse_read64_xmm_mem(ctx, "instr_F20F51", modrm_byte, r);
  5428. }
  5429. pub fn instr_F20F51_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5430. sse_read64_xmm_xmm(ctx, "instr_F20F51", r1, r2);
  5431. }
  5432. pub fn instr_F30F51_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5433. sse_read_f32_xmm_mem(ctx, "instr_F30F51", modrm_byte, r);
  5434. }
  5435. pub fn instr_F30F51_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5436. sse_read_f32_xmm_xmm(ctx, "instr_F30F51", r1, r2);
  5437. }
  5438. pub fn instr_0F52_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5439. sse_read128_xmm_mem(ctx, "instr_0F52", modrm_byte, r);
  5440. }
  5441. pub fn instr_0F52_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5442. sse_read128_xmm_xmm(ctx, "instr_0F52", r1, r2);
  5443. }
  5444. pub fn instr_F30F52_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5445. sse_read_f32_xmm_mem(ctx, "instr_F30F52", modrm_byte, r);
  5446. }
  5447. pub fn instr_F30F52_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5448. sse_read_f32_xmm_xmm(ctx, "instr_F30F52", r1, r2);
  5449. }
  5450. pub fn instr_0F53_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5451. sse_read128_xmm_mem(ctx, "instr_0F53", modrm_byte, r);
  5452. }
  5453. pub fn instr_0F53_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5454. sse_read128_xmm_xmm(ctx, "instr_0F53", r1, r2);
  5455. }
  5456. pub fn instr_F30F53_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5457. sse_read_f32_xmm_mem(ctx, "instr_F30F53", modrm_byte, r);
  5458. }
  5459. pub fn instr_F30F53_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5460. sse_read_f32_xmm_xmm(ctx, "instr_F30F53", r1, r2);
  5461. }
  5462. pub fn instr_0F54_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5463. sse_read128_xmm_mem(ctx, "instr_0F54", modrm_byte, r);
  5464. }
  5465. pub fn instr_0F54_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5466. sse_read128_xmm_xmm(ctx, "instr_0F54", r1, r2);
  5467. }
  5468. pub fn instr_660F54_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5469. sse_read128_xmm_mem(ctx, "instr_660F54", modrm_byte, r);
  5470. }
  5471. pub fn instr_660F54_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5472. sse_read128_xmm_xmm(ctx, "instr_660F54", r1, r2);
  5473. }
  5474. pub fn instr_0F55_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5475. sse_read128_xmm_mem(ctx, "instr_0F55", modrm_byte, r);
  5476. }
  5477. pub fn instr_0F55_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5478. sse_read128_xmm_xmm(ctx, "instr_0F55", r1, r2);
  5479. }
  5480. pub fn instr_660F55_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5481. sse_read128_xmm_mem(ctx, "instr_660F55", modrm_byte, r);
  5482. }
  5483. pub fn instr_660F55_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5484. sse_read128_xmm_xmm(ctx, "instr_660F55", r1, r2);
  5485. }
  5486. pub fn instr_0F56_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5487. sse_read128_xmm_mem(ctx, "instr_0F56", modrm_byte, r);
  5488. }
  5489. pub fn instr_0F56_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5490. sse_read128_xmm_xmm(ctx, "instr_0F56", r1, r2);
  5491. }
  5492. pub fn instr_660F56_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5493. sse_read128_xmm_mem(ctx, "instr_660F56", modrm_byte, r);
  5494. }
  5495. pub fn instr_660F56_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5496. sse_read128_xmm_xmm(ctx, "instr_660F56", r1, r2);
  5497. }
  5498. pub fn instr_0F57_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5499. sse_read128_xmm_mem(ctx, "instr_0F57", modrm_byte, r);
  5500. }
  5501. pub fn instr_0F57_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5502. sse_read128_xmm_xmm(ctx, "instr_0F57", r1, r2);
  5503. }
  5504. pub fn instr_660F57_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5505. sse_read128_xmm_mem(ctx, "instr_660F57", modrm_byte, r);
  5506. }
  5507. pub fn instr_660F57_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5508. sse_read128_xmm_xmm(ctx, "instr_660F57", r1, r2);
  5509. }
  5510. pub fn instr_0F58_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5511. sse_read128_xmm_mem(ctx, "instr_0F58", modrm_byte, r);
  5512. }
  5513. pub fn instr_0F58_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5514. sse_read128_xmm_xmm(ctx, "instr_0F58", r1, r2);
  5515. }
  5516. pub fn instr_660F58_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5517. sse_read128_xmm_mem(ctx, "instr_660F58", modrm_byte, r);
  5518. }
  5519. pub fn instr_660F58_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5520. sse_read128_xmm_xmm(ctx, "instr_660F58", r1, r2);
  5521. }
  5522. pub fn instr_F20F58_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5523. sse_read64_xmm_mem(ctx, "instr_F20F58", modrm_byte, r);
  5524. }
  5525. pub fn instr_F20F58_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5526. sse_read64_xmm_xmm(ctx, "instr_F20F58", r1, r2);
  5527. }
  5528. pub fn instr_F30F58_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5529. sse_read_f32_xmm_mem(ctx, "instr_F30F58", modrm_byte, r);
  5530. }
  5531. pub fn instr_F30F58_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5532. sse_read_f32_xmm_xmm(ctx, "instr_F30F58", r1, r2);
  5533. }
  5534. pub fn instr_0F59_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5535. sse_read128_xmm_mem(ctx, "instr_0F59", modrm_byte, r);
  5536. }
  5537. pub fn instr_0F59_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5538. sse_read128_xmm_xmm(ctx, "instr_0F59", r1, r2);
  5539. }
  5540. pub fn instr_660F59_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5541. sse_read128_xmm_mem(ctx, "instr_660F59", modrm_byte, r);
  5542. }
  5543. pub fn instr_660F59_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5544. sse_read128_xmm_xmm(ctx, "instr_660F59", r1, r2);
  5545. }
  5546. pub fn instr_F20F59_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5547. sse_read64_xmm_mem(ctx, "instr_F20F59", modrm_byte, r);
  5548. }
  5549. pub fn instr_F20F59_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5550. sse_read64_xmm_xmm(ctx, "instr_F20F59", r1, r2);
  5551. }
  5552. pub fn instr_F30F59_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5553. sse_read_f32_xmm_mem(ctx, "instr_F30F59", modrm_byte, r);
  5554. }
  5555. pub fn instr_F30F59_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5556. sse_read_f32_xmm_xmm(ctx, "instr_F30F59", r1, r2);
  5557. }
  5558. pub fn instr_0F5A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5559. sse_read64_xmm_mem(ctx, "instr_0F5A", modrm_byte, r);
  5560. }
  5561. pub fn instr_0F5A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5562. sse_read64_xmm_xmm(ctx, "instr_0F5A", r1, r2);
  5563. }
  5564. pub fn instr_660F5A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5565. sse_read128_xmm_mem(ctx, "instr_660F5A", modrm_byte, r);
  5566. }
  5567. pub fn instr_660F5A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5568. sse_read128_xmm_xmm(ctx, "instr_660F5A", r1, r2);
  5569. }
  5570. pub fn instr_F20F5A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5571. sse_read64_xmm_mem(ctx, "instr_F20F5A", modrm_byte, r);
  5572. }
  5573. pub fn instr_F20F5A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5574. sse_read64_xmm_xmm(ctx, "instr_F20F5A", r1, r2);
  5575. }
  5576. pub fn instr_F30F5A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5577. sse_read_f32_xmm_mem(ctx, "instr_F30F5A", modrm_byte, r);
  5578. }
  5579. pub fn instr_F30F5A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5580. sse_read_f32_xmm_xmm(ctx, "instr_F30F5A", r1, r2);
  5581. }
  5582. pub fn instr_0F5B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5583. sse_read128_xmm_mem(ctx, "instr_0F5B", modrm_byte, r);
  5584. }
  5585. pub fn instr_0F5B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5586. sse_read128_xmm_xmm(ctx, "instr_0F5B", r1, r2);
  5587. }
  5588. pub fn instr_660F5B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5589. sse_read128_xmm_mem(ctx, "instr_660F5B", modrm_byte, r);
  5590. }
  5591. pub fn instr_660F5B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5592. sse_read128_xmm_xmm(ctx, "instr_660F5B", r1, r2);
  5593. }
  5594. pub fn instr_F30F5B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5595. sse_read128_xmm_mem(ctx, "instr_F30F5B", modrm_byte, r);
  5596. }
  5597. pub fn instr_F30F5B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5598. sse_read128_xmm_xmm(ctx, "instr_F30F5B", r1, r2);
  5599. }
  5600. pub fn instr_0F5C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5601. sse_read128_xmm_mem(ctx, "instr_0F5C", modrm_byte, r);
  5602. }
  5603. pub fn instr_0F5C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5604. sse_read128_xmm_xmm(ctx, "instr_0F5C", r1, r2);
  5605. }
  5606. pub fn instr_660F5C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5607. sse_read128_xmm_mem(ctx, "instr_660F5C", modrm_byte, r);
  5608. }
  5609. pub fn instr_660F5C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5610. sse_read128_xmm_xmm(ctx, "instr_660F5C", r1, r2);
  5611. }
  5612. pub fn instr_F20F5C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5613. sse_read64_xmm_mem(ctx, "instr_F20F5C", modrm_byte, r);
  5614. }
  5615. pub fn instr_F20F5C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5616. sse_read64_xmm_xmm(ctx, "instr_F20F5C", r1, r2);
  5617. }
  5618. pub fn instr_F30F5C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5619. sse_read_f32_xmm_mem(ctx, "instr_F30F5C", modrm_byte, r);
  5620. }
  5621. pub fn instr_F30F5C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5622. sse_read_f32_xmm_xmm(ctx, "instr_F30F5C", r1, r2);
  5623. }
  5624. pub fn instr_0F5D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5625. sse_read128_xmm_mem(ctx, "instr_0F5D", modrm_byte, r);
  5626. }
  5627. pub fn instr_0F5D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5628. sse_read128_xmm_xmm(ctx, "instr_0F5D", r1, r2);
  5629. }
  5630. pub fn instr_660F5D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5631. sse_read128_xmm_mem(ctx, "instr_660F5D", modrm_byte, r);
  5632. }
  5633. pub fn instr_660F5D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5634. sse_read128_xmm_xmm(ctx, "instr_660F5D", r1, r2);
  5635. }
  5636. pub fn instr_F20F5D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5637. sse_read64_xmm_mem(ctx, "instr_F20F5D", modrm_byte, r);
  5638. }
  5639. pub fn instr_F20F5D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5640. sse_read64_xmm_xmm(ctx, "instr_F20F5D", r1, r2);
  5641. }
  5642. pub fn instr_F30F5D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5643. sse_read_f32_xmm_mem(ctx, "instr_F30F5D", modrm_byte, r);
  5644. }
  5645. pub fn instr_F30F5D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5646. sse_read_f32_xmm_xmm(ctx, "instr_F30F5D", r1, r2);
  5647. }
  5648. pub fn instr_0F5E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5649. sse_read128_xmm_mem(ctx, "instr_0F5E", modrm_byte, r);
  5650. }
  5651. pub fn instr_0F5E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5652. sse_read128_xmm_xmm(ctx, "instr_0F5E", r1, r2);
  5653. }
  5654. pub fn instr_660F5E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5655. sse_read128_xmm_mem(ctx, "instr_660F5E", modrm_byte, r);
  5656. }
  5657. pub fn instr_660F5E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5658. sse_read128_xmm_xmm(ctx, "instr_660F5E", r1, r2);
  5659. }
  5660. pub fn instr_F20F5E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5661. sse_read64_xmm_mem(ctx, "instr_F20F5E", modrm_byte, r);
  5662. }
  5663. pub fn instr_F20F5E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5664. sse_read64_xmm_xmm(ctx, "instr_F20F5E", r1, r2);
  5665. }
  5666. pub fn instr_F30F5E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5667. sse_read_f32_xmm_mem(ctx, "instr_F30F5E", modrm_byte, r);
  5668. }
  5669. pub fn instr_F30F5E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5670. sse_read_f32_xmm_xmm(ctx, "instr_F30F5E", r1, r2);
  5671. }
  5672. pub fn instr_0F5F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5673. sse_read128_xmm_mem(ctx, "instr_0F5F", modrm_byte, r);
  5674. }
  5675. pub fn instr_0F5F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5676. sse_read128_xmm_xmm(ctx, "instr_0F5F", r1, r2);
  5677. }
  5678. pub fn instr_660F5F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5679. sse_read128_xmm_mem(ctx, "instr_660F5F", modrm_byte, r);
  5680. }
  5681. pub fn instr_660F5F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5682. sse_read128_xmm_xmm(ctx, "instr_660F5F", r1, r2);
  5683. }
  5684. pub fn instr_F20F5F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5685. sse_read64_xmm_mem(ctx, "instr_F20F5F", modrm_byte, r);
  5686. }
  5687. pub fn instr_F20F5F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5688. sse_read64_xmm_xmm(ctx, "instr_F20F5F", r1, r2);
  5689. }
  5690. pub fn instr_F30F5F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5691. sse_read_f32_xmm_mem(ctx, "instr_F30F5F", modrm_byte, r);
  5692. }
  5693. pub fn instr_F30F5F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5694. sse_read_f32_xmm_xmm(ctx, "instr_F30F5F", r1, r2);
  5695. }
  5696. pub fn instr_0F60_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5697. mmx_read64_mm_mem32(ctx, "instr_0F60", modrm_byte, r);
  5698. }
  5699. pub fn instr_0F60_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5700. mmx_read64_mm_mm32(ctx, "instr_0F60", r1, r2);
  5701. }
  5702. pub fn instr_0F61_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5703. mmx_read64_mm_mem32(ctx, "instr_0F61", modrm_byte, r);
  5704. }
  5705. pub fn instr_0F61_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5706. mmx_read64_mm_mm32(ctx, "instr_0F61", r1, r2);
  5707. }
  5708. pub fn instr_0F62_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5709. mmx_read64_mm_mem32(ctx, "instr_0F62", modrm_byte, r);
  5710. }
  5711. pub fn instr_0F62_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5712. mmx_read64_mm_mm32(ctx, "instr_0F62", r1, r2);
  5713. }
  5714. pub fn instr_0F63_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5715. mmx_read64_mm_mem(ctx, "instr_0F63", modrm_byte, r);
  5716. }
  5717. pub fn instr_0F63_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5718. mmx_read64_mm_mm(ctx, "instr_0F63", r1, r2);
  5719. }
  5720. pub fn instr_0F64_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5721. mmx_read64_mm_mem(ctx, "instr_0F64", modrm_byte, r);
  5722. }
  5723. pub fn instr_0F64_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5724. mmx_read64_mm_mm(ctx, "instr_0F64", r1, r2);
  5725. }
  5726. pub fn instr_0F65_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5727. mmx_read64_mm_mem(ctx, "instr_0F65", modrm_byte, r);
  5728. }
  5729. pub fn instr_0F65_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5730. mmx_read64_mm_mm(ctx, "instr_0F65", r1, r2);
  5731. }
  5732. pub fn instr_0F66_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5733. mmx_read64_mm_mem(ctx, "instr_0F66", modrm_byte, r);
  5734. }
  5735. pub fn instr_0F66_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5736. mmx_read64_mm_mm(ctx, "instr_0F66", r1, r2);
  5737. }
  5738. pub fn instr_0F67_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5739. mmx_read64_mm_mem(ctx, "instr_0F67", modrm_byte, r);
  5740. }
  5741. pub fn instr_0F67_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5742. mmx_read64_mm_mm(ctx, "instr_0F67", r1, r2);
  5743. }
  5744. pub fn instr_0F68_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5745. mmx_read64_mm_mem(ctx, "instr_0F68", modrm_byte, r);
  5746. }
  5747. pub fn instr_0F68_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5748. mmx_read64_mm_mm(ctx, "instr_0F68", r1, r2);
  5749. }
  5750. pub fn instr_0F69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5751. mmx_read64_mm_mem(ctx, "instr_0F69", modrm_byte, r);
  5752. }
  5753. pub fn instr_0F69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5754. mmx_read64_mm_mm(ctx, "instr_0F69", r1, r2);
  5755. }
  5756. pub fn instr_0F6A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5757. mmx_read64_mm_mem(ctx, "instr_0F6A", modrm_byte, r);
  5758. }
  5759. pub fn instr_0F6A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5760. mmx_read64_mm_mm(ctx, "instr_0F6A", r1, r2);
  5761. }
  5762. pub fn instr_0F6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5763. mmx_read64_mm_mem(ctx, "instr_0F6B", modrm_byte, r);
  5764. }
  5765. pub fn instr_0F6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5766. mmx_read64_mm_mm(ctx, "instr_0F6B", r1, r2);
  5767. }
  5768. pub fn instr_660F60_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5769. // Note: Only requires 64-bit read, but is allowed to do 128-bit read
  5770. sse_read128_xmm_mem(ctx, "instr_660F60", modrm_byte, r);
  5771. }
  5772. pub fn instr_660F60_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5773. sse_read128_xmm_xmm(ctx, "instr_660F60", r1, r2);
  5774. }
  5775. pub fn instr_660F61_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5776. // Note: Only requires 64-bit read, but is allowed to do 128-bit read
  5777. sse_read128_xmm_mem(ctx, "instr_660F61", modrm_byte, r);
  5778. }
  5779. pub fn instr_660F61_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5780. sse_read128_xmm_xmm(ctx, "instr_660F61", r1, r2);
  5781. }
  5782. pub fn instr_660F62_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5783. sse_read128_xmm_mem(ctx, "instr_660F62", modrm_byte, r);
  5784. }
  5785. pub fn instr_660F62_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5786. sse_read128_xmm_xmm(ctx, "instr_660F62", r1, r2);
  5787. }
  5788. pub fn instr_660F63_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5789. sse_read128_xmm_mem(ctx, "instr_660F63", modrm_byte, r);
  5790. }
  5791. pub fn instr_660F63_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5792. sse_read128_xmm_xmm(ctx, "instr_660F63", r1, r2);
  5793. }
  5794. pub fn instr_660F64_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5795. sse_read128_xmm_mem(ctx, "instr_660F64", modrm_byte, r);
  5796. }
  5797. pub fn instr_660F64_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5798. sse_read128_xmm_xmm(ctx, "instr_660F64", r1, r2);
  5799. }
  5800. pub fn instr_660F65_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5801. sse_read128_xmm_mem(ctx, "instr_660F65", modrm_byte, r);
  5802. }
  5803. pub fn instr_660F65_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5804. sse_read128_xmm_xmm(ctx, "instr_660F65", r1, r2);
  5805. }
  5806. pub fn instr_660F66_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5807. sse_read128_xmm_mem(ctx, "instr_660F66", modrm_byte, r);
  5808. }
  5809. pub fn instr_660F66_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5810. sse_read128_xmm_xmm(ctx, "instr_660F66", r1, r2);
  5811. }
  5812. pub fn instr_660F67_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5813. sse_read128_xmm_mem(ctx, "instr_660F67", modrm_byte, r);
  5814. }
  5815. pub fn instr_660F67_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5816. sse_read128_xmm_xmm(ctx, "instr_660F67", r1, r2);
  5817. }
  5818. pub fn instr_660F68_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5819. sse_read128_xmm_mem(ctx, "instr_660F68", modrm_byte, r);
  5820. }
  5821. pub fn instr_660F68_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5822. sse_read128_xmm_xmm(ctx, "instr_660F68", r1, r2);
  5823. }
  5824. pub fn instr_660F69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5825. sse_read128_xmm_mem(ctx, "instr_660F69", modrm_byte, r);
  5826. }
  5827. pub fn instr_660F69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5828. sse_read128_xmm_xmm(ctx, "instr_660F69", r1, r2);
  5829. }
  5830. pub fn instr_660F6A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5831. sse_read128_xmm_mem(ctx, "instr_660F6A", modrm_byte, r);
  5832. }
  5833. pub fn instr_660F6A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5834. sse_read128_xmm_xmm(ctx, "instr_660F6A", r1, r2);
  5835. }
  5836. pub fn instr_660F6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5837. sse_read128_xmm_mem(ctx, "instr_660F6B", modrm_byte, r);
  5838. }
  5839. pub fn instr_660F6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5840. sse_read128_xmm_xmm(ctx, "instr_660F6B", r1, r2);
  5841. }
  5842. pub fn instr_660F6C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5843. sse_read128_xmm_mem(ctx, "instr_660F6C", modrm_byte, r);
  5844. }
  5845. pub fn instr_660F6C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5846. sse_read128_xmm_xmm(ctx, "instr_660F6C", r1, r2);
  5847. }
  5848. pub fn instr_660F6D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5849. sse_read128_xmm_mem(ctx, "instr_660F6D", modrm_byte, r);
  5850. }
  5851. pub fn instr_660F6D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5852. sse_read128_xmm_xmm(ctx, "instr_660F6D", r1, r2);
  5853. }
  5854. pub fn instr_0F6E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5855. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5856. ctx.builder.const_i32(r as i32);
  5857. ctx.builder.call_fn2("instr_0F6E")
  5858. }
  5859. pub fn instr_0F6E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5860. codegen::gen_get_reg32(ctx, r1);
  5861. ctx.builder.const_i32(r2 as i32);
  5862. ctx.builder.call_fn2("instr_0F6E")
  5863. }
  5864. pub fn instr_660F6E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5865. codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
  5866. ctx.builder.const_i32(r as i32);
  5867. ctx.builder.call_fn2("instr_660F6E")
  5868. }
  5869. pub fn instr_660F6E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5870. codegen::gen_get_reg32(ctx, r1);
  5871. ctx.builder.const_i32(r2 as i32);
  5872. ctx.builder.call_fn2("instr_660F6E")
  5873. }
  5874. pub fn instr_0F6F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5875. // XXX: Aligned read or #gp
  5876. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5877. ctx.builder.const_i32(r as i32);
  5878. ctx.builder.call_fn2_i64_i32("instr_0F6F")
  5879. }
  5880. pub fn instr_0F6F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  5881. ctx.builder.const_i32(r1 as i32);
  5882. ctx.builder.const_i32(r2 as i32);
  5883. ctx.builder.call_fn2("instr_0F6F_reg")
  5884. }
  5885. pub fn instr_660F6F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5886. // XXX: Aligned read or #gp
  5887. let dest = global_pointers::get_reg_xmm_offset(r);
  5888. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5889. }
  5890. pub fn instr_660F6F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5891. pub fn instr_F30F6F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  5892. let dest = global_pointers::get_reg_xmm_offset(r);
  5893. codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
  5894. }
  5895. pub fn instr_F30F6F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
  5896. pub fn instr_0F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  5897. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  5898. ctx.builder.const_i32(r as i32);
  5899. ctx.builder.const_i32(imm8 as i32);
  5900. ctx.builder.call_fn3_i64_i32_i32("instr_0F70");
  5901. }
  5902. pub fn instr_0F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  5903. ctx.builder
  5904. .const_i32(global_pointers::get_reg_mmx_offset(r1) as i32);
  5905. ctx.builder.load_aligned_i64(0);
  5906. ctx.builder.const_i32(r2 as i32);
  5907. ctx.builder.const_i32(imm8 as i32);
  5908. ctx.builder.call_fn3_i64_i32_i32("instr_0F70");
  5909. }
  5910. pub fn instr_660F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  5911. sse_read128_xmm_mem_imm(ctx, "instr_660F70", modrm_byte, r, imm8)
  5912. }
  5913. pub fn instr_660F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  5914. sse_read128_xmm_xmm_imm(ctx, "instr_660F70", r1, r2, imm8)
  5915. }
  5916. pub fn instr_F20F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  5917. sse_read128_xmm_mem_imm(ctx, "instr_F20F70", modrm_byte, r, imm8)
  5918. }
  5919. pub fn instr_F20F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  5920. sse_read128_xmm_xmm_imm(ctx, "instr_F20F70", r1, r2, imm8)
  5921. }
  5922. pub fn instr_F30F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
  5923. sse_read128_xmm_mem_imm(ctx, "instr_F30F70", modrm_byte, r, imm8)
  5924. }
  5925. pub fn instr_F30F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
  5926. sse_read128_xmm_xmm_imm(ctx, "instr_F30F70", r1, r2, imm8)
  5927. }
  5928. pub fn instr_0F71_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  5929. codegen::gen_trigger_ud(ctx);
  5930. }
  5931. pub fn instr_0F71_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  5932. ctx.builder.const_i32(r as i32);
  5933. ctx.builder.const_i32(imm8 as i32);
  5934. ctx.builder.call_fn2("instr_0F71_2_reg");
  5935. }
  5936. pub fn instr_0F71_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  5937. codegen::gen_trigger_ud(ctx);
  5938. }
  5939. pub fn instr_0F71_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  5940. ctx.builder.const_i32(r as i32);
  5941. ctx.builder.const_i32(imm8 as i32);
  5942. ctx.builder.call_fn2("instr_0F71_4_reg");
  5943. }
  5944. pub fn instr_0F71_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  5945. codegen::gen_trigger_ud(ctx);
  5946. }
  5947. pub fn instr_0F71_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  5948. ctx.builder.const_i32(r as i32);
  5949. ctx.builder.const_i32(imm8 as i32);
  5950. ctx.builder.call_fn2("instr_0F71_6_reg");
  5951. }
  5952. pub fn instr_0F72_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  5953. codegen::gen_trigger_ud(ctx);
  5954. }
  5955. pub fn instr_0F72_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  5956. ctx.builder.const_i32(r as i32);
  5957. ctx.builder.const_i32(imm8 as i32);
  5958. ctx.builder.call_fn2("instr_0F72_2_reg");
  5959. }
  5960. pub fn instr_0F72_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  5961. codegen::gen_trigger_ud(ctx);
  5962. }
  5963. pub fn instr_0F72_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  5964. ctx.builder.const_i32(r as i32);
  5965. ctx.builder.const_i32(imm8 as i32);
  5966. ctx.builder.call_fn2("instr_0F72_4_reg");
  5967. }
  5968. pub fn instr_0F72_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  5969. codegen::gen_trigger_ud(ctx);
  5970. }
  5971. pub fn instr_0F72_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  5972. ctx.builder.const_i32(r as i32);
  5973. ctx.builder.const_i32(imm8 as i32);
  5974. ctx.builder.call_fn2("instr_0F72_6_reg");
  5975. }
  5976. pub fn instr_0F73_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  5977. codegen::gen_trigger_ud(ctx);
  5978. }
  5979. pub fn instr_0F73_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  5980. ctx.builder.const_i32(r as i32);
  5981. ctx.builder.const_i32(imm8 as i32);
  5982. ctx.builder.call_fn2("instr_0F73_2_reg");
  5983. }
  5984. pub fn instr_0F73_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  5985. codegen::gen_trigger_ud(ctx);
  5986. }
  5987. pub fn instr_0F73_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  5988. ctx.builder.const_i32(r as i32);
  5989. ctx.builder.const_i32(imm8 as i32);
  5990. ctx.builder.call_fn2("instr_0F73_6_reg");
  5991. }
  5992. pub fn instr_660F71_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  5993. codegen::gen_trigger_ud(ctx);
  5994. }
  5995. pub fn instr_660F71_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  5996. ctx.builder.const_i32(r as i32);
  5997. ctx.builder.const_i32(imm8 as i32);
  5998. ctx.builder.call_fn2("instr_660F71_2_reg");
  5999. }
  6000. pub fn instr_660F71_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6001. codegen::gen_trigger_ud(ctx);
  6002. }
  6003. pub fn instr_660F71_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6004. ctx.builder.const_i32(r as i32);
  6005. ctx.builder.const_i32(imm8 as i32);
  6006. ctx.builder.call_fn2("instr_660F71_4_reg");
  6007. }
  6008. pub fn instr_660F71_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6009. codegen::gen_trigger_ud(ctx);
  6010. }
  6011. pub fn instr_660F71_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6012. ctx.builder.const_i32(r as i32);
  6013. ctx.builder.const_i32(imm8 as i32);
  6014. ctx.builder.call_fn2("instr_660F71_6_reg");
  6015. }
  6016. pub fn instr_660F72_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6017. codegen::gen_trigger_ud(ctx);
  6018. }
  6019. pub fn instr_660F72_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6020. ctx.builder.const_i32(r as i32);
  6021. ctx.builder.const_i32(imm8 as i32);
  6022. ctx.builder.call_fn2("instr_660F72_2_reg");
  6023. }
  6024. pub fn instr_660F72_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6025. codegen::gen_trigger_ud(ctx);
  6026. }
  6027. pub fn instr_660F72_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6028. ctx.builder.const_i32(r as i32);
  6029. ctx.builder.const_i32(imm8 as i32);
  6030. ctx.builder.call_fn2("instr_660F72_4_reg");
  6031. }
  6032. pub fn instr_660F72_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6033. codegen::gen_trigger_ud(ctx);
  6034. }
  6035. pub fn instr_660F72_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6036. ctx.builder.const_i32(r as i32);
  6037. ctx.builder.const_i32(imm8 as i32);
  6038. ctx.builder.call_fn2("instr_660F72_6_reg");
  6039. }
  6040. pub fn instr_660F73_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6041. codegen::gen_trigger_ud(ctx);
  6042. }
  6043. pub fn instr_660F73_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6044. ctx.builder.const_i32(r as i32);
  6045. ctx.builder.const_i32(imm8 as i32);
  6046. ctx.builder.call_fn2("instr_660F73_2_reg");
  6047. }
  6048. pub fn instr_660F73_3_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6049. codegen::gen_trigger_ud(ctx);
  6050. }
  6051. pub fn instr_660F73_3_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6052. ctx.builder.const_i32(r as i32);
  6053. ctx.builder.const_i32(imm8 as i32);
  6054. ctx.builder.call_fn2("instr_660F73_3_reg");
  6055. }
  6056. pub fn instr_660F73_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6057. codegen::gen_trigger_ud(ctx);
  6058. }
  6059. pub fn instr_660F73_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6060. ctx.builder.const_i32(r as i32);
  6061. ctx.builder.const_i32(imm8 as i32);
  6062. ctx.builder.call_fn2("instr_660F73_6_reg");
  6063. }
  6064. pub fn instr_660F73_7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
  6065. codegen::gen_trigger_ud(ctx);
  6066. }
  6067. pub fn instr_660F73_7_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6068. ctx.builder.const_i32(r as i32);
  6069. ctx.builder.const_i32(imm8 as i32);
  6070. ctx.builder.call_fn2("instr_660F73_7_reg");
  6071. }
  6072. pub fn instr_0F74_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6073. mmx_read64_mm_mem(ctx, "instr_0F74", modrm_byte, r);
  6074. }
  6075. pub fn instr_0F74_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6076. mmx_read64_mm_mm(ctx, "instr_0F74", r1, r2);
  6077. }
  6078. pub fn instr_0F75_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6079. mmx_read64_mm_mem(ctx, "instr_0F75", modrm_byte, r);
  6080. }
  6081. pub fn instr_0F75_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6082. mmx_read64_mm_mm(ctx, "instr_0F75", r1, r2);
  6083. }
  6084. pub fn instr_0F76_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6085. mmx_read64_mm_mem(ctx, "instr_0F76", modrm_byte, r);
  6086. }
  6087. pub fn instr_0F76_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6088. mmx_read64_mm_mm(ctx, "instr_0F76", r1, r2);
  6089. }
  6090. pub fn instr_660F74_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6091. sse_read128_xmm_mem(ctx, "instr_660F74", modrm_byte, r);
  6092. }
  6093. pub fn instr_660F74_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6094. sse_read128_xmm_xmm(ctx, "instr_660F74", r1, r2);
  6095. }
  6096. pub fn instr_660F75_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6097. sse_read128_xmm_mem(ctx, "instr_660F75", modrm_byte, r);
  6098. }
  6099. pub fn instr_660F75_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6100. sse_read128_xmm_xmm(ctx, "instr_660F75", r1, r2);
  6101. }
  6102. pub fn instr_660F76_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6103. sse_read128_xmm_mem(ctx, "instr_660F76", modrm_byte, r);
  6104. }
  6105. pub fn instr_660F76_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6106. sse_read128_xmm_xmm(ctx, "instr_660F76", r1, r2);
  6107. }
  6108. pub fn instr_0F7E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6109. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6110. let address_local = ctx.builder.set_new_local();
  6111. ctx.builder.const_i32(r as i32);
  6112. ctx.builder.call_fn1_ret("instr_0F7E");
  6113. let value_local = ctx.builder.set_new_local();
  6114. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  6115. ctx.builder.free_local(address_local);
  6116. ctx.builder.free_local(value_local);
  6117. }
  6118. pub fn instr_0F7E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6119. ctx.builder.const_i32(r2 as i32);
  6120. ctx.builder.call_fn1_ret("instr_0F7E");
  6121. codegen::gen_set_reg32(ctx, r1);
  6122. }
  6123. pub fn instr_660F7E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6124. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6125. let address_local = ctx.builder.set_new_local();
  6126. ctx.builder
  6127. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r));
  6128. let value_local = ctx.builder.set_new_local();
  6129. codegen::gen_safe_write32(ctx, &address_local, &value_local);
  6130. ctx.builder.free_local(address_local);
  6131. ctx.builder.free_local(value_local);
  6132. }
  6133. pub fn instr_660F7E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6134. ctx.builder
  6135. .load_fixed_i32(global_pointers::get_reg_xmm_offset(r2));
  6136. codegen::gen_set_reg32(ctx, r1);
  6137. }
  6138. pub fn instr_0F7F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6139. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6140. let address_local = ctx.builder.set_new_local();
  6141. ctx.builder.const_i32(r as i32);
  6142. ctx.builder.call_fn1_ret_i64("instr_0F7F");
  6143. let value_local = ctx.builder.set_new_local_i64();
  6144. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  6145. ctx.builder.free_local(address_local);
  6146. ctx.builder.free_local_i64(value_local);
  6147. }
  6148. pub fn instr_0F7F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6149. ctx.builder.const_i32(r1 as i32);
  6150. ctx.builder.const_i32(r2 as i32);
  6151. ctx.builder.call_fn2("instr_0F7F_reg")
  6152. }
  6153. pub fn instr_F30F7E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6154. ctx.builder
  6155. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
  6156. codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
  6157. ctx.builder.store_aligned_i64(0);
  6158. ctx.builder
  6159. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32 + 8);
  6160. ctx.builder.const_i64(0);
  6161. ctx.builder.store_aligned_i64(0);
  6162. }
  6163. pub fn instr_F30F7E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6164. ctx.builder.const_i32(r1 as i32);
  6165. ctx.builder.const_i32(r2 as i32);
  6166. ctx.builder.call_fn2("instr_F30F7E_reg");
  6167. }
  6168. pub fn instr_660F7F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6169. instr_0F29_mem_jit(ctx, modrm_byte, r);
  6170. }
  6171. pub fn instr_660F7F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  6172. pub fn instr_F30F7F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6173. instr_0F29_mem_jit(ctx, modrm_byte, r);
  6174. }
  6175. pub fn instr_F30F7F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
  6176. pub fn instr16_0FA0_jit(ctx: &mut JitContext) {
  6177. codegen::gen_get_sreg(ctx, regs::FS);
  6178. let sreg = ctx.builder.set_new_local();
  6179. codegen::gen_push16(ctx, &sreg);
  6180. ctx.builder.free_local(sreg);
  6181. }
  6182. pub fn instr32_0FA0_jit(ctx: &mut JitContext) {
  6183. codegen::gen_get_sreg(ctx, regs::FS);
  6184. let sreg = ctx.builder.set_new_local();
  6185. codegen::gen_push32(ctx, &sreg);
  6186. ctx.builder.free_local(sreg);
  6187. }
  6188. pub fn instr16_0FA8_jit(ctx: &mut JitContext) {
  6189. codegen::gen_get_sreg(ctx, regs::GS);
  6190. let sreg = ctx.builder.set_new_local();
  6191. codegen::gen_push16(ctx, &sreg);
  6192. ctx.builder.free_local(sreg);
  6193. }
  6194. pub fn instr32_0FA8_jit(ctx: &mut JitContext) {
  6195. codegen::gen_get_sreg(ctx, regs::GS);
  6196. let sreg = ctx.builder.set_new_local();
  6197. codegen::gen_push32(ctx, &sreg);
  6198. ctx.builder.free_local(sreg);
  6199. }
  6200. pub fn instr16_0FA3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6201. gen_bt(
  6202. &mut ctx.builder,
  6203. &ctx.register_locals[r1 as usize],
  6204. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6205. 15,
  6206. )
  6207. }
  6208. pub fn instr16_0FA3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6209. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6210. codegen::gen_get_reg16(ctx, r);
  6211. codegen::sign_extend_i16(ctx.builder);
  6212. ctx.builder.const_i32(3);
  6213. ctx.builder.shr_s_i32();
  6214. ctx.builder.add_i32();
  6215. let address_local = ctx.builder.set_new_local();
  6216. codegen::gen_safe_read8(ctx, &address_local);
  6217. ctx.builder.free_local(address_local);
  6218. let value = ctx.builder.set_new_local();
  6219. gen_bt(
  6220. &mut ctx.builder,
  6221. &value,
  6222. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize]),
  6223. 7,
  6224. );
  6225. ctx.builder.free_local(value);
  6226. }
  6227. pub fn instr32_0FA3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6228. gen_bt(
  6229. &mut ctx.builder,
  6230. &ctx.register_locals[r1 as usize],
  6231. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6232. 31,
  6233. )
  6234. }
  6235. pub fn instr32_0FA3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6236. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6237. codegen::gen_get_reg32(ctx, r);
  6238. ctx.builder.const_i32(3);
  6239. ctx.builder.shr_s_i32();
  6240. ctx.builder.add_i32();
  6241. let address_local = ctx.builder.set_new_local();
  6242. codegen::gen_safe_read8(ctx, &address_local);
  6243. ctx.builder.free_local(address_local);
  6244. let value = ctx.builder.set_new_local();
  6245. gen_bt(
  6246. &mut ctx.builder,
  6247. &value,
  6248. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize]),
  6249. 7,
  6250. );
  6251. ctx.builder.free_local(value);
  6252. }
  6253. pub fn instr16_0FAB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6254. gen_bts(
  6255. &mut ctx.builder,
  6256. &ctx.register_locals[r1 as usize],
  6257. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6258. 15,
  6259. )
  6260. }
  6261. pub fn instr16_0FAB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6262. gen_bit_rmw(
  6263. ctx,
  6264. modrm_byte,
  6265. &gen_bts,
  6266. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6267. 16,
  6268. );
  6269. }
  6270. pub fn instr32_0FAB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6271. gen_bts(
  6272. &mut ctx.builder,
  6273. &ctx.register_locals[r1 as usize],
  6274. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6275. 31,
  6276. )
  6277. }
  6278. pub fn instr32_0FAB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6279. gen_bit_rmw(
  6280. ctx,
  6281. modrm_byte,
  6282. &gen_bts,
  6283. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6284. 32,
  6285. );
  6286. }
  6287. pub fn instr16_0FB3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6288. gen_btr(
  6289. &mut ctx.builder,
  6290. &ctx.register_locals[r1 as usize],
  6291. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6292. 15,
  6293. )
  6294. }
  6295. pub fn instr16_0FB3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6296. gen_bit_rmw(
  6297. ctx,
  6298. modrm_byte,
  6299. &gen_btr,
  6300. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6301. 16,
  6302. );
  6303. }
  6304. pub fn instr32_0FB3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6305. gen_btr(
  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_0FB3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6313. gen_bit_rmw(
  6314. ctx,
  6315. modrm_byte,
  6316. &gen_btr,
  6317. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6318. 32,
  6319. );
  6320. }
  6321. pub fn instr16_0FBB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6322. gen_btc(
  6323. &mut ctx.builder,
  6324. &ctx.register_locals[r1 as usize],
  6325. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6326. 15,
  6327. )
  6328. }
  6329. pub fn instr16_0FBB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6330. gen_bit_rmw(
  6331. ctx,
  6332. modrm_byte,
  6333. &gen_btc,
  6334. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6335. 16,
  6336. );
  6337. }
  6338. pub fn instr32_0FBB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6339. gen_btc(
  6340. &mut ctx.builder,
  6341. &ctx.register_locals[r1 as usize],
  6342. &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
  6343. 31,
  6344. )
  6345. }
  6346. pub fn instr32_0FBB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6347. gen_bit_rmw(
  6348. ctx,
  6349. modrm_byte,
  6350. &gen_btc,
  6351. &LocalOrImmediate::WasmLocal(&ctx.reg(r)),
  6352. 32,
  6353. );
  6354. }
  6355. pub fn instr16_0FBA_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6356. gen_bt(
  6357. &mut ctx.builder,
  6358. &ctx.register_locals[r as usize],
  6359. &LocalOrImmediate::Immediate(imm8 as i32),
  6360. 15,
  6361. )
  6362. }
  6363. pub fn instr16_0FBA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6364. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6365. let offset = (imm8 as i32 & 15) >> 3;
  6366. if offset != 0 {
  6367. ctx.builder.const_i32(offset);
  6368. ctx.builder.add_i32();
  6369. }
  6370. let address_local = ctx.builder.set_new_local();
  6371. codegen::gen_safe_read8(ctx, &address_local);
  6372. ctx.builder.free_local(address_local);
  6373. let value = ctx.builder.set_new_local();
  6374. gen_bt(
  6375. &mut ctx.builder,
  6376. &value,
  6377. &LocalOrImmediate::Immediate(imm8 as i32),
  6378. 7,
  6379. );
  6380. ctx.builder.free_local(value);
  6381. }
  6382. pub fn instr32_0FBA_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6383. gen_bt(
  6384. &mut ctx.builder,
  6385. &ctx.register_locals[r as usize],
  6386. &LocalOrImmediate::Immediate(imm8 as i32),
  6387. 31,
  6388. )
  6389. }
  6390. pub fn instr32_0FBA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6391. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6392. let offset = (imm8 as i32 & 31) >> 3;
  6393. if offset != 0 {
  6394. ctx.builder.const_i32(offset);
  6395. ctx.builder.add_i32();
  6396. }
  6397. let address_local = ctx.builder.set_new_local();
  6398. codegen::gen_safe_read8(ctx, &address_local);
  6399. ctx.builder.free_local(address_local);
  6400. let value = ctx.builder.set_new_local();
  6401. gen_bt(
  6402. &mut ctx.builder,
  6403. &value,
  6404. &LocalOrImmediate::Immediate(imm8 as i32),
  6405. 7,
  6406. );
  6407. ctx.builder.free_local(value);
  6408. }
  6409. pub fn instr16_0FBA_5_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6410. gen_bts(
  6411. &mut ctx.builder,
  6412. &ctx.register_locals[r as usize],
  6413. &LocalOrImmediate::Immediate(imm8 as i32),
  6414. 15,
  6415. )
  6416. }
  6417. pub fn instr16_0FBA_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6418. gen_bit_rmw(
  6419. ctx,
  6420. modrm_byte,
  6421. &gen_bts,
  6422. &LocalOrImmediate::Immediate(imm8 as i32),
  6423. 16,
  6424. );
  6425. }
  6426. pub fn instr32_0FBA_5_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6427. gen_bts(
  6428. &mut ctx.builder,
  6429. &ctx.register_locals[r as usize],
  6430. &LocalOrImmediate::Immediate(imm8 as i32),
  6431. 31,
  6432. )
  6433. }
  6434. pub fn instr32_0FBA_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6435. gen_bit_rmw(
  6436. ctx,
  6437. modrm_byte,
  6438. &gen_bts,
  6439. &LocalOrImmediate::Immediate(imm8 as i32),
  6440. 32,
  6441. );
  6442. }
  6443. pub fn instr16_0FBA_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6444. gen_btr(
  6445. &mut ctx.builder,
  6446. &ctx.register_locals[r as usize],
  6447. &LocalOrImmediate::Immediate(imm8 as i32),
  6448. 15,
  6449. )
  6450. }
  6451. pub fn instr16_0FBA_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6452. gen_bit_rmw(
  6453. ctx,
  6454. modrm_byte,
  6455. &gen_btr,
  6456. &LocalOrImmediate::Immediate(imm8 as i32),
  6457. 16,
  6458. );
  6459. }
  6460. pub fn instr32_0FBA_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6461. gen_btr(
  6462. &mut ctx.builder,
  6463. &ctx.register_locals[r as usize],
  6464. &LocalOrImmediate::Immediate(imm8 as i32),
  6465. 31,
  6466. )
  6467. }
  6468. pub fn instr32_0FBA_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6469. gen_bit_rmw(
  6470. ctx,
  6471. modrm_byte,
  6472. &gen_btr,
  6473. &LocalOrImmediate::Immediate(imm8 as i32),
  6474. 32,
  6475. );
  6476. }
  6477. pub fn instr16_0FBA_7_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6478. gen_btc(
  6479. &mut ctx.builder,
  6480. &ctx.register_locals[r as usize],
  6481. &LocalOrImmediate::Immediate(imm8 as i32),
  6482. 15,
  6483. )
  6484. }
  6485. pub fn instr16_0FBA_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6486. gen_bit_rmw(
  6487. ctx,
  6488. modrm_byte,
  6489. &gen_btc,
  6490. &LocalOrImmediate::Immediate(imm8 as i32),
  6491. 16,
  6492. );
  6493. }
  6494. pub fn instr32_0FBA_7_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
  6495. gen_btc(
  6496. &mut ctx.builder,
  6497. &ctx.register_locals[r as usize],
  6498. &LocalOrImmediate::Immediate(imm8 as i32),
  6499. 31,
  6500. )
  6501. }
  6502. pub fn instr32_0FBA_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
  6503. gen_bit_rmw(
  6504. ctx,
  6505. modrm_byte,
  6506. &gen_btc,
  6507. &LocalOrImmediate::Immediate(imm8 as i32),
  6508. 32,
  6509. );
  6510. }
  6511. pub fn instr_0FAE_5_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte) {
  6512. dbg_log!("Generating #ud for unimplemented instruction: instr_0FAE_5_mem_jit");
  6513. codegen::gen_trigger_ud(ctx);
  6514. }
  6515. pub fn instr_0FAE_5_reg_jit(_ctx: &mut JitContext, _r: u32) {
  6516. // For this instruction, the processor ignores the r/m field of the ModR/M byte.
  6517. }
  6518. pub fn instr_0FD1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6519. mmx_read64_mm_mem(ctx, "instr_0FD1", modrm_byte, r);
  6520. }
  6521. pub fn instr_0FD1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6522. mmx_read64_mm_mm(ctx, "instr_0FD1", r1, r2);
  6523. }
  6524. pub fn instr_0FD2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6525. mmx_read64_mm_mem(ctx, "instr_0FD2", modrm_byte, r);
  6526. }
  6527. pub fn instr_0FD2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6528. mmx_read64_mm_mm(ctx, "instr_0FD2", r1, r2);
  6529. }
  6530. pub fn instr_0FD3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6531. mmx_read64_mm_mem(ctx, "instr_0FD3", modrm_byte, r);
  6532. }
  6533. pub fn instr_0FD3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6534. mmx_read64_mm_mm(ctx, "instr_0FD3", r1, r2);
  6535. }
  6536. pub fn instr_0FD4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6537. mmx_read64_mm_mem(ctx, "instr_0FD4", modrm_byte, r);
  6538. }
  6539. pub fn instr_0FD4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6540. mmx_read64_mm_mm(ctx, "instr_0FD4", r1, r2);
  6541. }
  6542. pub fn instr_0FD5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6543. mmx_read64_mm_mem(ctx, "instr_0FD5", modrm_byte, r);
  6544. }
  6545. pub fn instr_0FD5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6546. mmx_read64_mm_mm(ctx, "instr_0FD5", r1, r2);
  6547. }
  6548. pub fn instr_0FD7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
  6549. codegen::gen_trigger_ud(ctx)
  6550. }
  6551. pub fn instr_0FD7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6552. ctx.builder.const_i32(r1 as i32);
  6553. ctx.builder.call_fn1_ret("instr_0FD7");
  6554. codegen::gen_set_reg32(ctx, r2);
  6555. }
  6556. pub fn instr_0FD8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6557. mmx_read64_mm_mem(ctx, "instr_0FD8", modrm_byte, r);
  6558. }
  6559. pub fn instr_0FD8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6560. mmx_read64_mm_mm(ctx, "instr_0FD8", r1, r2);
  6561. }
  6562. pub fn instr_0FD9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6563. mmx_read64_mm_mem(ctx, "instr_0FD9", modrm_byte, r);
  6564. }
  6565. pub fn instr_0FD9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6566. mmx_read64_mm_mm(ctx, "instr_0FD9", r1, r2);
  6567. }
  6568. pub fn instr_0FDA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6569. mmx_read64_mm_mem(ctx, "instr_0FDA", modrm_byte, r);
  6570. }
  6571. pub fn instr_0FDA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6572. mmx_read64_mm_mm(ctx, "instr_0FDA", r1, r2);
  6573. }
  6574. pub fn instr_0FDB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6575. mmx_read64_mm_mem(ctx, "instr_0FDB", modrm_byte, r);
  6576. }
  6577. pub fn instr_0FDB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6578. mmx_read64_mm_mm(ctx, "instr_0FDB", r1, r2);
  6579. }
  6580. pub fn instr_0FDC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6581. mmx_read64_mm_mem(ctx, "instr_0FDC", modrm_byte, r);
  6582. }
  6583. pub fn instr_0FDC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6584. mmx_read64_mm_mm(ctx, "instr_0FDC", r1, r2);
  6585. }
  6586. pub fn instr_0FDD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6587. mmx_read64_mm_mem(ctx, "instr_0FDD", modrm_byte, r);
  6588. }
  6589. pub fn instr_0FDD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6590. mmx_read64_mm_mm(ctx, "instr_0FDD", r1, r2);
  6591. }
  6592. pub fn instr_0FDE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6593. mmx_read64_mm_mem(ctx, "instr_0FDE", modrm_byte, r);
  6594. }
  6595. pub fn instr_0FDE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6596. mmx_read64_mm_mm(ctx, "instr_0FDE", r1, r2);
  6597. }
  6598. pub fn instr_0FDF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6599. mmx_read64_mm_mem(ctx, "instr_0FDF", modrm_byte, r);
  6600. }
  6601. pub fn instr_0FDF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6602. mmx_read64_mm_mm(ctx, "instr_0FDF", r1, r2);
  6603. }
  6604. pub fn instr_660FD1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6605. sse_read128_xmm_mem(ctx, "instr_660FD1", modrm_byte, r);
  6606. }
  6607. pub fn instr_660FD1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6608. sse_read128_xmm_xmm(ctx, "instr_660FD1", r1, r2);
  6609. }
  6610. pub fn instr_660FD2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6611. sse_read128_xmm_mem(ctx, "instr_660FD2", modrm_byte, r);
  6612. }
  6613. pub fn instr_660FD2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6614. sse_read128_xmm_xmm(ctx, "instr_660FD2", r1, r2);
  6615. }
  6616. pub fn instr_660FD3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6617. sse_read128_xmm_mem(ctx, "instr_660FD3", modrm_byte, r);
  6618. }
  6619. pub fn instr_660FD3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6620. sse_read128_xmm_xmm(ctx, "instr_660FD3", r1, r2);
  6621. }
  6622. pub fn instr_660FD4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6623. sse_read128_xmm_mem(ctx, "instr_660FD4", modrm_byte, r);
  6624. }
  6625. pub fn instr_660FD4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6626. sse_read128_xmm_xmm(ctx, "instr_660FD4", r1, r2);
  6627. }
  6628. pub fn instr_660FD5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6629. sse_read128_xmm_mem(ctx, "instr_660FD5", modrm_byte, r);
  6630. }
  6631. pub fn instr_660FD5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6632. sse_read128_xmm_xmm(ctx, "instr_660FD5", r1, r2);
  6633. }
  6634. pub fn instr_660FD6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6635. codegen::gen_modrm_resolve(ctx, modrm_byte);
  6636. let address_local = ctx.builder.set_new_local();
  6637. ctx.builder
  6638. .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
  6639. ctx.builder.load_aligned_i64(0);
  6640. let value_local = ctx.builder.set_new_local_i64();
  6641. codegen::gen_safe_write64(ctx, &address_local, &value_local);
  6642. ctx.builder.free_local(address_local);
  6643. ctx.builder.free_local_i64(value_local);
  6644. }
  6645. pub fn instr_660FD6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6646. ctx.builder.const_i32(r1 as i32);
  6647. ctx.builder.const_i32(r2 as i32);
  6648. ctx.builder.call_fn2("instr_660FD6_reg");
  6649. }
  6650. pub fn instr_660FD7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
  6651. codegen::gen_trigger_ud(ctx)
  6652. }
  6653. pub fn instr_660FD7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6654. ctx.builder.const_i32(r1 as i32);
  6655. ctx.builder.call_fn1_ret("instr_660FD7");
  6656. codegen::gen_set_reg32(ctx, r2);
  6657. }
  6658. pub fn instr_660FD8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6659. sse_read128_xmm_mem(ctx, "instr_660FD8", modrm_byte, r);
  6660. }
  6661. pub fn instr_660FD8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6662. sse_read128_xmm_xmm(ctx, "instr_660FD8", r1, r2);
  6663. }
  6664. pub fn instr_660FD9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6665. sse_read128_xmm_mem(ctx, "instr_660FD9", modrm_byte, r);
  6666. }
  6667. pub fn instr_660FD9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6668. sse_read128_xmm_xmm(ctx, "instr_660FD9", r1, r2);
  6669. }
  6670. pub fn instr_660FDA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6671. sse_read128_xmm_mem(ctx, "instr_660FDA", modrm_byte, r);
  6672. }
  6673. pub fn instr_660FDA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6674. sse_read128_xmm_xmm(ctx, "instr_660FDA", r1, r2);
  6675. }
  6676. pub fn instr_660FDB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6677. sse_read128_xmm_mem(ctx, "instr_660FDB", modrm_byte, r);
  6678. }
  6679. pub fn instr_660FDB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6680. sse_read128_xmm_xmm(ctx, "instr_660FDB", r1, r2);
  6681. }
  6682. pub fn instr_660FDC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6683. sse_read128_xmm_mem(ctx, "instr_660FDC", modrm_byte, r);
  6684. }
  6685. pub fn instr_660FDC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6686. sse_read128_xmm_xmm(ctx, "instr_660FDC", r1, r2);
  6687. }
  6688. pub fn instr_660FDD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6689. sse_read128_xmm_mem(ctx, "instr_660FDD", modrm_byte, r);
  6690. }
  6691. pub fn instr_660FDD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6692. sse_read128_xmm_xmm(ctx, "instr_660FDD", r1, r2);
  6693. }
  6694. pub fn instr_660FDE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6695. sse_read128_xmm_mem(ctx, "instr_660FDE", modrm_byte, r);
  6696. }
  6697. pub fn instr_660FDE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6698. sse_read128_xmm_xmm(ctx, "instr_660FDE", r1, r2);
  6699. }
  6700. pub fn instr_660FDF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6701. sse_read128_xmm_mem(ctx, "instr_660FDF", modrm_byte, r);
  6702. }
  6703. pub fn instr_660FDF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6704. sse_read128_xmm_xmm(ctx, "instr_660FDF", r1, r2);
  6705. }
  6706. pub fn instr_0FE0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6707. mmx_read64_mm_mem(ctx, "instr_0FE0", modrm_byte, r);
  6708. }
  6709. pub fn instr_0FE0_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6710. mmx_read64_mm_mm(ctx, "instr_0FE0", r1, r2);
  6711. }
  6712. pub fn instr_0FE1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6713. mmx_read64_mm_mem(ctx, "instr_0FE1", modrm_byte, r);
  6714. }
  6715. pub fn instr_0FE1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6716. mmx_read64_mm_mm(ctx, "instr_0FE1", r1, r2);
  6717. }
  6718. pub fn instr_0FE2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6719. mmx_read64_mm_mem(ctx, "instr_0FE2", modrm_byte, r);
  6720. }
  6721. pub fn instr_0FE2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6722. mmx_read64_mm_mm(ctx, "instr_0FE2", r1, r2);
  6723. }
  6724. pub fn instr_0FE3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6725. mmx_read64_mm_mem(ctx, "instr_0FE3", modrm_byte, r);
  6726. }
  6727. pub fn instr_0FE3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6728. mmx_read64_mm_mm(ctx, "instr_0FE3", r1, r2);
  6729. }
  6730. pub fn instr_0FE4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6731. mmx_read64_mm_mem(ctx, "instr_0FE4", modrm_byte, r);
  6732. }
  6733. pub fn instr_0FE4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6734. mmx_read64_mm_mm(ctx, "instr_0FE4", r1, r2);
  6735. }
  6736. pub fn instr_0FE5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6737. mmx_read64_mm_mem(ctx, "instr_0FE5", modrm_byte, r);
  6738. }
  6739. pub fn instr_0FE5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6740. mmx_read64_mm_mm(ctx, "instr_0FE5", r1, r2);
  6741. }
  6742. pub fn instr_0FE8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6743. mmx_read64_mm_mem(ctx, "instr_0FE8", modrm_byte, r);
  6744. }
  6745. pub fn instr_0FE8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6746. mmx_read64_mm_mm(ctx, "instr_0FE8", r1, r2);
  6747. }
  6748. pub fn instr_0FE9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6749. mmx_read64_mm_mem(ctx, "instr_0FE9", modrm_byte, r);
  6750. }
  6751. pub fn instr_0FE9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6752. mmx_read64_mm_mm(ctx, "instr_0FE9", r1, r2);
  6753. }
  6754. pub fn instr_0FEA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6755. mmx_read64_mm_mem(ctx, "instr_0FEA", modrm_byte, r);
  6756. }
  6757. pub fn instr_0FEA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6758. mmx_read64_mm_mm(ctx, "instr_0FEA", r1, r2);
  6759. }
  6760. pub fn instr_0FEB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6761. mmx_read64_mm_mem(ctx, "instr_0FEB", modrm_byte, r);
  6762. }
  6763. pub fn instr_0FEB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6764. mmx_read64_mm_mm(ctx, "instr_0FEB", r1, r2);
  6765. }
  6766. pub fn instr_0FEC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6767. mmx_read64_mm_mem(ctx, "instr_0FEC", modrm_byte, r);
  6768. }
  6769. pub fn instr_0FEC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6770. mmx_read64_mm_mm(ctx, "instr_0FEC", r1, r2);
  6771. }
  6772. pub fn instr_0FED_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6773. mmx_read64_mm_mem(ctx, "instr_0FED", modrm_byte, r);
  6774. }
  6775. pub fn instr_0FED_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6776. mmx_read64_mm_mm(ctx, "instr_0FED", r1, r2);
  6777. }
  6778. pub fn instr_0FEE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6779. mmx_read64_mm_mem(ctx, "instr_0FEE", modrm_byte, r);
  6780. }
  6781. pub fn instr_0FEE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6782. mmx_read64_mm_mm(ctx, "instr_0FEE", r1, r2);
  6783. }
  6784. pub fn instr_0FEF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6785. mmx_read64_mm_mem(ctx, "instr_0FEF", modrm_byte, r);
  6786. }
  6787. pub fn instr_0FEF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6788. mmx_read64_mm_mm(ctx, "instr_0FEF", r1, r2);
  6789. }
  6790. pub fn instr_660FE0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6791. sse_read128_xmm_mem(ctx, "instr_660FE0", modrm_byte, r);
  6792. }
  6793. pub fn instr_660FE0_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6794. sse_read128_xmm_xmm(ctx, "instr_660FE0", r1, r2);
  6795. }
  6796. pub fn instr_660FE1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6797. sse_read128_xmm_mem(ctx, "instr_660FE1", modrm_byte, r);
  6798. }
  6799. pub fn instr_660FE1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6800. sse_read128_xmm_xmm(ctx, "instr_660FE1", r1, r2);
  6801. }
  6802. pub fn instr_660FE2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6803. sse_read128_xmm_mem(ctx, "instr_660FE2", modrm_byte, r);
  6804. }
  6805. pub fn instr_660FE2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6806. sse_read128_xmm_xmm(ctx, "instr_660FE2", r1, r2);
  6807. }
  6808. pub fn instr_660FE3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6809. sse_read128_xmm_mem(ctx, "instr_660FE3", modrm_byte, r);
  6810. }
  6811. pub fn instr_660FE3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6812. sse_read128_xmm_xmm(ctx, "instr_660FE3", r1, r2);
  6813. }
  6814. pub fn instr_660FE4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6815. sse_read128_xmm_mem(ctx, "instr_660FE4", modrm_byte, r);
  6816. }
  6817. pub fn instr_660FE4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6818. sse_read128_xmm_xmm(ctx, "instr_660FE4", r1, r2);
  6819. }
  6820. pub fn instr_660FE5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6821. sse_read128_xmm_mem(ctx, "instr_660FE5", modrm_byte, r);
  6822. }
  6823. pub fn instr_660FE5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6824. sse_read128_xmm_xmm(ctx, "instr_660FE5", r1, r2);
  6825. }
  6826. pub fn instr_660FE6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6827. sse_read128_xmm_mem(ctx, "instr_660FE6", modrm_byte, r);
  6828. }
  6829. pub fn instr_660FE6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6830. sse_read128_xmm_xmm(ctx, "instr_660FE6", r1, r2);
  6831. }
  6832. pub fn instr_F20FE6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6833. sse_read128_xmm_mem(ctx, "instr_F20FE6", modrm_byte, r);
  6834. }
  6835. pub fn instr_F20FE6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6836. sse_read128_xmm_xmm(ctx, "instr_F20FE6", r1, r2);
  6837. }
  6838. pub fn instr_F30FE6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6839. sse_read64_xmm_mem(ctx, "instr_F30FE6", modrm_byte, r);
  6840. }
  6841. pub fn instr_F30FE6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6842. sse_read64_xmm_xmm(ctx, "instr_F30FE6", r1, r2);
  6843. }
  6844. pub fn instr_660FE7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6845. instr_0F29_mem_jit(ctx, modrm_byte, r);
  6846. }
  6847. pub fn instr_660FE7_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
  6848. codegen::gen_trigger_ud(ctx);
  6849. }
  6850. pub fn instr_660FE8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6851. sse_read128_xmm_mem(ctx, "instr_660FE8", modrm_byte, r);
  6852. }
  6853. pub fn instr_660FE8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6854. sse_read128_xmm_xmm(ctx, "instr_660FE8", r1, r2);
  6855. }
  6856. pub fn instr_660FE9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6857. sse_read128_xmm_mem(ctx, "instr_660FE9", modrm_byte, r);
  6858. }
  6859. pub fn instr_660FE9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6860. sse_read128_xmm_xmm(ctx, "instr_660FE9", r1, r2);
  6861. }
  6862. pub fn instr_660FEA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6863. sse_read128_xmm_mem(ctx, "instr_660FEA", modrm_byte, r);
  6864. }
  6865. pub fn instr_660FEA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6866. sse_read128_xmm_xmm(ctx, "instr_660FEA", r1, r2);
  6867. }
  6868. pub fn instr_660FEB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6869. sse_read128_xmm_mem(ctx, "instr_660FEB", modrm_byte, r);
  6870. }
  6871. pub fn instr_660FEB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6872. sse_read128_xmm_xmm(ctx, "instr_660FEB", r1, r2);
  6873. }
  6874. pub fn instr_660FEC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6875. sse_read128_xmm_mem(ctx, "instr_660FEC", modrm_byte, r);
  6876. }
  6877. pub fn instr_660FEC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6878. sse_read128_xmm_xmm(ctx, "instr_660FEC", r1, r2);
  6879. }
  6880. pub fn instr_660FED_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6881. sse_read128_xmm_mem(ctx, "instr_660FED", modrm_byte, r);
  6882. }
  6883. pub fn instr_660FED_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6884. sse_read128_xmm_xmm(ctx, "instr_660FED", r1, r2);
  6885. }
  6886. pub fn instr_660FEE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6887. sse_read128_xmm_mem(ctx, "instr_660FEE", modrm_byte, r);
  6888. }
  6889. pub fn instr_660FEE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6890. sse_read128_xmm_xmm(ctx, "instr_660FEE", r1, r2);
  6891. }
  6892. pub fn instr_660FEF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6893. sse_read128_xmm_mem(ctx, "instr_660FEF", modrm_byte, r);
  6894. }
  6895. pub fn instr_660FEF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6896. sse_read128_xmm_xmm(ctx, "instr_660FEF", r1, r2);
  6897. }
  6898. pub fn instr_0FF1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6899. mmx_read64_mm_mem(ctx, "instr_0FF1", modrm_byte, r);
  6900. }
  6901. pub fn instr_0FF1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6902. mmx_read64_mm_mm(ctx, "instr_0FF1", r1, r2);
  6903. }
  6904. pub fn instr_0FF2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6905. mmx_read64_mm_mem(ctx, "instr_0FF2", modrm_byte, r);
  6906. }
  6907. pub fn instr_0FF2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6908. mmx_read64_mm_mm(ctx, "instr_0FF2", r1, r2);
  6909. }
  6910. pub fn instr_0FF3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6911. mmx_read64_mm_mem(ctx, "instr_0FF3", modrm_byte, r);
  6912. }
  6913. pub fn instr_0FF3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6914. mmx_read64_mm_mm(ctx, "instr_0FF3", r1, r2);
  6915. }
  6916. pub fn instr_0FF4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6917. mmx_read64_mm_mem(ctx, "instr_0FF4", modrm_byte, r);
  6918. }
  6919. pub fn instr_0FF4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6920. mmx_read64_mm_mm(ctx, "instr_0FF4", r1, r2);
  6921. }
  6922. pub fn instr_0FF5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6923. mmx_read64_mm_mem(ctx, "instr_0FF5", modrm_byte, r);
  6924. }
  6925. pub fn instr_0FF5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6926. mmx_read64_mm_mm(ctx, "instr_0FF5", r1, r2);
  6927. }
  6928. pub fn instr_0FF6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6929. mmx_read64_mm_mem(ctx, "instr_0FF6", modrm_byte, r);
  6930. }
  6931. pub fn instr_0FF6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6932. mmx_read64_mm_mm(ctx, "instr_0FF6", r1, r2);
  6933. }
  6934. pub fn instr_0FF7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
  6935. codegen::gen_trigger_ud(ctx)
  6936. }
  6937. pub fn instr_0FF7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6938. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  6939. ctx.builder,
  6940. ctx.start_of_current_instruction as i32 & 0xFFF,
  6941. );
  6942. codegen::gen_move_registers_from_locals_to_memory(ctx);
  6943. ctx.builder.const_i32(r1 as i32);
  6944. ctx.builder.const_i32(r2 as i32);
  6945. if ctx.cpu.asize_32() {
  6946. codegen::gen_get_reg32(ctx, regs::EDI);
  6947. }
  6948. else {
  6949. codegen::gen_get_reg16(ctx, regs::DI);
  6950. }
  6951. jit_add_seg_offset(ctx, regs::DS);
  6952. ctx.builder.call_fn3("maskmovq");
  6953. codegen::gen_move_registers_from_memory_to_locals(ctx);
  6954. codegen::gen_get_page_fault(ctx.builder);
  6955. ctx.builder.if_void();
  6956. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  6957. ctx.builder.br(ctx.exit_label);
  6958. ctx.builder.block_end();
  6959. }
  6960. pub fn instr_0FF8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6961. mmx_read64_mm_mem(ctx, "instr_0FF8", modrm_byte, r);
  6962. }
  6963. pub fn instr_0FF8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6964. mmx_read64_mm_mm(ctx, "instr_0FF8", r1, r2);
  6965. }
  6966. pub fn instr_0FF9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6967. mmx_read64_mm_mem(ctx, "instr_0FF9", modrm_byte, r);
  6968. }
  6969. pub fn instr_0FF9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6970. mmx_read64_mm_mm(ctx, "instr_0FF9", r1, r2);
  6971. }
  6972. pub fn instr_0FFA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6973. mmx_read64_mm_mem(ctx, "instr_0FFA", modrm_byte, r);
  6974. }
  6975. pub fn instr_0FFA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6976. mmx_read64_mm_mm(ctx, "instr_0FFA", r1, r2);
  6977. }
  6978. pub fn instr_0FFB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6979. mmx_read64_mm_mem(ctx, "instr_0FFB", modrm_byte, r);
  6980. }
  6981. pub fn instr_0FFB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6982. mmx_read64_mm_mm(ctx, "instr_0FFB", r1, r2);
  6983. }
  6984. pub fn instr_0FFC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6985. mmx_read64_mm_mem(ctx, "instr_0FFC", modrm_byte, r);
  6986. }
  6987. pub fn instr_0FFC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6988. mmx_read64_mm_mm(ctx, "instr_0FFC", r1, r2);
  6989. }
  6990. pub fn instr_0FFD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6991. mmx_read64_mm_mem(ctx, "instr_0FFD", modrm_byte, r);
  6992. }
  6993. pub fn instr_0FFD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  6994. mmx_read64_mm_mm(ctx, "instr_0FFD", r1, r2);
  6995. }
  6996. pub fn instr_0FFE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  6997. mmx_read64_mm_mem(ctx, "instr_0FFE", modrm_byte, r);
  6998. }
  6999. pub fn instr_0FFE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7000. mmx_read64_mm_mm(ctx, "instr_0FFE", r1, r2);
  7001. }
  7002. pub fn instr_660FF1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7003. sse_read128_xmm_mem(ctx, "instr_660FF1", modrm_byte, r);
  7004. }
  7005. pub fn instr_660FF1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7006. sse_read128_xmm_xmm(ctx, "instr_660FF1", r1, r2);
  7007. }
  7008. pub fn instr_660FF2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7009. sse_read128_xmm_mem(ctx, "instr_660FF2", modrm_byte, r);
  7010. }
  7011. pub fn instr_660FF2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7012. sse_read128_xmm_xmm(ctx, "instr_660FF2", r1, r2);
  7013. }
  7014. pub fn instr_660FF3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7015. sse_read128_xmm_mem(ctx, "instr_660FF3", modrm_byte, r);
  7016. }
  7017. pub fn instr_660FF3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7018. sse_read128_xmm_xmm(ctx, "instr_660FF3", r1, r2);
  7019. }
  7020. pub fn instr_660FF4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7021. sse_read128_xmm_mem(ctx, "instr_660FF4", modrm_byte, r);
  7022. }
  7023. pub fn instr_660FF4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7024. sse_read128_xmm_xmm(ctx, "instr_660FF4", r1, r2);
  7025. }
  7026. pub fn instr_660FF5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7027. sse_read128_xmm_mem(ctx, "instr_660FF5", modrm_byte, r);
  7028. }
  7029. pub fn instr_660FF5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7030. sse_read128_xmm_xmm(ctx, "instr_660FF5", r1, r2);
  7031. }
  7032. pub fn instr_660FF6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7033. sse_read128_xmm_mem(ctx, "instr_660FF6", modrm_byte, r);
  7034. }
  7035. pub fn instr_660FF6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7036. sse_read128_xmm_xmm(ctx, "instr_660FF6", r1, r2);
  7037. }
  7038. pub fn instr_660FF7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
  7039. codegen::gen_trigger_ud(ctx)
  7040. }
  7041. pub fn instr_660FF7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7042. codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
  7043. ctx.builder,
  7044. ctx.start_of_current_instruction as i32 & 0xFFF,
  7045. );
  7046. codegen::gen_move_registers_from_locals_to_memory(ctx);
  7047. ctx.builder.const_i32(r1 as i32);
  7048. ctx.builder.const_i32(r2 as i32);
  7049. if ctx.cpu.asize_32() {
  7050. codegen::gen_get_reg32(ctx, regs::EDI);
  7051. }
  7052. else {
  7053. codegen::gen_get_reg16(ctx, regs::DI);
  7054. }
  7055. jit_add_seg_offset(ctx, regs::DS);
  7056. ctx.builder.call_fn3("maskmovdqu");
  7057. codegen::gen_move_registers_from_memory_to_locals(ctx);
  7058. codegen::gen_get_page_fault(ctx.builder);
  7059. ctx.builder.if_void();
  7060. codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
  7061. ctx.builder.br(ctx.exit_label);
  7062. ctx.builder.block_end();
  7063. }
  7064. pub fn instr_660FF8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7065. sse_read128_xmm_mem(ctx, "instr_660FF8", modrm_byte, r);
  7066. }
  7067. pub fn instr_660FF8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7068. sse_read128_xmm_xmm(ctx, "instr_660FF8", r1, r2);
  7069. }
  7070. pub fn instr_660FF9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7071. sse_read128_xmm_mem(ctx, "instr_660FF9", modrm_byte, r);
  7072. }
  7073. pub fn instr_660FF9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7074. sse_read128_xmm_xmm(ctx, "instr_660FF9", r1, r2);
  7075. }
  7076. pub fn instr_660FFA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7077. sse_read128_xmm_mem(ctx, "instr_660FFA", modrm_byte, r);
  7078. }
  7079. pub fn instr_660FFA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7080. sse_read128_xmm_xmm(ctx, "instr_660FFA", r1, r2);
  7081. }
  7082. pub fn instr_660FFB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7083. sse_read128_xmm_mem(ctx, "instr_660FFB", modrm_byte, r);
  7084. }
  7085. pub fn instr_660FFB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7086. sse_read128_xmm_xmm(ctx, "instr_660FFB", r1, r2);
  7087. }
  7088. pub fn instr_660FFC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7089. sse_read128_xmm_mem(ctx, "instr_660FFC", modrm_byte, r);
  7090. }
  7091. pub fn instr_660FFC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7092. sse_read128_xmm_xmm(ctx, "instr_660FFC", r1, r2);
  7093. }
  7094. pub fn instr_660FFD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7095. sse_read128_xmm_mem(ctx, "instr_660FFD", modrm_byte, r);
  7096. }
  7097. pub fn instr_660FFD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7098. sse_read128_xmm_xmm(ctx, "instr_660FFD", r1, r2);
  7099. }
  7100. pub fn instr_660FFE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
  7101. sse_read128_xmm_mem(ctx, "instr_660FFE", modrm_byte, r);
  7102. }
  7103. pub fn instr_660FFE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
  7104. sse_read128_xmm_xmm(ctx, "instr_660FFE", r1, r2);
  7105. }