jit_instructions.rs 242 KB

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