1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427 |
- #![allow(non_snake_case)]
- use codegen;
- use codegen::BitSize;
- use cpu::cpu::{
- FLAGS_ALL, FLAGS_DEFAULT, FLAGS_MASK, FLAG_ADJUST, FLAG_CARRY, FLAG_DIRECTION, FLAG_INTERRUPT,
- FLAG_OVERFLOW, FLAG_SUB, FLAG_ZERO, OPSIZE_8, OPSIZE_16, OPSIZE_32,
- };
- use cpu::global_pointers;
- use jit::JitContext;
- use modrm::{jit_add_seg_offset, ModrmByte};
- use prefix::SEG_PREFIX_ZERO;
- use prefix::{PREFIX_66, PREFIX_67, PREFIX_F2, PREFIX_F3};
- use regs;
- use regs::{AX, BP, BX, CX, DI, DX, SI, SP};
- use regs::{CS, DS, ES, FS, GS, SS};
- use regs::{EAX, EBP, EBX, ECX, EDI, EDX, ESI, ESP};
- use wasmgen::wasm_builder::{WasmBuilder, WasmLocal};
- enum LocalOrImmediate<'a> {
- WasmLocal(&'a WasmLocal),
- Immediate(i32),
- }
- impl<'a> LocalOrImmediate<'a> {
- pub fn gen_get(&self, builder: &mut WasmBuilder) {
- match self {
- LocalOrImmediate::WasmLocal(l) => builder.get_local(l),
- LocalOrImmediate::Immediate(i) => builder.const_i32(*i),
- }
- }
- }
- pub fn jit_instruction(ctx: &mut JitContext, instr_flags: &mut u32) {
- ctx.cpu.prefixes = 0;
- ctx.start_of_current_instruction = ctx.cpu.eip;
- ::gen::jit::jit(
- ctx.cpu.read_imm8() as u32 | (ctx.cpu.osize_32() as u32) << 8,
- ctx,
- instr_flags,
- );
- }
- pub fn jit_handle_prefix(ctx: &mut JitContext, instr_flags: &mut u32) {
- ::gen::jit::jit(
- ctx.cpu.read_imm8() as u32 | (ctx.cpu.osize_32() as u32) << 8,
- ctx,
- instr_flags,
- );
- }
- pub fn jit_handle_segment_prefix(segment: u32, ctx: &mut JitContext, instr_flags: &mut u32) {
- dbg_assert!(segment <= 5);
- ctx.cpu.prefixes |= segment + 1;
- jit_handle_prefix(ctx, instr_flags)
- }
- pub fn instr16_0F_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- ::gen::jit0f::jit(ctx.cpu.read_imm8() as u32, ctx, instr_flags)
- }
- pub fn instr32_0F_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- ::gen::jit0f::jit(ctx.cpu.read_imm8() as u32 | 0x100, ctx, instr_flags)
- }
- pub fn instr_26_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- jit_handle_segment_prefix(ES, ctx, instr_flags)
- }
- pub fn instr_2E_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- jit_handle_segment_prefix(CS, ctx, instr_flags)
- }
- pub fn instr_36_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- jit_handle_segment_prefix(SS, ctx, instr_flags)
- }
- pub fn instr_3E_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- jit_handle_segment_prefix(DS, ctx, instr_flags)
- }
- pub fn instr_64_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- jit_handle_segment_prefix(FS, ctx, instr_flags)
- }
- pub fn instr_65_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- jit_handle_segment_prefix(GS, ctx, instr_flags)
- }
- pub fn instr_66_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- ctx.cpu.prefixes |= PREFIX_66;
- jit_handle_prefix(ctx, instr_flags)
- }
- pub fn instr_67_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- ctx.cpu.prefixes |= PREFIX_67;
- jit_handle_prefix(ctx, instr_flags)
- }
- pub fn instr_F0_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- // lock: Ignore
- jit_handle_prefix(ctx, instr_flags)
- }
- pub fn instr_F2_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- ctx.cpu.prefixes |= PREFIX_F2;
- jit_handle_prefix(ctx, instr_flags)
- }
- pub fn instr_F3_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
- ctx.cpu.prefixes |= PREFIX_F3;
- jit_handle_prefix(ctx, instr_flags)
- }
- fn sse_read128_xmm_mem(ctx: &mut JitContext, name: &str, modrm_byte: ModrmByte, r: u32) {
- let dest = global_pointers::sse_scratch_register as u32;
- codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
- ctx.builder.const_i32(dest as i32);
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn2(name);
- }
- fn sse_read128_xmm_xmm(ctx: &mut JitContext, name: &str, r1: u32, r2: u32) {
- // Make a copy to avoid aliasing problems: Called function expects a reg128, which must not
- // alias with memory
- codegen::gen_read_reg_xmm128_into_scratch(ctx, r1);
- let dest = global_pointers::sse_scratch_register;
- ctx.builder.const_i32(dest as i32);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2(name);
- }
- fn sse_mov_xmm_xmm(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r2) as i32);
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
- ctx.builder.load_aligned_i64(0);
- ctx.builder.store_aligned_i64(0);
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r2) as i32 + 8);
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32 + 8);
- ctx.builder.load_aligned_i64(0);
- ctx.builder.store_aligned_i64(0);
- }
- fn mmx_read64_mm_mem32(ctx: &mut JitContext, name: &str, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn2(name)
- }
- fn mmx_read64_mm_mm32(ctx: &mut JitContext, name: &str, r1: u32, r2: u32) {
- ctx.builder
- .const_i32(global_pointers::get_reg_mmx_offset(r1) as i32);
- ctx.builder.load_aligned_i32(0);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2(name);
- }
- fn mmx_read64_mm_mem(ctx: &mut JitContext, name: &str, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn2_i64_i32(name)
- }
- fn mmx_read64_mm_mm(ctx: &mut JitContext, name: &str, r1: u32, r2: u32) {
- ctx.builder
- .const_i32(global_pointers::get_reg_mmx_offset(r1) as i32);
- ctx.builder.load_aligned_i64(0);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2_i64_i32(name);
- }
- fn push16_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_reg16(ctx, r);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &value_local);
- ctx.builder.free_local(value_local);
- }
- fn push32_reg_jit(ctx: &mut JitContext, r: u32) {
- let reg = ctx.register_locals[r as usize].unsafe_clone();
- codegen::gen_push32(ctx, ®);
- }
- fn push16_imm_jit(ctx: &mut JitContext, imm: u32) {
- ctx.builder.const_i32(imm as i32);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &value_local);
- ctx.builder.free_local(value_local);
- }
- fn push32_imm_jit(ctx: &mut JitContext, imm: u32) {
- ctx.builder.const_i32(imm as i32);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &value_local);
- ctx.builder.free_local(value_local);
- }
- fn push16_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &value_local);
- ctx.builder.free_local(value_local);
- }
- fn push32_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &value_local);
- ctx.builder.free_local(value_local);
- }
- fn pop16_reg_jit(ctx: &mut JitContext, reg: u32) {
- codegen::gen_pop16(ctx);
- codegen::gen_set_reg16(ctx, reg);
- }
- fn pop32_reg_jit(ctx: &mut JitContext, reg: u32) {
- codegen::gen_pop32s(ctx);
- codegen::gen_set_reg32(ctx, reg);
- }
- fn group_arith_al_imm8(ctx: &mut JitContext, op: &str, imm8: u32) {
- codegen::gen_get_reg8(ctx, regs::AL);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2_ret(op);
- codegen::gen_set_reg8(ctx, regs::AL);
- }
- fn group_arith_ax_imm16(ctx: &mut JitContext, op: &str, imm16: u32) {
- codegen::gen_get_reg16(ctx, regs::AX);
- ctx.builder.const_i32(imm16 as i32);
- ctx.builder.call_fn2_ret(op);
- codegen::gen_set_reg16(ctx, regs::AX);
- }
- fn group_arith_eax_imm32(
- ctx: &mut JitContext,
- op: &dyn Fn(&mut WasmBuilder, &WasmLocal, &LocalOrImmediate),
- imm32: u32,
- ) {
- op(
- ctx.builder,
- &ctx.register_locals[regs::EAX as usize],
- &LocalOrImmediate::Immediate(imm32 as i32),
- );
- }
- macro_rules! define_instruction_read8(
- ($fn:expr, $name_mem:ident, $name_reg:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
- let dest_operand = ctx.builder.set_new_local();
- let source_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r);
- $fn(ctx.builder, &dest_operand, &LocalOrImmediate::WasmLocal(&source_operand));
- ctx.builder.free_local(dest_operand);
- codegen::gen_free_reg8_or_alias(ctx, r, source_operand);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r1);
- let source_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r2);
- $fn(ctx.builder, &dest_operand, &LocalOrImmediate::WasmLocal(&source_operand));
- codegen::gen_free_reg8_or_alias(ctx, r1, dest_operand);
- codegen::gen_free_reg8_or_alias(ctx, r2, source_operand);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
- let dest_operand = ctx.builder.set_new_local();
- let imm = mask_imm!(imm, $imm);
- $fn(ctx.builder, &dest_operand, &LocalOrImmediate::Immediate(imm as i32));
- ctx.builder.free_local(dest_operand);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, imm: u32) {
- let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r1);
- $fn(ctx.builder, &dest_operand, &LocalOrImmediate::Immediate(imm as i32));
- codegen::gen_free_reg8_or_alias(ctx, r1, dest_operand);
- }
- );
- );
- macro_rules! define_instruction_read16(
- ($fn:expr, $name_mem:ident, $name_reg:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- let dest_operand = ctx.builder.set_new_local();
- $fn(
- ctx.builder,
- &dest_operand,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize]),
- );
- ctx.builder.free_local(dest_operand);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- $fn(
- ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize])
- );
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- let dest_operand = ctx.builder.set_new_local();
- let imm = mask_imm!(imm, $imm);
- $fn(
- ctx.builder,
- &dest_operand,
- &LocalOrImmediate::Immediate(imm as i32),
- );
- ctx.builder.free_local(dest_operand);
- }
- pub fn $name_reg(ctx: &mut JitContext, r: u32, imm: u32) {
- $fn(
- ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::Immediate(imm as i32),
- );
- }
- );
- );
- macro_rules! define_instruction_read32(
- ($fn:expr, $name_mem:ident, $name_reg:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- let dest_operand = ctx.builder.set_new_local();
- $fn(
- ctx.builder,
- &dest_operand,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize]),
- );
- ctx.builder.free_local(dest_operand);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- $fn(
- ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize])
- );
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- let dest_operand = ctx.builder.set_new_local();
- let imm = mask_imm!(imm, $imm);
- $fn(
- ctx.builder,
- &dest_operand,
- &LocalOrImmediate::Immediate(imm as i32),
- );
- ctx.builder.free_local(dest_operand);
- }
- pub fn $name_reg(ctx: &mut JitContext, r: u32, imm: u32) {
- $fn(
- ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::Immediate(imm as i32),
- );
- }
- );
- );
- macro_rules! define_instruction_write_reg8(
- ($fn:expr, $name_mem:ident, $name_reg:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_get_reg8(ctx, r);
- codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg8(ctx, r);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg8(ctx, r2);
- codegen::gen_get_reg8(ctx, r1);
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg8(ctx, r2);
- }
- )
- );
- macro_rules! define_instruction_write_reg16(
- ($fn:expr, $name_mem:ident, $name_reg:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_get_reg16(ctx, r);
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg16(ctx, r);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg16(ctx, r2);
- codegen::gen_get_reg16(ctx, r1);
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg16(ctx, r2);
- }
- )
- );
- macro_rules! define_instruction_write_reg32(
- ($fn:expr, $name_mem:ident, $name_reg:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- let source_operand = ctx.builder.set_new_local();
- $fn(
- ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::WasmLocal(&source_operand),
- );
- ctx.builder.free_local(source_operand);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- $fn(
- ctx.builder,
- &ctx.register_locals[r2 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r1 as usize]),
- );
- }
- );
- );
- macro_rules! mask_imm(
- ($imm:expr, imm8_5bits) => { $imm & 31 };
- ($imm:expr, imm8) => { $imm };
- ($imm:expr, imm8s) => { $imm };
- ($imm:expr, imm16) => { $imm };
- ($imm:expr, imm32) => { $imm };
- );
- macro_rules! define_instruction_read_write_mem8(
- ($fn:expr, $name_mem:ident, $name_reg:ident, reg) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::BYTE, &address_local, &|ref mut ctx| {
- codegen::gen_get_reg8(ctx, r);
- ctx.builder.call_fn2_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg8(ctx, r1);
- codegen::gen_get_reg8(ctx, r2);
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg8(ctx, r1);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, constant_one) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::BYTE, &address_local, &|ref mut ctx| {
- ctx.builder.const_i32(1);
- ctx.builder.call_fn2_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
- codegen::gen_get_reg8(ctx, r1);
- ctx.builder.const_i32(1);
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg8(ctx, r1);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, cl) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::BYTE, &address_local, &|ref mut ctx| {
- codegen::gen_get_reg8(ctx, regs::CL);
- ctx.builder.const_i32(31);
- ctx.builder.and_i32();
- ctx.builder.call_fn2_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
- codegen::gen_get_reg8(ctx, r1);
- codegen::gen_get_reg8(ctx, regs::CL);
- ctx.builder.const_i32(31);
- ctx.builder.and_i32();
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg8(ctx, r1);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, none) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::BYTE, &address_local, &|ref mut ctx| {
- ctx.builder.call_fn1_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
- codegen::gen_get_reg8(ctx, r1);
- ctx.builder.call_fn1_ret($fn);
- codegen::gen_set_reg8(ctx, r1);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- let imm = mask_imm!(imm, $imm) as i32;
- codegen::gen_safe_read_write(ctx, BitSize::BYTE, &address_local, &|ref mut ctx| {
- ctx.builder.const_i32(imm as i32);
- ctx.builder.call_fn2_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, imm: u32) {
- let imm = mask_imm!(imm, $imm);
- codegen::gen_get_reg8(ctx, r1);
- ctx.builder.const_i32(imm as i32);
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg8(ctx, r1);
- }
- );
- );
- macro_rules! define_instruction_read_write_mem16(
- ($fn:expr, $name_mem:ident, $name_reg:ident, reg) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
- codegen::gen_get_reg16(ctx, r);
- ctx.builder.call_fn2_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg16(ctx, r1);
- codegen::gen_get_reg16(ctx, r2);
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg16(ctx, r1);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, constant_one) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
- ctx.builder.const_i32(1);
- ctx.builder.call_fn2_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
- codegen::gen_get_reg16(ctx, r1);
- ctx.builder.const_i32(1);
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg16(ctx, r1);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, cl) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
- codegen::gen_get_reg8(ctx, regs::CL);
- ctx.builder.const_i32(31);
- ctx.builder.and_i32();
- ctx.builder.call_fn2_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
- codegen::gen_get_reg16(ctx, r1);
- codegen::gen_get_reg8(ctx, regs::CL);
- ctx.builder.const_i32(31);
- ctx.builder.and_i32();
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg16(ctx, r1);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, reg, cl) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
- codegen::gen_get_reg16(ctx, r);
- codegen::gen_get_reg8(ctx, regs::CL);
- ctx.builder.const_i32(31);
- ctx.builder.and_i32();
- ctx.builder.call_fn3_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg16(ctx, r1);
- codegen::gen_get_reg16(ctx, r2);
- codegen::gen_get_reg8(ctx, regs::CL);
- ctx.builder.const_i32(31);
- ctx.builder.and_i32();
- ctx.builder.call_fn3_ret($fn);
- codegen::gen_set_reg16(ctx, r1);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, reg, $imm:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- let imm = mask_imm!(imm, $imm);
- codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
- codegen::gen_get_reg16(ctx, r);
- ctx.builder.const_i32(imm as i32);
- ctx.builder.call_fn3_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32, imm: u32) {
- let imm = mask_imm!(imm, $imm);
- codegen::gen_get_reg16(ctx, r1);
- codegen::gen_get_reg16(ctx, r2);
- ctx.builder.const_i32(imm as i32);
- ctx.builder.call_fn3_ret($fn);
- codegen::gen_set_reg16(ctx, r1);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, none) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
- let mut dest_operand = ctx.builder.set_new_local();
- $fn(ctx.builder, &mut dest_operand);
- ctx.builder.get_local(&dest_operand);
- ctx.builder.free_local(dest_operand);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
- $fn(ctx.builder, &mut ctx.register_locals[r1 as usize]);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- let imm = mask_imm!(imm, $imm) as i32;
- codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
- ctx.builder.const_i32(imm as i32);
- ctx.builder.call_fn2_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, imm: u32) {
- let imm = mask_imm!(imm, $imm);
- codegen::gen_get_reg16(ctx, r1);
- ctx.builder.const_i32(imm as i32);
- ctx.builder.call_fn2_ret($fn);
- codegen::gen_set_reg16(ctx, r1);
- }
- );
- );
- macro_rules! define_instruction_read_write_mem32(
- ($fn:expr, $name_mem:ident, $name_reg:ident, reg) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
- let dest_operand = ctx.builder.set_new_local();
- $fn(
- ctx.builder,
- &dest_operand,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize]),
- );
- ctx.builder.get_local(&dest_operand);
- ctx.builder.free_local(dest_operand);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- $fn(
- ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
- );
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, constant_one) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
- let dest_operand = ctx.builder.set_new_local();
- $fn(ctx.builder, &dest_operand, &LocalOrImmediate::Immediate(1));
- ctx.builder.get_local(&dest_operand);
- ctx.builder.free_local(dest_operand);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
- $fn(ctx.builder, &ctx.register_locals[r1 as usize], &LocalOrImmediate::Immediate(1));
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, cl) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
- let dest_operand = ctx.builder.set_new_local();
- $fn(
- ctx.builder,
- &dest_operand,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[regs::ECX as usize]),
- );
- ctx.builder.get_local(&dest_operand);
- ctx.builder.free_local(dest_operand);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
- $fn(
- ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[regs::ECX as usize]),
- );
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, reg, cl) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
- codegen::gen_get_reg32(ctx, r);
- codegen::gen_get_reg8(ctx, regs::CL);
- ctx.builder.const_i32(31);
- ctx.builder.and_i32();
- ctx.builder.call_fn3_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg32(ctx, r1);
- codegen::gen_get_reg32(ctx, r2);
- codegen::gen_get_reg8(ctx, regs::CL);
- ctx.builder.const_i32(31);
- ctx.builder.and_i32();
- ctx.builder.call_fn3_ret($fn);
- codegen::gen_set_reg32(ctx, r1);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, reg, $imm:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- let imm = mask_imm!(imm, $imm) as i32;
- codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
- codegen::gen_get_reg32(ctx, r);
- ctx.builder.const_i32(imm as i32);
- ctx.builder.call_fn3_ret($fn);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32, imm: u32) {
- let imm = mask_imm!(imm, $imm);
- codegen::gen_get_reg32(ctx, r1);
- codegen::gen_get_reg32(ctx, r2);
- ctx.builder.const_i32(imm as i32);
- ctx.builder.call_fn3_ret($fn);
- codegen::gen_set_reg32(ctx, r1);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, none) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
- let mut dest_operand = ctx.builder.set_new_local();
- $fn(ctx.builder, &mut dest_operand);
- ctx.builder.get_local(&dest_operand);
- ctx.builder.free_local(dest_operand);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32) {
- $fn(ctx.builder, &mut ctx.register_locals[r1 as usize]);
- }
- );
- ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- let imm = mask_imm!(imm, $imm) as i32;
- codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
- let dest_operand = ctx.builder.set_new_local();
- $fn(
- ctx.builder,
- &dest_operand,
- &LocalOrImmediate::Immediate(imm),
- );
- ctx.builder.get_local(&dest_operand);
- ctx.builder.free_local(dest_operand);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, imm: u32) {
- let imm = mask_imm!(imm, $imm);
- $fn(
- ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::Immediate(imm as i32),
- );
- }
- );
- );
- fn gen_add32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- codegen::gen_set_last_op1(builder, &dest_operand);
- builder.get_local(&dest_operand);
- source_operand.gen_get(builder);
- builder.add_i32();
- builder.set_local(dest_operand);
- codegen::gen_set_last_result(builder, &dest_operand);
- codegen::gen_set_last_op_size(builder, OPSIZE_32);
- codegen::gen_set_flags_changed(builder, FLAGS_ALL);
- }
- fn gen_sub32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- codegen::gen_set_last_op1(builder, &dest_operand);
- builder.get_local(&dest_operand);
- source_operand.gen_get(builder);
- builder.sub_i32();
- builder.set_local(dest_operand);
- codegen::gen_set_last_result(builder, &dest_operand);
- codegen::gen_set_last_op_size(builder, OPSIZE_32);
- codegen::gen_set_flags_changed(builder, FLAGS_ALL | FLAG_SUB);
- }
- fn gen_cmp(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- size: i32,
- ) {
- builder.const_i32(global_pointers::last_result as i32);
- builder.get_local(&dest_operand);
- source_operand.gen_get(builder);
- builder.sub_i32();
- if size == OPSIZE_8 || size == OPSIZE_16 {
- builder.const_i32(if size == OPSIZE_8 { 0xFF } else { 0xFFFF });
- builder.and_i32();
- }
- builder.store_aligned_i32(0);
- builder.const_i32(global_pointers::last_op1 as i32);
- builder.get_local(&dest_operand);
- if size == OPSIZE_8 || size == OPSIZE_16 {
- builder.const_i32(if size == OPSIZE_8 { 0xFF } else { 0xFFFF });
- builder.and_i32();
- }
- builder.store_aligned_i32(0);
- codegen::gen_set_last_op_size(builder, size);
- codegen::gen_set_flags_changed(builder, FLAGS_ALL | FLAG_SUB);
- }
- fn gen_cmp8(builder: &mut WasmBuilder, dest: &WasmLocal, source: &LocalOrImmediate) {
- gen_cmp(builder, dest, source, OPSIZE_8)
- }
- fn gen_cmp16(builder: &mut WasmBuilder, dest: &WasmLocal, source: &LocalOrImmediate) {
- gen_cmp(builder, dest, source, OPSIZE_16)
- }
- fn gen_cmp32(builder: &mut WasmBuilder, dest: &WasmLocal, source: &LocalOrImmediate) {
- gen_cmp(builder, dest, source, OPSIZE_32)
- }
- fn gen_adc32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- builder.get_local(&dest_operand);
- source_operand.gen_get(builder);
- builder.call_fn2_ret("adc32");
- builder.set_local(dest_operand);
- }
- fn gen_sbb32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- builder.get_local(&dest_operand);
- source_operand.gen_get(builder);
- builder.call_fn2_ret("sbb32");
- builder.set_local(dest_operand);
- }
- fn gen_and32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- builder.get_local(&dest_operand);
- source_operand.gen_get(builder);
- builder.and_i32();
- builder.set_local(dest_operand);
- codegen::gen_set_last_result(builder, &dest_operand);
- codegen::gen_set_last_op_size(builder, OPSIZE_32);
- codegen::gen_set_flags_changed(
- builder,
- FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
- );
- codegen::gen_clear_flags_bits(builder, FLAG_CARRY | FLAG_OVERFLOW | FLAG_ADJUST);
- }
- fn gen_test(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- size: i32,
- ) {
- builder.const_i32(global_pointers::last_result as i32);
- builder.get_local(&dest_operand);
- source_operand.gen_get(builder);
- builder.and_i32();
- builder.store_aligned_i32(0);
- codegen::gen_set_last_op_size(builder, size);
- codegen::gen_set_flags_changed(
- builder,
- FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
- );
- codegen::gen_clear_flags_bits(builder, FLAG_CARRY | FLAG_OVERFLOW | FLAG_ADJUST);
- }
- fn gen_test8(builder: &mut WasmBuilder, dest: &WasmLocal, source: &LocalOrImmediate) {
- gen_test(builder, dest, source, OPSIZE_8)
- }
- fn gen_test16(builder: &mut WasmBuilder, dest: &WasmLocal, source: &LocalOrImmediate) {
- gen_test(builder, dest, source, OPSIZE_16)
- }
- fn gen_test32(builder: &mut WasmBuilder, dest: &WasmLocal, source: &LocalOrImmediate) {
- gen_test(builder, dest, source, OPSIZE_32)
- }
- fn gen_or32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- builder.get_local(&dest_operand);
- source_operand.gen_get(builder);
- builder.or_i32();
- builder.set_local(dest_operand);
- codegen::gen_set_last_result(builder, &dest_operand);
- codegen::gen_set_last_op_size(builder, OPSIZE_32);
- codegen::gen_set_flags_changed(
- builder,
- FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
- );
- codegen::gen_clear_flags_bits(builder, FLAG_CARRY | FLAG_OVERFLOW | FLAG_ADJUST);
- }
- fn gen_xor32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- builder.get_local(&dest_operand);
- source_operand.gen_get(builder);
- builder.xor_i32();
- builder.set_local(dest_operand);
- codegen::gen_set_last_result(builder, &dest_operand);
- codegen::gen_set_last_op_size(builder, OPSIZE_32);
- codegen::gen_set_flags_changed(
- builder,
- FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW & !FLAG_ADJUST,
- );
- codegen::gen_clear_flags_bits(builder, FLAG_CARRY | FLAG_OVERFLOW | FLAG_ADJUST);
- }
- fn gen_rol32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- builder.get_local(dest_operand);
- match source_operand {
- LocalOrImmediate::WasmLocal(l) => {
- builder.get_local(l);
- builder.const_i32(31);
- builder.and_i32();
- },
- LocalOrImmediate::Immediate(i) => {
- builder.const_i32(*i & 31);
- },
- }
- builder.const_i32(31);
- builder.and_i32();
- builder.call_fn2_ret("rol32");
- builder.set_local(dest_operand);
- }
- fn gen_ror32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- builder.get_local(dest_operand);
- match source_operand {
- LocalOrImmediate::WasmLocal(l) => {
- builder.get_local(l);
- builder.const_i32(31);
- builder.and_i32();
- },
- LocalOrImmediate::Immediate(i) => {
- builder.const_i32(*i & 31);
- },
- }
- builder.const_i32(31);
- builder.and_i32();
- builder.call_fn2_ret("ror32");
- builder.set_local(dest_operand);
- }
- fn gen_rcl32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- builder.get_local(dest_operand);
- match source_operand {
- LocalOrImmediate::WasmLocal(l) => {
- builder.get_local(l);
- builder.const_i32(31);
- builder.and_i32();
- },
- LocalOrImmediate::Immediate(i) => {
- builder.const_i32(*i & 31);
- },
- }
- builder.const_i32(31);
- builder.and_i32();
- builder.call_fn2_ret("rcl32");
- builder.set_local(dest_operand);
- }
- fn gen_rcr32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- builder.get_local(dest_operand);
- match source_operand {
- LocalOrImmediate::WasmLocal(l) => {
- builder.get_local(l);
- builder.const_i32(31);
- builder.and_i32();
- },
- LocalOrImmediate::Immediate(i) => {
- builder.const_i32(*i & 31);
- },
- }
- builder.const_i32(31);
- builder.and_i32();
- builder.call_fn2_ret("rcr32");
- builder.set_local(dest_operand);
- }
- enum ShiftCount {
- Local(WasmLocal),
- Immediate(i32),
- }
- impl ShiftCount {
- pub fn gen_get(builder: &mut WasmBuilder, count: &ShiftCount) {
- match &count {
- ShiftCount::Local(l) => builder.get_local(l),
- ShiftCount::Immediate(i) => builder.const_i32(*i),
- }
- }
- pub fn gen_get_thirtytwo_minus(builder: &mut WasmBuilder, count: &ShiftCount) {
- match &count {
- ShiftCount::Local(l) => {
- builder.const_i32(32);
- builder.get_local(l);
- builder.sub_i32();
- },
- ShiftCount::Immediate(i) => builder.const_i32(32 - *i),
- }
- }
- pub fn gen_get_minus_one(builder: &mut WasmBuilder, count: &ShiftCount) {
- match &count {
- ShiftCount::Local(l) => {
- builder.get_local(l);
- builder.const_i32(1);
- builder.sub_i32()
- },
- ShiftCount::Immediate(i) => builder.const_i32(*i - 1),
- }
- }
- }
- fn gen_shl32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- let count = match source_operand {
- LocalOrImmediate::WasmLocal(l) => {
- let exit = builder.block_void();
- builder.get_local(l);
- builder.const_i32(31); // Note: mask can probably be avoided since wasm has the same semantics on shl_i32
- builder.and_i32();
- let count = builder.tee_new_local();
- builder.eqz_i32();
- builder.br_if(exit);
- ShiftCount::Local(count)
- },
- LocalOrImmediate::Immediate(i) => {
- if *i & 31 == 0 {
- return;
- }
- ShiftCount::Immediate(*i & 31)
- },
- };
- builder.get_local(&dest_operand);
- ShiftCount::gen_get_thirtytwo_minus(builder, &count);
- builder.shr_u_i32();
- builder.const_i32(1);
- builder.and_i32();
- let b = builder.set_new_local();
- builder.get_local(dest_operand);
- ShiftCount::gen_get(builder, &count);
- builder.shl_i32();
- builder.set_local(dest_operand);
- codegen::gen_set_last_result(builder, dest_operand);
- codegen::gen_set_last_op_size(builder, OPSIZE_32);
- codegen::gen_set_flags_changed(builder, FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW);
- builder.const_i32(global_pointers::flags as i32);
- codegen::gen_get_flags(builder);
- builder.const_i32(!(FLAG_CARRY | FLAG_OVERFLOW));
- builder.and_i32();
- builder.get_local(&b);
- builder.or_i32();
- {
- builder.get_local(&b);
- builder.get_local(&dest_operand);
- builder.const_i32(31);
- builder.shr_u_i32();
- builder.xor_i32();
- builder.const_i32(11);
- builder.shl_i32();
- builder.const_i32(FLAG_OVERFLOW);
- builder.and_i32();
- builder.or_i32();
- }
- builder.store_aligned_i32(0);
- builder.free_local(b);
- if let ShiftCount::Local(l) = count {
- builder.block_end();
- builder.free_local(l);
- }
- }
- fn gen_shr32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- let count = match source_operand {
- LocalOrImmediate::WasmLocal(l) => {
- let exit = builder.block_void();
- builder.get_local(l);
- builder.const_i32(31); // Note: mask can probably be avoided since wasm has the same semantics on shl_i32
- builder.and_i32();
- let count = builder.tee_new_local();
- builder.eqz_i32();
- builder.br_if(exit);
- ShiftCount::Local(count)
- },
- LocalOrImmediate::Immediate(i) => {
- if *i & 31 == 0 {
- return;
- }
- ShiftCount::Immediate(*i & 31)
- },
- };
- builder.const_i32(global_pointers::flags as i32);
- codegen::gen_get_flags(builder);
- builder.const_i32(!(FLAG_CARRY | FLAG_OVERFLOW));
- builder.and_i32();
- {
- builder.get_local(dest_operand);
- ShiftCount::gen_get_minus_one(builder, &count);
- builder.shr_u_i32();
- builder.const_i32(1);
- builder.and_i32();
- builder.or_i32()
- }
- {
- builder.get_local(dest_operand);
- builder.const_i32(20);
- builder.shr_u_i32();
- builder.const_i32(FLAG_OVERFLOW);
- builder.and_i32();
- builder.or_i32()
- }
- builder.store_aligned_i32(0);
- builder.get_local(dest_operand);
- ShiftCount::gen_get(builder, &count);
- builder.shr_u_i32();
- builder.set_local(dest_operand);
- codegen::gen_set_last_result(builder, dest_operand);
- codegen::gen_set_last_op_size(builder, OPSIZE_32);
- codegen::gen_set_flags_changed(builder, FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW);
- if let ShiftCount::Local(l) = count {
- builder.block_end();
- builder.free_local(l);
- }
- }
- fn gen_sar32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- let count = match source_operand {
- LocalOrImmediate::WasmLocal(l) => {
- let exit = builder.block_void();
- builder.get_local(l);
- builder.const_i32(31); // Note: mask can probably be avoided since wasm has the same semantics on shl_i32
- builder.and_i32();
- let count = builder.tee_new_local();
- builder.eqz_i32();
- builder.br_if(exit);
- ShiftCount::Local(count)
- },
- LocalOrImmediate::Immediate(i) => {
- if *i & 31 == 0 {
- return;
- }
- ShiftCount::Immediate(*i & 31)
- },
- };
- builder.const_i32(global_pointers::flags as i32);
- codegen::gen_get_flags(builder);
- builder.const_i32(!(FLAG_CARRY | FLAG_OVERFLOW));
- builder.and_i32();
- {
- builder.get_local(dest_operand);
- ShiftCount::gen_get_minus_one(builder, &count);
- builder.shr_u_i32();
- builder.const_i32(1);
- builder.and_i32();
- builder.or_i32()
- }
- builder.store_aligned_i32(0);
- builder.get_local(dest_operand);
- ShiftCount::gen_get(builder, &count);
- builder.shr_s_i32();
- builder.set_local(dest_operand);
- codegen::gen_set_last_result(builder, dest_operand);
- codegen::gen_set_last_op_size(builder, OPSIZE_32);
- codegen::gen_set_flags_changed(builder, FLAGS_ALL & !FLAG_CARRY & !FLAG_OVERFLOW);
- if let ShiftCount::Local(l) = count {
- builder.block_end();
- builder.free_local(l);
- }
- }
- fn gen_xadd32(ctx: &mut JitContext, dest_operand: &WasmLocal, r: u32) {
- ctx.builder.get_local(&ctx.register_locals[r as usize]);
- let tmp = ctx.builder.set_new_local();
- ctx.builder.get_local(&dest_operand);
- codegen::gen_set_reg32(ctx, r);
- gen_add32(
- ctx.builder,
- &dest_operand,
- &LocalOrImmediate::WasmLocal(&tmp),
- );
- ctx.builder.free_local(tmp);
- }
- fn gen_cmpxchg32(ctx: &mut JitContext, r: u32) {
- let source = ctx.builder.set_new_local();
- gen_cmp32(
- ctx.builder,
- &ctx.register_locals[0],
- &LocalOrImmediate::WasmLocal(&source),
- );
- ctx.builder.get_local(&ctx.register_locals[0]);
- ctx.builder.get_local(&source);
- ctx.builder.eq_i32();
- ctx.builder.if_i32();
- codegen::gen_get_reg32(ctx, r);
- ctx.builder.else_();
- ctx.builder.get_local(&source);
- codegen::gen_set_reg32(ctx, regs::EAX);
- ctx.builder.get_local(&source);
- ctx.builder.block_end();
- ctx.builder.free_local(source);
- }
- fn gen_mul32(ctx: &mut JitContext) {
- ctx.builder.extend_unsigned_i32_to_i64();
- codegen::gen_get_reg32(ctx, regs::EAX);
- ctx.builder.extend_unsigned_i32_to_i64();
- ctx.builder.mul_i64();
- let result = ctx.builder.tee_new_local_i64();
- ctx.builder.const_i64(32);
- ctx.builder.shr_u_i64();
- ctx.builder.wrap_i64_to_i32();
- codegen::gen_set_reg32(ctx, regs::EDX);
- ctx.builder.get_local_i64(&result);
- ctx.builder.free_local_i64(result);
- ctx.builder.wrap_i64_to_i32();
- codegen::gen_set_reg32(ctx, regs::EAX);
- codegen::gen_get_reg32(ctx, regs::EDX);
- ctx.builder.if_void();
- codegen::gen_set_flags_bits(ctx.builder, 1 | FLAG_OVERFLOW);
- ctx.builder.else_();
- codegen::gen_clear_flags_bits(ctx.builder, 1 | FLAG_OVERFLOW);
- ctx.builder.block_end();
- codegen::gen_set_last_result(ctx.builder, &ctx.register_locals[regs::EAX as usize]);
- codegen::gen_set_last_op_size(ctx.builder, OPSIZE_32);
- codegen::gen_set_flags_changed(ctx.builder, FLAGS_ALL & !1 & !FLAG_OVERFLOW);
- }
- fn gen_imul32(ctx: &mut JitContext) {
- ctx.builder.extend_signed_i32_to_i64();
- codegen::gen_get_reg32(ctx, regs::EAX);
- ctx.builder.extend_signed_i32_to_i64();
- ctx.builder.mul_i64();
- let result = ctx.builder.tee_new_local_i64();
- ctx.builder.const_i64(32);
- ctx.builder.shr_u_i64();
- ctx.builder.wrap_i64_to_i32();
- codegen::gen_set_reg32(ctx, regs::EDX);
- ctx.builder.get_local_i64(&result);
- ctx.builder.free_local_i64(result);
- ctx.builder.wrap_i64_to_i32();
- codegen::gen_set_reg32(ctx, regs::EAX);
- codegen::gen_get_reg32(ctx, regs::EDX);
- codegen::gen_get_reg32(ctx, regs::EAX);
- ctx.builder.const_i32(31);
- ctx.builder.shr_s_i32();
- ctx.builder.eq_i32();
- ctx.builder.if_void();
- codegen::gen_clear_flags_bits(ctx.builder, 1 | FLAG_OVERFLOW);
- ctx.builder.else_();
- codegen::gen_set_flags_bits(ctx.builder, 1 | FLAG_OVERFLOW);
- ctx.builder.block_end();
- codegen::gen_set_last_result(ctx.builder, &ctx.register_locals[regs::EAX as usize]);
- codegen::gen_set_last_op_size(ctx.builder, OPSIZE_32);
- codegen::gen_set_flags_changed(ctx.builder, FLAGS_ALL & !1 & !FLAG_OVERFLOW);
- }
- fn gen_imul_reg32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- gen_imul3_reg32(builder, dest_operand, dest_operand, source_operand);
- }
- fn gen_imul3_reg32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand1: &WasmLocal,
- source_operand2: &LocalOrImmediate,
- ) {
- builder.get_local(&source_operand1);
- builder.extend_signed_i32_to_i64();
- source_operand2.gen_get(builder);
- builder.extend_signed_i32_to_i64();
- builder.mul_i64();
- let result = builder.tee_new_local_i64();
- builder.wrap_i64_to_i32();
- builder.set_local(&dest_operand);
- codegen::gen_set_last_result(builder, &dest_operand);
- codegen::gen_set_last_op_size(builder, OPSIZE_32);
- codegen::gen_set_flags_changed(builder, FLAGS_ALL & !1 & !FLAG_OVERFLOW);
- builder.const_i32(global_pointers::flags as i32);
- builder.get_local_i64(&result);
- builder.wrap_i64_to_i32();
- builder.extend_signed_i32_to_i64();
- builder.get_local_i64(&result);
- builder.ne_i64();
- builder.const_i32(1 | FLAG_OVERFLOW);
- builder.mul_i32();
- codegen::gen_get_flags(builder);
- builder.const_i32(!1 & !FLAG_OVERFLOW);
- builder.and_i32();
- builder.or_i32();
- builder.store_aligned_i32(0);
- builder.free_local_i64(result);
- }
- fn gen_div32(ctx: &mut JitContext, source: &WasmLocal) {
- let done = ctx.builder.block_void();
- {
- let exception = ctx.builder.block_void();
- {
- ctx.builder.get_local(source);
- ctx.builder.eqz_i32();
- ctx.builder.br_if(exception);
- codegen::gen_get_reg32(ctx, regs::EDX);
- ctx.builder.extend_unsigned_i32_to_i64();
- ctx.builder.const_i64(32);
- ctx.builder.shl_i64();
- codegen::gen_get_reg32(ctx, regs::EAX);
- ctx.builder.extend_unsigned_i32_to_i64();
- ctx.builder.or_i64();
- let dest_operand = ctx.builder.tee_new_local_i64();
- ctx.builder.get_local(source);
- ctx.builder.extend_unsigned_i32_to_i64();
- ctx.builder.div_i64();
- let result = ctx.builder.tee_new_local_i64();
- ctx.builder.const_i64(0xFFFF_FFFF);
- ctx.builder.gtu_i64();
- ctx.builder.br_if(exception);
- ctx.builder.get_local_i64(&dest_operand);
- ctx.builder.get_local(source);
- ctx.builder.extend_unsigned_i32_to_i64();
- ctx.builder.rem_i64();
- ctx.builder.wrap_i64_to_i32();
- codegen::gen_set_reg32(ctx, regs::EDX);
- ctx.builder.get_local_i64(&result);
- ctx.builder.wrap_i64_to_i32();
- codegen::gen_set_reg32(ctx, regs::EAX);
- ctx.builder.br(done);
- ctx.builder.free_local_i64(dest_operand);
- ctx.builder.free_local_i64(result);
- }
- ctx.builder.block_end();
- codegen::gen_trigger_de(ctx);
- }
- ctx.builder.block_end();
- }
- fn gen_bt(
- builder: &mut WasmBuilder,
- bit_base: &WasmLocal,
- bit_offset: &LocalOrImmediate,
- offset_mask: u32,
- ) {
- builder.const_i32(global_pointers::flags as i32);
- codegen::gen_get_flags(builder);
- builder.const_i32(!1);
- builder.and_i32();
- builder.get_local(bit_base);
- match bit_offset {
- LocalOrImmediate::WasmLocal(l) => {
- builder.get_local(l);
- builder.const_i32(offset_mask as i32);
- builder.and_i32();
- },
- LocalOrImmediate::Immediate(imm) => builder.const_i32(imm & offset_mask as i32),
- }
- builder.shr_u_i32();
- builder.const_i32(1);
- builder.and_i32();
- builder.or_i32();
- builder.store_aligned_i32(0);
- codegen::gen_clear_flags_changed_bits(builder, 1);
- }
- fn gen_bts(
- builder: &mut WasmBuilder,
- dest_bit_base: &WasmLocal,
- bit_offset: &LocalOrImmediate,
- offset_mask: u32,
- ) {
- gen_bt(builder, dest_bit_base, bit_offset, offset_mask);
- builder.get_local(dest_bit_base);
- match bit_offset {
- LocalOrImmediate::WasmLocal(l) => {
- builder.const_i32(1);
- builder.get_local(l);
- builder.const_i32(offset_mask as i32);
- builder.and_i32();
- builder.shl_i32();
- },
- LocalOrImmediate::Immediate(imm) => builder.const_i32(1 << (imm & offset_mask as i32)),
- }
- builder.or_i32();
- builder.set_local(dest_bit_base);
- }
- fn gen_btc(
- builder: &mut WasmBuilder,
- dest_bit_base: &WasmLocal,
- bit_offset: &LocalOrImmediate,
- offset_mask: u32,
- ) {
- gen_bt(builder, dest_bit_base, bit_offset, offset_mask);
- builder.get_local(dest_bit_base);
- match bit_offset {
- LocalOrImmediate::WasmLocal(l) => {
- builder.const_i32(1);
- builder.get_local(l);
- builder.const_i32(offset_mask as i32);
- builder.and_i32();
- builder.shl_i32();
- },
- LocalOrImmediate::Immediate(imm) => builder.const_i32(1 << (imm & offset_mask as i32)),
- }
- builder.xor_i32();
- builder.set_local(dest_bit_base);
- }
- fn gen_btr(
- builder: &mut WasmBuilder,
- dest_bit_base: &WasmLocal,
- bit_offset: &LocalOrImmediate,
- offset_mask: u32,
- ) {
- gen_bt(builder, dest_bit_base, bit_offset, offset_mask);
- builder.get_local(dest_bit_base);
- match bit_offset {
- LocalOrImmediate::WasmLocal(l) => {
- builder.const_i32(1);
- builder.get_local(l);
- builder.const_i32(offset_mask as i32);
- builder.and_i32();
- builder.shl_i32();
- builder.const_i32(-1);
- builder.xor_i32();
- },
- LocalOrImmediate::Immediate(imm) => builder.const_i32(!(1 << (imm & offset_mask as i32))),
- }
- builder.and_i32();
- builder.set_local(dest_bit_base);
- }
- fn gen_bit_rmw(
- ctx: &mut JitContext,
- modrm_byte: ModrmByte,
- op: &dyn Fn(&mut WasmBuilder, &WasmLocal, &LocalOrImmediate, u32),
- source_operand: &LocalOrImmediate,
- opsize: i32,
- ) {
- dbg_assert!(opsize == 16 || opsize == 32);
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- match source_operand {
- LocalOrImmediate::WasmLocal(l) => {
- ctx.builder.get_local(l);
- if opsize == 16 {
- codegen::sign_extend_i16(ctx.builder);
- }
- ctx.builder.const_i32(3);
- ctx.builder.shr_s_i32();
- ctx.builder.add_i32();
- },
- LocalOrImmediate::Immediate(imm8) => {
- ctx.builder.const_i32((*imm8 as i32 & (opsize - 1)) >> 3);
- ctx.builder.add_i32();
- },
- }
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::BYTE, &address_local, &|ref mut ctx| {
- let value_local = ctx.builder.set_new_local();
- op(ctx.builder, &value_local, source_operand, 7);
- ctx.builder.get_local(&value_local);
- ctx.builder.free_local(value_local);
- });
- ctx.builder.free_local(address_local);
- }
- fn gen_bsf32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- builder.get_local(&dest_operand);
- source_operand.gen_get(builder);
- builder.call_fn2_ret("bsf32");
- builder.set_local(dest_operand);
- }
- fn gen_bsr32(
- builder: &mut WasmBuilder,
- dest_operand: &WasmLocal,
- source_operand: &LocalOrImmediate,
- ) {
- builder.get_local(&dest_operand);
- source_operand.gen_get(builder);
- builder.call_fn2_ret("bsr32");
- builder.set_local(dest_operand);
- }
- fn gen_bswap(ctx: &mut JitContext, reg: i32) {
- let l = &ctx.register_locals[reg as usize];
- ctx.builder.get_local(l);
- ctx.builder.const_i32(8);
- ctx.builder.rotl_i32();
- ctx.builder.const_i32(0xFF00FF);
- ctx.builder.and_i32();
- ctx.builder.get_local(l);
- ctx.builder.const_i32(24);
- ctx.builder.rotl_i32();
- ctx.builder.const_i32(0xFF00FF00u32 as i32);
- ctx.builder.and_i32();
- ctx.builder.or_i32();
- ctx.builder.set_local(l);
- }
- define_instruction_read_write_mem8!("add8", instr_00_mem_jit, instr_00_reg_jit, reg);
- define_instruction_read_write_mem16!("add16", instr16_01_mem_jit, instr16_01_reg_jit, reg);
- define_instruction_read_write_mem32!(gen_add32, instr32_01_mem_jit, instr32_01_reg_jit, reg);
- define_instruction_write_reg8!("add8", instr_02_mem_jit, instr_02_reg_jit);
- define_instruction_write_reg16!("add16", instr16_03_mem_jit, instr16_03_reg_jit);
- define_instruction_write_reg32!(gen_add32, instr32_03_mem_jit, instr32_03_reg_jit);
- pub fn instr_04_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, "add8", imm8); }
- pub fn instr16_05_jit(ctx: &mut JitContext, imm16: u32) {
- group_arith_ax_imm16(ctx, "add16", imm16);
- }
- pub fn instr32_05_jit(ctx: &mut JitContext, imm32: u32) {
- group_arith_eax_imm32(ctx, &gen_add32, imm32);
- }
- define_instruction_read_write_mem8!("or8", instr_08_mem_jit, instr_08_reg_jit, reg);
- define_instruction_read_write_mem16!("or16", instr16_09_mem_jit, instr16_09_reg_jit, reg);
- define_instruction_read_write_mem32!(gen_or32, instr32_09_mem_jit, instr32_09_reg_jit, reg);
- define_instruction_write_reg8!("or8", instr_0A_mem_jit, instr_0A_reg_jit);
- define_instruction_write_reg16!("or16", instr16_0B_mem_jit, instr16_0B_reg_jit);
- define_instruction_write_reg32!(gen_or32, instr32_0B_mem_jit, instr32_0B_reg_jit);
- pub fn instr_0C_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, "or8", imm8); }
- pub fn instr16_0D_jit(ctx: &mut JitContext, imm16: u32) {
- group_arith_ax_imm16(ctx, "or16", imm16);
- }
- pub fn instr32_0D_jit(ctx: &mut JitContext, imm32: u32) {
- group_arith_eax_imm32(ctx, &gen_or32, imm32);
- }
- define_instruction_read_write_mem8!("adc8", instr_10_mem_jit, instr_10_reg_jit, reg);
- define_instruction_read_write_mem16!("adc16", instr16_11_mem_jit, instr16_11_reg_jit, reg);
- define_instruction_read_write_mem32!(gen_adc32, instr32_11_mem_jit, instr32_11_reg_jit, reg);
- define_instruction_write_reg8!("adc8", instr_12_mem_jit, instr_12_reg_jit);
- define_instruction_write_reg16!("adc16", instr16_13_mem_jit, instr16_13_reg_jit);
- define_instruction_write_reg32!(gen_adc32, instr32_13_mem_jit, instr32_13_reg_jit);
- pub fn instr_14_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, "adc8", imm8); }
- pub fn instr16_15_jit(ctx: &mut JitContext, imm16: u32) {
- group_arith_ax_imm16(ctx, "adc16", imm16);
- }
- pub fn instr32_15_jit(ctx: &mut JitContext, imm32: u32) {
- group_arith_eax_imm32(ctx, &gen_adc32, imm32);
- }
- define_instruction_read_write_mem8!("sbb8", instr_18_mem_jit, instr_18_reg_jit, reg);
- define_instruction_read_write_mem16!("sbb16", instr16_19_mem_jit, instr16_19_reg_jit, reg);
- define_instruction_read_write_mem32!(gen_sbb32, instr32_19_mem_jit, instr32_19_reg_jit, reg);
- define_instruction_write_reg8!("sbb8", instr_1A_mem_jit, instr_1A_reg_jit);
- define_instruction_write_reg16!("sbb16", instr16_1B_mem_jit, instr16_1B_reg_jit);
- define_instruction_write_reg32!(gen_sbb32, instr32_1B_mem_jit, instr32_1B_reg_jit);
- pub fn instr_1C_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, "sbb8", imm8); }
- pub fn instr16_1D_jit(ctx: &mut JitContext, imm16: u32) {
- group_arith_ax_imm16(ctx, "sbb16", imm16);
- }
- pub fn instr32_1D_jit(ctx: &mut JitContext, imm32: u32) {
- group_arith_eax_imm32(ctx, &gen_sbb32, imm32);
- }
- define_instruction_read_write_mem8!("and8", instr_20_mem_jit, instr_20_reg_jit, reg);
- define_instruction_read_write_mem16!("and16", instr16_21_mem_jit, instr16_21_reg_jit, reg);
- define_instruction_read_write_mem32!(gen_and32, instr32_21_mem_jit, instr32_21_reg_jit, reg);
- define_instruction_write_reg8!("and8", instr_22_mem_jit, instr_22_reg_jit);
- define_instruction_write_reg16!("and16", instr16_23_mem_jit, instr16_23_reg_jit);
- define_instruction_write_reg32!(gen_and32, instr32_23_mem_jit, instr32_23_reg_jit);
- pub fn instr_24_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, "and8", imm8); }
- pub fn instr16_25_jit(ctx: &mut JitContext, imm16: u32) {
- group_arith_ax_imm16(ctx, "and16", imm16);
- }
- pub fn instr32_25_jit(ctx: &mut JitContext, imm32: u32) {
- group_arith_eax_imm32(ctx, &gen_and32, imm32);
- }
- define_instruction_read_write_mem8!("sub8", instr_28_mem_jit, instr_28_reg_jit, reg);
- define_instruction_read_write_mem16!("sub16", instr16_29_mem_jit, instr16_29_reg_jit, reg);
- define_instruction_read_write_mem32!(gen_sub32, instr32_29_mem_jit, instr32_29_reg_jit, reg);
- define_instruction_write_reg8!("sub8", instr_2A_mem_jit, instr_2A_reg_jit);
- define_instruction_write_reg16!("sub16", instr16_2B_mem_jit, instr16_2B_reg_jit);
- define_instruction_write_reg32!(gen_sub32, instr32_2B_mem_jit, instr32_2B_reg_jit);
- pub fn instr_2C_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, "sub8", imm8); }
- pub fn instr16_2D_jit(ctx: &mut JitContext, imm16: u32) {
- group_arith_ax_imm16(ctx, "sub16", imm16);
- }
- pub fn instr32_2D_jit(ctx: &mut JitContext, imm32: u32) {
- group_arith_eax_imm32(ctx, &gen_sub32, imm32);
- }
- define_instruction_read_write_mem8!("xor8", instr_30_mem_jit, instr_30_reg_jit, reg);
- define_instruction_read_write_mem16!("xor16", instr16_31_mem_jit, instr16_31_reg_jit, reg);
- define_instruction_read_write_mem32!(gen_xor32, instr32_31_mem_jit, instr32_31_reg_jit, reg);
- define_instruction_write_reg8!("xor8", instr_32_mem_jit, instr_32_reg_jit);
- define_instruction_write_reg16!("xor16", instr16_33_mem_jit, instr16_33_reg_jit);
- define_instruction_write_reg32!(gen_xor32, instr32_33_mem_jit, instr32_33_reg_jit);
- pub fn instr_34_jit(ctx: &mut JitContext, imm8: u32) { group_arith_al_imm8(ctx, "xor8", imm8); }
- pub fn instr16_35_jit(ctx: &mut JitContext, imm16: u32) {
- group_arith_ax_imm16(ctx, "xor16", imm16);
- }
- pub fn instr32_35_jit(ctx: &mut JitContext, imm32: u32) {
- group_arith_eax_imm32(ctx, &gen_xor32, imm32);
- }
- define_instruction_read8!(gen_cmp8, instr_38_mem_jit, instr_38_reg_jit);
- define_instruction_read16!(gen_cmp16, instr16_39_mem_jit, instr16_39_reg_jit);
- define_instruction_read32!(gen_cmp32, instr32_39_mem_jit, instr32_39_reg_jit);
- pub fn instr_3A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r);
- codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
- let source_operand = ctx.builder.set_new_local();
- gen_cmp8(
- ctx.builder,
- &dest_operand,
- &LocalOrImmediate::WasmLocal(&source_operand),
- );
- codegen::gen_free_reg8_or_alias(ctx, r, dest_operand);
- ctx.builder.free_local(source_operand);
- }
- pub fn instr_3A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- let dest_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r2);
- let source_operand = codegen::gen_get_reg8_or_alias_to_reg32(ctx, r1);
- gen_cmp8(
- ctx.builder,
- &dest_operand,
- &LocalOrImmediate::WasmLocal(&source_operand),
- );
- codegen::gen_free_reg8_or_alias(ctx, r2, dest_operand);
- codegen::gen_free_reg8_or_alias(ctx, r1, source_operand);
- }
- pub fn instr16_3B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- let source_operand = ctx.builder.set_new_local();
- gen_cmp16(
- ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::WasmLocal(&source_operand),
- );
- ctx.builder.free_local(source_operand);
- }
- pub fn instr16_3B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- gen_cmp16(
- ctx.builder,
- &ctx.register_locals[r2 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r1 as usize]),
- );
- }
- pub fn instr32_3B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- let source_operand = ctx.builder.set_new_local();
- gen_cmp32(
- ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::WasmLocal(&source_operand),
- );
- ctx.builder.free_local(source_operand);
- }
- pub fn instr32_3B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- gen_cmp32(
- ctx.builder,
- &ctx.register_locals[r2 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r1 as usize]),
- );
- }
- pub fn instr_3C_jit(ctx: &mut JitContext, imm8: u32) {
- gen_cmp8(
- ctx.builder,
- &ctx.register_locals[0],
- &LocalOrImmediate::Immediate(imm8 as i32),
- );
- }
- pub fn instr16_3D_jit(ctx: &mut JitContext, imm16: u32) {
- gen_cmp16(
- ctx.builder,
- &ctx.register_locals[0],
- &LocalOrImmediate::Immediate(imm16 as i32),
- );
- }
- pub fn instr32_3D_jit(ctx: &mut JitContext, imm32: u32) {
- gen_cmp32(
- ctx.builder,
- &ctx.register_locals[0],
- &LocalOrImmediate::Immediate(imm32 as i32),
- );
- }
- fn gen_inc(builder: &mut WasmBuilder, dest_operand: &WasmLocal, size: i32) {
- builder.const_i32(global_pointers::flags as i32);
- codegen::gen_get_flags(builder);
- builder.const_i32(!1);
- builder.and_i32();
- codegen::gen_getcf(builder);
- builder.or_i32();
- builder.store_aligned_i32(0);
- builder.const_i32(global_pointers::last_op1 as i32);
- builder.get_local(&dest_operand);
- if size == OPSIZE_8 || size == OPSIZE_16 {
- builder.const_i32(if size == OPSIZE_8 { 0xFF } else { 0xFFFF });
- builder.and_i32();
- }
- builder.store_aligned_i32(0);
- builder.get_local(dest_operand);
- builder.const_i32(1);
- builder.add_i32();
- if size == OPSIZE_16 {
- codegen::gen_set_reg16_local(builder, dest_operand);
- }
- else {
- builder.set_local(dest_operand);
- }
- builder.const_i32(global_pointers::last_result as i32);
- builder.get_local(&dest_operand);
- if size == OPSIZE_16 {
- builder.const_i32(0xFFFF);
- builder.and_i32();
- }
- builder.store_aligned_i32(0);
- codegen::gen_set_last_op_size(builder, size);
- codegen::gen_set_flags_changed(builder, FLAGS_ALL & !1);
- }
- fn gen_inc16(builder: &mut WasmBuilder, dest_operand: &WasmLocal) {
- gen_inc(builder, dest_operand, OPSIZE_16);
- }
- fn gen_inc32(builder: &mut WasmBuilder, dest_operand: &WasmLocal) {
- gen_inc(builder, dest_operand, OPSIZE_32);
- }
- fn gen_dec(builder: &mut WasmBuilder, dest_operand: &WasmLocal, size: i32) {
- builder.const_i32(global_pointers::flags as i32);
- codegen::gen_get_flags(builder);
- builder.const_i32(!1);
- builder.and_i32();
- codegen::gen_getcf(builder);
- builder.or_i32();
- builder.store_aligned_i32(0);
- builder.const_i32(global_pointers::last_op1 as i32);
- builder.get_local(&dest_operand);
- if size == OPSIZE_8 || size == OPSIZE_16 {
- builder.const_i32(if size == OPSIZE_8 { 0xFF } else { 0xFFFF });
- builder.and_i32();
- }
- builder.store_aligned_i32(0);
- builder.get_local(dest_operand);
- builder.const_i32(1);
- builder.sub_i32();
- if size == OPSIZE_16 {
- codegen::gen_set_reg16_local(builder, dest_operand);
- }
- else {
- builder.set_local(dest_operand);
- }
- builder.const_i32(global_pointers::last_result as i32);
- builder.get_local(&dest_operand);
- if size == OPSIZE_16 {
- builder.const_i32(0xFFFF);
- builder.and_i32();
- }
- builder.store_aligned_i32(0);
- codegen::gen_set_last_op_size(builder, size);
- codegen::gen_set_flags_changed(builder, FLAGS_ALL & !1 | FLAG_SUB);
- }
- fn gen_dec16(builder: &mut WasmBuilder, dest_operand: &WasmLocal) {
- gen_dec(builder, dest_operand, OPSIZE_16)
- }
- fn gen_dec32(builder: &mut WasmBuilder, dest_operand: &WasmLocal) {
- gen_dec(builder, dest_operand, OPSIZE_32)
- }
- fn gen_inc16_r(ctx: &mut JitContext, r: u32) {
- gen_inc16(ctx.builder, &mut ctx.register_locals[r as usize])
- }
- fn gen_inc32_r(ctx: &mut JitContext, r: u32) {
- gen_inc32(ctx.builder, &mut ctx.register_locals[r as usize])
- }
- fn gen_dec16_r(ctx: &mut JitContext, r: u32) {
- gen_dec16(ctx.builder, &mut ctx.register_locals[r as usize])
- }
- fn gen_dec32_r(ctx: &mut JitContext, r: u32) {
- gen_dec32(ctx.builder, &mut ctx.register_locals[r as usize])
- }
- fn gen_not16(builder: &mut WasmBuilder, dest_operand: &WasmLocal) {
- builder.get_local(dest_operand);
- builder.const_i32(-1);
- builder.xor_i32();
- codegen::gen_set_reg16_local(builder, dest_operand);
- }
- fn gen_not32(builder: &mut WasmBuilder, dest_operand: &WasmLocal) {
- builder.get_local(dest_operand);
- builder.const_i32(-1);
- builder.xor_i32();
- builder.set_local(dest_operand);
- }
- fn gen_neg16(builder: &mut WasmBuilder, dest_operand: &WasmLocal) {
- builder.get_local(dest_operand);
- builder.call_fn1_ret("neg16");
- codegen::gen_set_reg16_local(builder, dest_operand);
- }
- fn gen_neg32(builder: &mut WasmBuilder, dest_operand: &WasmLocal) {
- builder.const_i32(global_pointers::last_op1 as i32);
- builder.const_i32(0);
- builder.store_aligned_i32(0);
- builder.const_i32(0);
- builder.get_local(&dest_operand);
- builder.sub_i32();
- builder.set_local(dest_operand);
- codegen::gen_set_last_result(builder, &dest_operand);
- codegen::gen_set_last_op_size(builder, OPSIZE_32);
- codegen::gen_set_flags_changed(builder, FLAGS_ALL | FLAG_SUB);
- }
- pub fn instr16_06_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::ES);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr32_06_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::ES);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr16_0E_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::CS);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr32_0E_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::CS);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr16_16_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::SS);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr32_16_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::SS);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr16_1E_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::DS);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr32_1E_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::DS);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr16_40_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, AX); }
- pub fn instr32_40_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EAX); }
- pub fn instr16_41_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, CX); }
- pub fn instr32_41_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, ECX); }
- pub fn instr16_42_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, DX); }
- pub fn instr32_42_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EDX); }
- pub fn instr16_43_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, BX); }
- pub fn instr32_43_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EBX); }
- pub fn instr16_44_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, SP); }
- pub fn instr32_44_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, ESP); }
- pub fn instr16_45_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, BP); }
- pub fn instr32_45_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EBP); }
- pub fn instr16_46_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, SI); }
- pub fn instr32_46_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, ESI); }
- pub fn instr16_47_jit(ctx: &mut JitContext) { gen_inc16_r(ctx, DI); }
- pub fn instr32_47_jit(ctx: &mut JitContext) { gen_inc32_r(ctx, EDI); }
- pub fn instr16_48_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, AX); }
- pub fn instr32_48_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EAX); }
- pub fn instr16_49_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, CX); }
- pub fn instr32_49_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, ECX); }
- pub fn instr16_4A_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, DX); }
- pub fn instr32_4A_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EDX); }
- pub fn instr16_4B_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, BX); }
- pub fn instr32_4B_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EBX); }
- pub fn instr16_4C_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, SP); }
- pub fn instr32_4C_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, ESP); }
- pub fn instr16_4D_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, BP); }
- pub fn instr32_4D_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EBP); }
- pub fn instr16_4E_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, SI); }
- pub fn instr32_4E_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, ESI); }
- pub fn instr16_4F_jit(ctx: &mut JitContext) { gen_dec16_r(ctx, DI); }
- pub fn instr32_4F_jit(ctx: &mut JitContext) { gen_dec32_r(ctx, EDI); }
- pub fn instr16_50_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, AX); }
- pub fn instr32_50_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EAX); }
- pub fn instr16_51_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, CX); }
- pub fn instr32_51_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, ECX); }
- pub fn instr16_52_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, DX); }
- pub fn instr32_52_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EDX); }
- pub fn instr16_53_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, BX); }
- pub fn instr32_53_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EBX); }
- pub fn instr16_54_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, SP); }
- pub fn instr32_54_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, ESP); }
- pub fn instr16_55_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, BP); }
- pub fn instr32_55_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EBP); }
- pub fn instr16_56_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, SI); }
- pub fn instr32_56_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, ESI); }
- pub fn instr16_57_jit(ctx: &mut JitContext) { push16_reg_jit(ctx, DI); }
- pub fn instr32_57_jit(ctx: &mut JitContext) { push32_reg_jit(ctx, EDI); }
- pub fn instr16_58_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, AX); }
- pub fn instr32_58_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EAX); }
- pub fn instr16_59_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, CX); }
- pub fn instr32_59_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, ECX); }
- pub fn instr16_5A_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, DX); }
- pub fn instr32_5A_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EDX); }
- pub fn instr16_5B_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, BX); }
- pub fn instr32_5B_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EBX); }
- pub fn instr16_5C_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, SP); }
- pub fn instr32_5C_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, ESP); }
- pub fn instr16_5D_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, BP); }
- pub fn instr32_5D_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EBP); }
- pub fn instr16_5E_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, SI); }
- pub fn instr32_5E_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, ESI); }
- pub fn instr16_5F_jit(ctx: &mut JitContext) { pop16_reg_jit(ctx, DI); }
- pub fn instr32_5F_jit(ctx: &mut JitContext) { pop32_reg_jit(ctx, EDI); }
- pub fn instr16_68_jit(ctx: &mut JitContext, imm16: u32) { push16_imm_jit(ctx, imm16) }
- pub fn instr32_68_jit(ctx: &mut JitContext, imm32: u32) { push32_imm_jit(ctx, imm32) }
- pub fn instr16_6A_jit(ctx: &mut JitContext, imm16: u32) { push16_imm_jit(ctx, imm16) }
- pub fn instr32_6A_jit(ctx: &mut JitContext, imm32: u32) { push32_imm_jit(ctx, imm32) }
- pub fn instr16_69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm16: u32) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- ctx.builder.const_i32(imm16 as i32);
- ctx.builder.call_fn2_ret("imul_reg16");
- codegen::gen_set_reg16(ctx, r);
- }
- pub fn instr16_69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm16: u32) {
- codegen::gen_get_reg16(ctx, r1);
- ctx.builder.const_i32(imm16 as i32);
- ctx.builder.call_fn2_ret("imul_reg16");
- codegen::gen_set_reg16(ctx, r2);
- }
- pub fn instr32_69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm32: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- let value_local = ctx.builder.set_new_local();
- gen_imul3_reg32(
- ctx.builder,
- &ctx.register_locals[r as usize],
- &value_local,
- &LocalOrImmediate::Immediate(imm32 as i32),
- );
- ctx.builder.free_local(value_local);
- }
- pub fn instr32_69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm32: u32) {
- gen_imul3_reg32(
- ctx.builder,
- &ctx.register_locals[r2 as usize],
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::Immediate(imm32 as i32),
- );
- }
- pub fn instr16_6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8s: u32) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- ctx.builder.const_i32(imm8s as i32);
- ctx.builder.call_fn2_ret("imul_reg16");
- codegen::gen_set_reg16(ctx, r);
- }
- pub fn instr16_6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8s: u32) {
- codegen::gen_get_reg16(ctx, r1);
- ctx.builder.const_i32(imm8s as i32);
- ctx.builder.call_fn2_ret("imul_reg16");
- codegen::gen_set_reg16(ctx, r2);
- }
- pub fn instr32_6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8s: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- let value_local = ctx.builder.set_new_local();
- gen_imul3_reg32(
- ctx.builder,
- &ctx.register_locals[r as usize],
- &value_local,
- &LocalOrImmediate::Immediate(imm8s as i32),
- );
- ctx.builder.free_local(value_local);
- }
- pub fn instr32_6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8s: u32) {
- gen_imul3_reg32(
- ctx.builder,
- &ctx.register_locals[r2 as usize],
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::Immediate(imm8s as i32),
- );
- }
- // Code for conditional jumps is generated automatically by the basic block codegen
- pub fn instr16_70_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_70_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_71_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_71_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_72_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_72_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_73_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_73_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_74_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_74_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_75_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_75_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_76_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_76_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_77_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_77_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_78_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_78_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_79_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_79_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_7A_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_7A_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_7B_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_7B_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_7C_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_7C_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_7D_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_7D_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_7E_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_7E_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_7F_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_7F_jit(_ctx: &mut JitContext, _imm: u32) {}
- // loop/loopz/loopnz/jcxz: Conditional jump is generated in main loop
- pub fn instr16_E0_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
- pub fn instr32_E0_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
- pub fn instr16_E1_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
- pub fn instr32_E1_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
- pub fn instr16_E2_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
- pub fn instr32_E2_jit(ctx: &mut JitContext, _imm: u32) { codegen::decr_exc_asize(ctx) }
- pub fn instr16_E3_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_E3_jit(_ctx: &mut JitContext, _imm: u32) {}
- define_instruction_read_write_mem8!("add8", instr_80_0_mem_jit, instr_80_0_reg_jit, imm8);
- define_instruction_read_write_mem8!("or8", instr_80_1_mem_jit, instr_80_1_reg_jit, imm8);
- define_instruction_read_write_mem8!("adc8", instr_80_2_mem_jit, instr_80_2_reg_jit, imm8);
- define_instruction_read_write_mem8!("sbb8", instr_80_3_mem_jit, instr_80_3_reg_jit, imm8);
- define_instruction_read_write_mem8!("and8", instr_80_4_mem_jit, instr_80_4_reg_jit, imm8);
- define_instruction_read_write_mem8!("sub8", instr_80_5_mem_jit, instr_80_5_reg_jit, imm8);
- define_instruction_read_write_mem8!("xor8", instr_80_6_mem_jit, instr_80_6_reg_jit, imm8);
- define_instruction_read_write_mem8!("add8", instr_82_0_mem_jit, instr_82_0_reg_jit, imm8);
- define_instruction_read_write_mem8!("or8", instr_82_1_mem_jit, instr_82_1_reg_jit, imm8);
- define_instruction_read_write_mem8!("adc8", instr_82_2_mem_jit, instr_82_2_reg_jit, imm8);
- define_instruction_read_write_mem8!("sbb8", instr_82_3_mem_jit, instr_82_3_reg_jit, imm8);
- define_instruction_read_write_mem8!("and8", instr_82_4_mem_jit, instr_82_4_reg_jit, imm8);
- define_instruction_read_write_mem8!("sub8", instr_82_5_mem_jit, instr_82_5_reg_jit, imm8);
- define_instruction_read_write_mem8!("xor8", instr_82_6_mem_jit, instr_82_6_reg_jit, imm8);
- define_instruction_read_write_mem16!("add16", instr16_81_0_mem_jit, instr16_81_0_reg_jit, imm16);
- define_instruction_read_write_mem32!(gen_add32, instr32_81_0_mem_jit, instr32_81_0_reg_jit, imm32);
- define_instruction_read_write_mem16!("or16", instr16_81_1_mem_jit, instr16_81_1_reg_jit, imm16);
- define_instruction_read_write_mem32!(gen_or32, instr32_81_1_mem_jit, instr32_81_1_reg_jit, imm32);
- define_instruction_read_write_mem16!("adc16", instr16_81_2_mem_jit, instr16_81_2_reg_jit, imm16);
- define_instruction_read_write_mem32!(gen_adc32, instr32_81_2_mem_jit, instr32_81_2_reg_jit, imm32);
- define_instruction_read_write_mem16!("sbb16", instr16_81_3_mem_jit, instr16_81_3_reg_jit, imm16);
- define_instruction_read_write_mem32!(gen_sbb32, instr32_81_3_mem_jit, instr32_81_3_reg_jit, imm32);
- define_instruction_read_write_mem16!("and16", instr16_81_4_mem_jit, instr16_81_4_reg_jit, imm16);
- define_instruction_read_write_mem32!(gen_and32, instr32_81_4_mem_jit, instr32_81_4_reg_jit, imm32);
- define_instruction_read_write_mem16!("sub16", instr16_81_5_mem_jit, instr16_81_5_reg_jit, imm16);
- define_instruction_read_write_mem32!(gen_sub32, instr32_81_5_mem_jit, instr32_81_5_reg_jit, imm32);
- define_instruction_read_write_mem16!("xor16", instr16_81_6_mem_jit, instr16_81_6_reg_jit, imm16);
- define_instruction_read_write_mem32!(gen_xor32, instr32_81_6_mem_jit, instr32_81_6_reg_jit, imm32);
- define_instruction_read_write_mem16!("add16", instr16_83_0_mem_jit, instr16_83_0_reg_jit, imm8s);
- define_instruction_read_write_mem32!(gen_add32, instr32_83_0_mem_jit, instr32_83_0_reg_jit, imm8s);
- define_instruction_read_write_mem16!("or16", instr16_83_1_mem_jit, instr16_83_1_reg_jit, imm8s);
- define_instruction_read_write_mem32!(gen_or32, instr32_83_1_mem_jit, instr32_83_1_reg_jit, imm8s);
- define_instruction_read_write_mem16!("adc16", instr16_83_2_mem_jit, instr16_83_2_reg_jit, imm8s);
- define_instruction_read_write_mem32!(gen_adc32, instr32_83_2_mem_jit, instr32_83_2_reg_jit, imm8s);
- define_instruction_read_write_mem16!("sbb16", instr16_83_3_mem_jit, instr16_83_3_reg_jit, imm8s);
- define_instruction_read_write_mem32!(gen_sbb32, instr32_83_3_mem_jit, instr32_83_3_reg_jit, imm8s);
- define_instruction_read_write_mem16!("and16", instr16_83_4_mem_jit, instr16_83_4_reg_jit, imm8s);
- define_instruction_read_write_mem32!(gen_and32, instr32_83_4_mem_jit, instr32_83_4_reg_jit, imm8s);
- define_instruction_read_write_mem16!("sub16", instr16_83_5_mem_jit, instr16_83_5_reg_jit, imm8s);
- define_instruction_read_write_mem32!(gen_sub32, instr32_83_5_mem_jit, instr32_83_5_reg_jit, imm8s);
- define_instruction_read_write_mem16!("xor16", instr16_83_6_mem_jit, instr16_83_6_reg_jit, imm8s);
- define_instruction_read_write_mem32!(gen_xor32, instr32_83_6_mem_jit, instr32_83_6_reg_jit, imm8s);
- define_instruction_read8!(gen_cmp8, instr_80_7_mem_jit, instr_80_7_reg_jit, imm8);
- define_instruction_read16!(gen_cmp16, instr16_81_7_mem_jit, instr16_81_7_reg_jit, imm16);
- define_instruction_read32!(gen_cmp32, instr32_81_7_mem_jit, instr32_81_7_reg_jit, imm32);
- define_instruction_read8!(gen_cmp8, instr_82_7_mem_jit, instr_82_7_reg_jit, imm8);
- define_instruction_read16!(gen_cmp16, instr16_83_7_mem_jit, instr16_83_7_reg_jit, imm8s);
- define_instruction_read32!(gen_cmp32, instr32_83_7_mem_jit, instr32_83_7_reg_jit, imm8s);
- define_instruction_read8!(gen_test8, instr_84_mem_jit, instr_84_reg_jit);
- define_instruction_read16!(gen_test16, instr16_85_mem_jit, instr16_85_reg_jit);
- define_instruction_read32!(gen_test32, instr32_85_mem_jit, instr32_85_reg_jit);
- pub fn instr_86_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::BYTE, &address_local, &|ref mut ctx| {
- codegen::gen_get_reg8(ctx, r);
- let tmp = ctx.builder.set_new_local();
- codegen::gen_set_reg8(ctx, r);
- ctx.builder.get_local(&tmp);
- ctx.builder.free_local(tmp);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn instr_86_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg8(ctx, r2);
- let tmp = ctx.builder.set_new_local();
- codegen::gen_get_reg8(ctx, r1);
- codegen::gen_set_reg8(ctx, r2);
- ctx.builder.get_local(&tmp);
- codegen::gen_set_reg8(ctx, r1);
- ctx.builder.free_local(tmp);
- }
- pub fn instr16_87_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
- codegen::gen_get_reg16(ctx, r);
- let tmp = ctx.builder.set_new_local();
- codegen::gen_set_reg16(ctx, r);
- ctx.builder.get_local(&tmp);
- ctx.builder.free_local(tmp);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn instr32_87_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
- codegen::gen_get_reg32(ctx, r);
- let tmp = ctx.builder.set_new_local();
- codegen::gen_set_reg32(ctx, r);
- ctx.builder.get_local(&tmp);
- ctx.builder.free_local(tmp);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn instr16_87_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg16(ctx, r2);
- let tmp = ctx.builder.set_new_local();
- codegen::gen_get_reg16(ctx, r1);
- codegen::gen_set_reg16(ctx, r2);
- ctx.builder.get_local(&tmp);
- codegen::gen_set_reg16(ctx, r1);
- ctx.builder.free_local(tmp);
- }
- pub fn instr32_87_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg32(ctx, r2);
- let tmp = ctx.builder.set_new_local();
- codegen::gen_get_reg32(ctx, r1);
- codegen::gen_set_reg32(ctx, r2);
- ctx.builder.get_local(&tmp);
- codegen::gen_set_reg32(ctx, r1);
- ctx.builder.free_local(tmp);
- }
- pub fn instr_88_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_get_reg8(ctx, r);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write8(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- }
- pub fn instr_88_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_set_reg8_r(ctx, r1, r2);
- }
- pub fn instr16_89_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_write16(
- ctx,
- &address_local,
- &ctx.register_locals[r as usize].unsafe_clone(),
- );
- ctx.builder.free_local(address_local);
- }
- pub fn instr16_89_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_set_reg16_r(ctx, r1, r2);
- }
- pub fn instr32_89_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- // Pseudo: safe_write32(modrm_resolve(modrm_byte), reg32[r]);
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_write32(
- ctx,
- &address_local,
- &ctx.register_locals[r as usize].unsafe_clone(),
- );
- ctx.builder.free_local(address_local);
- }
- pub fn instr32_89_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_set_reg32_r(ctx, r1, r2);
- }
- pub fn instr_8A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- // Pseudo: reg8[r] = safe_read8(modrm_resolve(modrm_byte));
- codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
- codegen::gen_set_reg8(ctx, r);
- }
- pub fn instr_8A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_set_reg8_r(ctx, r2, r1);
- }
- pub fn instr16_8B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- // Pseudo: reg16[r] = safe_read16(modrm_resolve(modrm_byte));
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- codegen::gen_set_reg16(ctx, r);
- }
- pub fn instr16_8B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_set_reg16_r(ctx, r2, r1);
- }
- pub fn instr32_8B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- // Pseudo: reg32[r] = safe_read32s(modrm_resolve(modrm_byte));
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr32_8B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_set_reg32_r(ctx, r2, r1);
- }
- pub fn instr16_8C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- if r >= 6 {
- codegen::gen_trigger_ud(ctx);
- }
- else {
- codegen::gen_get_sreg(ctx, r);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write16(ctx, &address_local, &value_local);
- ctx.builder.free_local(value_local);
- }
- ctx.builder.free_local(address_local);
- }
- pub fn instr32_8C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- if r >= 6 {
- codegen::gen_trigger_ud(ctx);
- }
- else {
- codegen::gen_get_sreg(ctx, r);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write16(ctx, &address_local, &value_local);
- ctx.builder.free_local(value_local);
- }
- ctx.builder.free_local(address_local);
- }
- pub fn instr16_8C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- if r2 >= 6 {
- codegen::gen_trigger_ud(ctx);
- }
- else {
- codegen::gen_get_sreg(ctx, r2);
- codegen::gen_set_reg16(ctx, r1);
- }
- }
- pub fn instr32_8C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- if r2 >= 6 {
- codegen::gen_trigger_ud(ctx);
- }
- else {
- codegen::gen_get_sreg(ctx, r2);
- codegen::gen_set_reg32(ctx, r1);
- }
- }
- pub fn instr16_8D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, reg: u32) {
- ctx.cpu.prefixes |= SEG_PREFIX_ZERO;
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- codegen::gen_set_reg16(ctx, reg);
- }
- pub fn instr32_8D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, reg: u32) {
- ctx.cpu.prefixes |= SEG_PREFIX_ZERO;
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- codegen::gen_set_reg32(ctx, reg);
- }
- pub fn instr16_8D_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr32_8D_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr16_8F_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- // before gen_modrm_resolve, update esp to the new value
- codegen::gen_adjust_stack_reg(ctx, 2);
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- // pop takes care of updating esp, so undo the previous change
- codegen::gen_adjust_stack_reg(ctx, (-2i32) as u32);
- codegen::gen_pop16(ctx);
- let value_local = ctx.builder.set_new_local();
- // undo the esp change of pop, as safe_write16 can fail
- codegen::gen_adjust_stack_reg(ctx, (-2i32) as u32);
- codegen::gen_safe_write16(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- // finally, actually update esp
- codegen::gen_adjust_stack_reg(ctx, 2);
- }
- pub fn instr16_8F_0_reg_jit(ctx: &mut JitContext, r: u32) { pop16_reg_jit(ctx, r); }
- pub fn instr32_8F_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_adjust_stack_reg(ctx, 4);
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_adjust_stack_reg(ctx, (-4i32) as u32);
- codegen::gen_pop32s(ctx);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_adjust_stack_reg(ctx, (-4i32) as u32);
- codegen::gen_safe_write32(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- codegen::gen_adjust_stack_reg(ctx, 4);
- }
- pub fn instr32_8F_0_reg_jit(ctx: &mut JitContext, r: u32) { pop32_reg_jit(ctx, r); }
- define_instruction_read_write_mem16!(
- "rol16",
- instr16_C1_0_mem_jit,
- instr16_C1_0_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem32!(
- gen_rol32,
- instr32_C1_0_mem_jit,
- instr32_C1_0_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem16!(
- "ror16",
- instr16_C1_1_mem_jit,
- instr16_C1_1_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem32!(
- gen_ror32,
- instr32_C1_1_mem_jit,
- instr32_C1_1_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem16!(
- "rcl16",
- instr16_C1_2_mem_jit,
- instr16_C1_2_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem32!(
- gen_rcl32,
- instr32_C1_2_mem_jit,
- instr32_C1_2_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem16!(
- "rcr16",
- instr16_C1_3_mem_jit,
- instr16_C1_3_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem32!(
- gen_rcr32,
- instr32_C1_3_mem_jit,
- instr32_C1_3_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem16!(
- "shl16",
- instr16_C1_4_mem_jit,
- instr16_C1_4_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem32!(
- gen_shl32,
- instr32_C1_4_mem_jit,
- instr32_C1_4_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem16!(
- "shr16",
- instr16_C1_5_mem_jit,
- instr16_C1_5_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem32!(
- gen_shr32,
- instr32_C1_5_mem_jit,
- instr32_C1_5_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem16!(
- "shl16",
- instr16_C1_6_mem_jit,
- instr16_C1_6_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem32!(
- gen_shl32,
- instr32_C1_6_mem_jit,
- instr32_C1_6_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem16!(
- "sar16",
- instr16_C1_7_mem_jit,
- instr16_C1_7_reg_jit,
- imm8_5bits
- );
- define_instruction_read_write_mem32!(
- gen_sar32,
- instr32_C1_7_mem_jit,
- instr32_C1_7_reg_jit,
- imm8_5bits
- );
- pub fn instr16_E8_jit(ctx: &mut JitContext, imm: u32) {
- codegen::gen_get_real_eip(ctx);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &value_local);
- ctx.builder.free_local(value_local);
- codegen::gen_jmp_rel16(ctx.builder, imm as u16);
- }
- pub fn instr32_E8_jit(ctx: &mut JitContext, imm: u32) {
- codegen::gen_get_real_eip(ctx);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &value_local);
- ctx.builder.free_local(value_local);
- codegen::gen_relative_jump(ctx.builder, imm as i32);
- }
- pub fn instr16_E9_jit(ctx: &mut JitContext, imm: u32) {
- codegen::gen_jmp_rel16(ctx.builder, imm as u16);
- }
- pub fn instr32_E9_jit(ctx: &mut JitContext, imm: u32) {
- codegen::gen_relative_jump(ctx.builder, imm as i32);
- }
- pub fn instr16_C2_jit(ctx: &mut JitContext, imm16: u32) {
- ctx.builder.const_i32(0);
- codegen::gen_pop16(ctx);
- codegen::gen_add_cs_offset(ctx);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- codegen::gen_adjust_stack_reg(ctx, imm16);
- }
- pub fn instr32_C2_jit(ctx: &mut JitContext, imm16: u32) {
- ctx.builder.const_i32(0);
- codegen::gen_pop32s(ctx);
- codegen::gen_add_cs_offset(ctx);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- codegen::gen_adjust_stack_reg(ctx, imm16);
- }
- pub fn instr16_C3_jit(ctx: &mut JitContext) {
- ctx.builder.const_i32(0);
- codegen::gen_pop16(ctx);
- codegen::gen_add_cs_offset(ctx);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- }
- pub fn instr32_C3_jit(ctx: &mut JitContext) {
- ctx.builder.const_i32(0);
- codegen::gen_pop32s(ctx);
- codegen::gen_add_cs_offset(ctx);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- }
- pub fn instr16_C9_jit(ctx: &mut JitContext) { codegen::gen_leave(ctx, false); }
- pub fn instr32_C9_jit(ctx: &mut JitContext) { codegen::gen_leave(ctx, true); }
- pub fn gen_mov_reg8_imm(ctx: &mut JitContext, r: u32, imm: u32) {
- ctx.builder.const_i32(imm as i32);
- codegen::gen_set_reg8(ctx, r);
- }
- pub fn instr_B0_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 0, imm) }
- pub fn instr_B1_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 1, imm) }
- pub fn instr_B2_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 2, imm) }
- pub fn instr_B3_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 3, imm) }
- pub fn instr_B4_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 4, imm) }
- pub fn instr_B5_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 5, imm) }
- pub fn instr_B6_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 6, imm) }
- pub fn instr_B7_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg8_imm(ctx, 7, imm) }
- pub fn gen_mov_reg16_imm(ctx: &mut JitContext, r: u32, imm: u32) {
- ctx.builder.const_i32(imm as i32);
- codegen::gen_set_reg16(ctx, r);
- }
- pub fn instr16_B8_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 0, imm) }
- pub fn instr16_B9_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 1, imm) }
- pub fn instr16_BA_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 2, imm) }
- pub fn instr16_BB_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 3, imm) }
- pub fn instr16_BC_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 4, imm) }
- pub fn instr16_BD_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 5, imm) }
- pub fn instr16_BE_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 6, imm) }
- pub fn instr16_BF_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg16_imm(ctx, 7, imm) }
- pub fn gen_mov_reg32_imm(ctx: &mut JitContext, r: u32, imm: u32) {
- ctx.builder.const_i32(imm as i32);
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr32_B8_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 0, imm) }
- pub fn instr32_B9_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 1, imm) }
- pub fn instr32_BA_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 2, imm) }
- pub fn instr32_BB_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 3, imm) }
- pub fn instr32_BC_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 4, imm) }
- pub fn instr32_BD_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 5, imm) }
- pub fn instr32_BE_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 6, imm) }
- pub fn instr32_BF_jit(ctx: &mut JitContext, imm: u32) { gen_mov_reg32_imm(ctx, 7, imm) }
- define_instruction_read_write_mem8!("rol8", instr_C0_0_mem_jit, instr_C0_0_reg_jit, imm8_5bits);
- define_instruction_read_write_mem8!("ror8", instr_C0_1_mem_jit, instr_C0_1_reg_jit, imm8_5bits);
- define_instruction_read_write_mem8!("rcl8", instr_C0_2_mem_jit, instr_C0_2_reg_jit, imm8_5bits);
- define_instruction_read_write_mem8!("rcr8", instr_C0_3_mem_jit, instr_C0_3_reg_jit, imm8_5bits);
- define_instruction_read_write_mem8!("shl8", instr_C0_4_mem_jit, instr_C0_4_reg_jit, imm8_5bits);
- define_instruction_read_write_mem8!("shr8", instr_C0_5_mem_jit, instr_C0_5_reg_jit, imm8_5bits);
- define_instruction_read_write_mem8!("shl8", instr_C0_6_mem_jit, instr_C0_6_reg_jit, imm8_5bits);
- define_instruction_read_write_mem8!("sar8", instr_C0_7_mem_jit, instr_C0_7_reg_jit, imm8_5bits);
- define_instruction_read_write_mem8!("rol8", instr_D0_0_mem_jit, instr_D0_0_reg_jit, constant_one);
- define_instruction_read_write_mem8!("ror8", instr_D0_1_mem_jit, instr_D0_1_reg_jit, constant_one);
- define_instruction_read_write_mem8!("rcl8", instr_D0_2_mem_jit, instr_D0_2_reg_jit, constant_one);
- define_instruction_read_write_mem8!("rcr8", instr_D0_3_mem_jit, instr_D0_3_reg_jit, constant_one);
- define_instruction_read_write_mem8!("shl8", instr_D0_4_mem_jit, instr_D0_4_reg_jit, constant_one);
- define_instruction_read_write_mem8!("shr8", instr_D0_5_mem_jit, instr_D0_5_reg_jit, constant_one);
- define_instruction_read_write_mem8!("shl8", instr_D0_6_mem_jit, instr_D0_6_reg_jit, constant_one);
- define_instruction_read_write_mem8!("sar8", instr_D0_7_mem_jit, instr_D0_7_reg_jit, constant_one);
- define_instruction_read_write_mem16!(
- "rol16",
- instr16_D1_0_mem_jit,
- instr16_D1_0_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem32!(
- gen_rol32,
- instr32_D1_0_mem_jit,
- instr32_D1_0_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem16!(
- "ror16",
- instr16_D1_1_mem_jit,
- instr16_D1_1_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem32!(
- gen_ror32,
- instr32_D1_1_mem_jit,
- instr32_D1_1_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem16!(
- "rcl16",
- instr16_D1_2_mem_jit,
- instr16_D1_2_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem32!(
- gen_rcl32,
- instr32_D1_2_mem_jit,
- instr32_D1_2_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem16!(
- "rcr16",
- instr16_D1_3_mem_jit,
- instr16_D1_3_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem32!(
- gen_rcr32,
- instr32_D1_3_mem_jit,
- instr32_D1_3_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem16!(
- "shl16",
- instr16_D1_4_mem_jit,
- instr16_D1_4_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem32!(
- gen_shl32,
- instr32_D1_4_mem_jit,
- instr32_D1_4_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem16!(
- "shr16",
- instr16_D1_5_mem_jit,
- instr16_D1_5_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem32!(
- gen_shr32,
- instr32_D1_5_mem_jit,
- instr32_D1_5_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem16!(
- "shl16",
- instr16_D1_6_mem_jit,
- instr16_D1_6_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem32!(
- gen_shl32,
- instr32_D1_6_mem_jit,
- instr32_D1_6_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem16!(
- "sar16",
- instr16_D1_7_mem_jit,
- instr16_D1_7_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem32!(
- gen_sar32,
- instr32_D1_7_mem_jit,
- instr32_D1_7_reg_jit,
- constant_one
- );
- define_instruction_read_write_mem8!("rol8", instr_D2_0_mem_jit, instr_D2_0_reg_jit, cl);
- define_instruction_read_write_mem8!("ror8", instr_D2_1_mem_jit, instr_D2_1_reg_jit, cl);
- define_instruction_read_write_mem8!("rcl8", instr_D2_2_mem_jit, instr_D2_2_reg_jit, cl);
- define_instruction_read_write_mem8!("rcr8", instr_D2_3_mem_jit, instr_D2_3_reg_jit, cl);
- define_instruction_read_write_mem8!("shl8", instr_D2_4_mem_jit, instr_D2_4_reg_jit, cl);
- define_instruction_read_write_mem8!("shr8", instr_D2_5_mem_jit, instr_D2_5_reg_jit, cl);
- define_instruction_read_write_mem8!("shl8", instr_D2_6_mem_jit, instr_D2_6_reg_jit, cl);
- define_instruction_read_write_mem8!("sar8", instr_D2_7_mem_jit, instr_D2_7_reg_jit, cl);
- define_instruction_read_write_mem16!("rol16", instr16_D3_0_mem_jit, instr16_D3_0_reg_jit, cl);
- define_instruction_read_write_mem32!(gen_rol32, instr32_D3_0_mem_jit, instr32_D3_0_reg_jit, cl);
- define_instruction_read_write_mem16!("ror16", instr16_D3_1_mem_jit, instr16_D3_1_reg_jit, cl);
- define_instruction_read_write_mem32!(gen_ror32, instr32_D3_1_mem_jit, instr32_D3_1_reg_jit, cl);
- define_instruction_read_write_mem16!("rcl16", instr16_D3_2_mem_jit, instr16_D3_2_reg_jit, cl);
- define_instruction_read_write_mem32!(gen_rcl32, instr32_D3_2_mem_jit, instr32_D3_2_reg_jit, cl);
- define_instruction_read_write_mem16!("rcr16", instr16_D3_3_mem_jit, instr16_D3_3_reg_jit, cl);
- define_instruction_read_write_mem32!(gen_rcr32, instr32_D3_3_mem_jit, instr32_D3_3_reg_jit, cl);
- define_instruction_read_write_mem16!("shl16", instr16_D3_4_mem_jit, instr16_D3_4_reg_jit, cl);
- define_instruction_read_write_mem32!(gen_shl32, instr32_D3_4_mem_jit, instr32_D3_4_reg_jit, cl);
- define_instruction_read_write_mem16!("shr16", instr16_D3_5_mem_jit, instr16_D3_5_reg_jit, cl);
- define_instruction_read_write_mem32!(gen_shr32, instr32_D3_5_mem_jit, instr32_D3_5_reg_jit, cl);
- define_instruction_read_write_mem16!("shl16", instr16_D3_6_mem_jit, instr16_D3_6_reg_jit, cl);
- define_instruction_read_write_mem32!(gen_shl32, instr32_D3_6_mem_jit, instr32_D3_6_reg_jit, cl);
- define_instruction_read_write_mem16!("sar16", instr16_D3_7_mem_jit, instr16_D3_7_reg_jit, cl);
- define_instruction_read_write_mem32!(gen_sar32, instr32_D3_7_mem_jit, instr32_D3_7_reg_jit, cl);
- pub fn instr_D7_jit(ctx: &mut JitContext) {
- if ctx.cpu.asize_32() {
- codegen::gen_get_reg32(ctx, regs::EBX);
- }
- else {
- codegen::gen_get_reg16(ctx, regs::BX);
- }
- codegen::gen_get_reg8(ctx, regs::AL);
- ctx.builder.add_i32();
- if !ctx.cpu.asize_32() {
- ctx.builder.const_i32(0xFFFF);
- ctx.builder.and_i32();
- }
- jit_add_seg_offset(ctx, regs::DS);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read8(ctx, &address_local);
- ctx.builder.free_local(address_local);
- codegen::gen_set_reg8(ctx, regs::AL);
- }
- fn instr_group_D8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) {
- ctx.builder.const_i32(0);
- codegen::gen_fpu_load_m32(ctx, modrm_byte);
- ctx.builder.call_fn3_i32_i64_i32(op)
- }
- fn instr_group_D8_reg_jit(ctx: &mut JitContext, r: u32, op: &str) {
- ctx.builder.const_i32(0);
- codegen::gen_fpu_get_sti(ctx, r);
- ctx.builder.call_fn3_i32_i64_i32(op)
- }
- pub fn instr_D8_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fadd")
- }
- pub fn instr_D8_0_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_D8_reg_jit(ctx, r, "fpu_fadd")
- }
- pub fn instr_D8_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fmul")
- }
- pub fn instr_D8_1_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_D8_reg_jit(ctx, r, "fpu_fmul")
- }
- pub fn instr_D8_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_fpu_load_m32(ctx, modrm_byte);
- ctx.builder.call_fn2_i64_i32("fpu_fcom")
- }
- pub fn instr_D8_2_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fpu_get_sti(ctx, r);
- ctx.builder.call_fn2_i64_i32("fpu_fcom")
- }
- pub fn instr_D8_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_fpu_load_m32(ctx, modrm_byte);
- ctx.builder.call_fn2_i64_i32("fpu_fcomp")
- }
- pub fn instr_D8_3_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fpu_get_sti(ctx, r);
- ctx.builder.call_fn2_i64_i32("fpu_fcomp")
- }
- pub fn instr_D8_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fsub")
- }
- pub fn instr_D8_4_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_D8_reg_jit(ctx, r, "fpu_fsub")
- }
- pub fn instr_D8_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fsubr")
- }
- pub fn instr_D8_5_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_D8_reg_jit(ctx, r, "fpu_fsubr")
- }
- pub fn instr_D8_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fdiv")
- }
- pub fn instr_D8_6_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_D8_reg_jit(ctx, r, "fpu_fdiv")
- }
- pub fn instr_D8_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_D8_mem_jit(ctx, modrm_byte, "fpu_fdivr")
- }
- pub fn instr_D8_7_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_D8_reg_jit(ctx, r, "fpu_fdivr")
- }
- pub fn instr16_D9_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_fpu_load_m32(ctx, modrm_byte);
- ctx.builder.call_fn2_i64_i32("fpu_push");
- }
- pub fn instr16_D9_0_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fpu_get_sti(ctx, r);
- ctx.builder.call_fn2_i64_i32("fpu_push");
- }
- pub fn instr32_D9_0_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_0_reg_jit(ctx, r) }
- pub fn instr32_D9_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_D9_0_mem_jit(ctx, modrm_byte)
- }
- pub fn instr16_D9_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr16_D9_1_reg_jit(ctx: &mut JitContext, r: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn1("fpu_fxch");
- }
- pub fn instr32_D9_1_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_1_reg_jit(ctx, r) }
- pub fn instr32_D9_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_D9_1_mem_jit(ctx, modrm_byte)
- }
- pub fn instr16_D9_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_fpu_get_sti(ctx, 0);
- ctx.builder.call_fn2_i64_i32_ret("f80_to_f32");
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write32(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- }
- pub fn instr16_D9_2_reg_jit(ctx: &mut JitContext, r: u32) {
- if r != 0 {
- codegen::gen_trigger_ud(ctx);
- }
- }
- pub fn instr32_D9_2_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_2_reg_jit(ctx, r) }
- pub fn instr32_D9_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_D9_2_mem_jit(ctx, modrm_byte)
- }
- pub fn instr16_D9_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_fpu_get_sti(ctx, 0);
- ctx.builder.call_fn2_i64_i32_ret("f80_to_f32");
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write32(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- codegen::gen_fn0_const(ctx.builder, "fpu_pop");
- }
- pub fn instr16_D9_3_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
- }
- pub fn instr32_D9_3_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_3_reg_jit(ctx, r) }
- pub fn instr32_D9_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_D9_3_mem_jit(ctx, modrm_byte)
- }
- pub fn instr16_D9_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
- ctx.builder,
- ctx.start_of_current_instruction as i32 & 0xFFF,
- );
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1("fpu_fldenv32");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- codegen::gen_get_page_fault(ctx.builder);
- ctx.builder.if_void();
- codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.return_();
- ctx.builder.block_end();
- }
- pub fn instr16_D9_4_reg_jit(ctx: &mut JitContext, r: u32) {
- match r {
- 0 | 1 | 4 | 5 => {
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn1("instr16_D9_4_reg");
- },
- _ => codegen::gen_trigger_ud(ctx),
- }
- }
- pub fn instr32_D9_4_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_4_reg_jit(ctx, r) }
- pub fn instr32_D9_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_D9_4_mem_jit(ctx, modrm_byte)
- }
- pub fn instr16_D9_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- ctx.builder.call_fn1("set_control_word");
- }
- pub fn instr16_D9_5_reg_jit(ctx: &mut JitContext, r: u32) {
- if r == 7 {
- codegen::gen_trigger_ud(ctx);
- }
- else {
- codegen::gen_fn1_const(ctx.builder, "instr16_D9_5_reg", r);
- }
- }
- pub fn instr32_D9_5_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_5_reg_jit(ctx, r) }
- pub fn instr32_D9_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_D9_5_mem_jit(ctx, modrm_byte)
- }
- pub fn instr16_D9_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
- ctx.builder,
- ctx.start_of_current_instruction as i32 & 0xFFF,
- );
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1("fpu_fstenv32");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- codegen::gen_get_page_fault(ctx.builder);
- ctx.builder.if_void();
- codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.return_();
- ctx.builder.block_end();
- }
- pub fn instr16_D9_6_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "instr16_D9_6_reg", r);
- }
- pub fn instr32_D9_6_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_6_reg_jit(ctx, r) }
- pub fn instr32_D9_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_D9_6_mem_jit(ctx, modrm_byte)
- }
- pub fn instr16_D9_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- ctx.builder
- .const_i32(global_pointers::fpu_control_word as i32);
- ctx.builder.load_aligned_u16(0);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write16(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- }
- pub fn instr16_D9_7_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "instr16_D9_7_reg", r);
- }
- pub fn instr32_D9_7_reg_jit(ctx: &mut JitContext, r: u32) { instr16_D9_7_reg_jit(ctx, r) }
- pub fn instr32_D9_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_D9_7_mem_jit(ctx, modrm_byte)
- }
- pub fn instr_DA_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- ctx.builder.const_i32(0);
- codegen::gen_fpu_load_i32(ctx, modrm_byte);
- ctx.builder.call_fn3_i32_i64_i32("fpu_fsubr")
- }
- pub fn instr_DA_5_reg_jit(ctx: &mut JitContext, r: u32) {
- if r == 1 {
- codegen::gen_fn0_const(ctx.builder, "fpu_fucompp");
- }
- else {
- codegen::gen_trigger_ud(ctx);
- };
- }
- pub fn instr_DB_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_fpu_load_i32(ctx, modrm_byte);
- ctx.builder.call_fn2_i64_i32("fpu_push");
- }
- pub fn instr_DB_0_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "instr_DB_0_reg", r);
- }
- pub fn instr_DB_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_fpu_get_sti(ctx, 0);
- ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i32");
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write32(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- }
- pub fn instr_DB_2_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "instr_DB_2_reg", r);
- }
- pub fn instr_DB_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_fpu_get_sti(ctx, 0);
- ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i32");
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write32(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- codegen::gen_fn0_const(ctx.builder, "fpu_pop");
- }
- pub fn instr_DB_3_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "instr_DB_3_reg", r);
- }
- pub fn instr_DB_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
- ctx.builder,
- ctx.start_of_current_instruction as i32 & 0xFFF,
- );
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1("fpu_fldm80");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- codegen::gen_get_page_fault(ctx.builder);
- ctx.builder.if_void();
- codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.return_();
- ctx.builder.block_end();
- }
- pub fn instr_DB_5_reg_jit(ctx: &mut JitContext, r: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn1("fpu_fucomi");
- }
- pub fn instr_DB_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_DB_6_reg_jit(ctx: &mut JitContext, r: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn1("fpu_fcomi");
- }
- fn instr_group_DC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) {
- ctx.builder.const_i32(0);
- codegen::gen_fpu_load_m64(ctx, modrm_byte);
- ctx.builder.call_fn3_i32_i64_i32(op)
- }
- fn instr_group_DC_reg_jit(ctx: &mut JitContext, r: u32, op: &str) {
- ctx.builder.const_i32(r as i32);
- codegen::gen_fpu_get_sti(ctx, r);
- ctx.builder.call_fn3_i32_i64_i32(op)
- }
- pub fn instr_DC_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fadd")
- }
- pub fn instr_DC_0_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DC_reg_jit(ctx, r, "fpu_fadd")
- }
- pub fn instr_DC_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fmul")
- }
- pub fn instr_DC_1_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DC_reg_jit(ctx, r, "fpu_fmul")
- }
- pub fn instr_DC_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_fpu_load_m64(ctx, modrm_byte);
- ctx.builder.call_fn2_i64_i32("fpu_fcom")
- }
- pub fn instr_DC_2_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fpu_get_sti(ctx, r);
- ctx.builder.call_fn2_i64_i32("fpu_fcom")
- }
- pub fn instr_DC_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_fpu_load_m64(ctx, modrm_byte);
- ctx.builder.call_fn2_i64_i32("fpu_fcomp")
- }
- pub fn instr_DC_3_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fpu_get_sti(ctx, r);
- ctx.builder.call_fn2_i64_i32("fpu_fcomp")
- }
- pub fn instr_DC_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fsub")
- }
- pub fn instr_DC_4_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DC_reg_jit(ctx, r, "fpu_fsub")
- }
- pub fn instr_DC_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fsubr")
- }
- pub fn instr_DC_5_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DC_reg_jit(ctx, r, "fpu_fsubr")
- }
- pub fn instr_DC_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fdiv")
- }
- pub fn instr_DC_6_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DC_reg_jit(ctx, r, "fpu_fdiv")
- }
- pub fn instr_DC_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DC_mem_jit(ctx, modrm_byte, "fpu_fdivr")
- }
- pub fn instr_DC_7_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DC_reg_jit(ctx, r, "fpu_fdivr")
- }
- pub fn instr16_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_fpu_load_m64(ctx, modrm_byte);
- ctx.builder.call_fn2_i64_i32("fpu_push");
- }
- pub fn instr16_DD_0_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "fpu_ffree", r);
- }
- pub fn instr32_DD_0_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_0_reg_jit(ctx, r) }
- pub fn instr32_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_DD_0_mem_jit(ctx, modrm_byte)
- }
- pub fn instr16_DD_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_fpu_get_sti(ctx, 0);
- ctx.builder.call_fn2_i64_i32_ret_i64("f80_to_f64");
- let value_local = ctx.builder.set_new_local_i64();
- codegen::gen_safe_write64(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local_i64(value_local);
- }
- pub fn instr16_DD_2_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "fpu_fst", r);
- }
- pub fn instr32_DD_2_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_2_reg_jit(ctx, r) }
- pub fn instr32_DD_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_DD_2_mem_jit(ctx, modrm_byte)
- }
- pub fn instr16_DD_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_fpu_get_sti(ctx, 0);
- ctx.builder.call_fn2_i64_i32_ret_i64("f80_to_f64");
- let value_local = ctx.builder.set_new_local_i64();
- codegen::gen_safe_write64(ctx, &address_local, &value_local);
- codegen::gen_fn0_const(ctx.builder, "fpu_pop");
- ctx.builder.free_local(address_local);
- ctx.builder.free_local_i64(value_local);
- }
- pub fn instr16_DD_3_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
- }
- pub fn instr32_DD_3_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_3_reg_jit(ctx, r) }
- pub fn instr32_DD_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_DD_3_mem_jit(ctx, modrm_byte)
- }
- pub fn instr16_DD_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr16_DD_5_reg_jit(ctx: &mut JitContext, r: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn1("fpu_fucomp");
- }
- pub fn instr32_DD_5_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_5_reg_jit(ctx, r) }
- pub fn instr32_DD_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_DD_5_mem_jit(ctx, modrm_byte)
- }
- fn instr_group_DE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) {
- ctx.builder.const_i32(0);
- codegen::gen_fpu_load_i16(ctx, modrm_byte);
- ctx.builder.call_fn3_i32_i64_i32(op)
- }
- fn instr_group_DE_reg_jit(ctx: &mut JitContext, r: u32, op: &str) {
- ctx.builder.const_i32(r as i32);
- codegen::gen_fpu_get_sti(ctx, r);
- ctx.builder.call_fn3_i32_i64_i32(op);
- codegen::gen_fn0_const(ctx.builder, "fpu_pop")
- }
- pub fn instr_DE_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fadd")
- }
- pub fn instr_DE_0_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DE_reg_jit(ctx, r, "fpu_fadd")
- }
- pub fn instr_DE_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fmul")
- }
- pub fn instr_DE_1_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DE_reg_jit(ctx, r, "fpu_fmul")
- }
- pub fn instr_DE_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_fpu_load_i16(ctx, modrm_byte);
- ctx.builder.call_fn2_i64_i32("fpu_fcom")
- }
- pub fn instr_DE_2_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fpu_get_sti(ctx, r);
- ctx.builder.call_fn2_i64_i32("fpu_fcom");
- codegen::gen_fn0_const(ctx.builder, "fpu_pop")
- }
- pub fn instr_DE_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_fpu_load_i16(ctx, modrm_byte);
- ctx.builder.call_fn2_i64_i32("fpu_fcomp")
- }
- pub fn instr_DE_3_reg_jit(ctx: &mut JitContext, r: u32) {
- if r == 1 {
- codegen::gen_fpu_get_sti(ctx, r);
- ctx.builder.call_fn2_i64_i32("fpu_fcomp");
- codegen::gen_fn0_const(ctx.builder, "fpu_pop")
- }
- else {
- codegen::gen_trigger_ud(ctx);
- }
- }
- pub fn instr_DE_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fsub")
- }
- pub fn instr_DE_4_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DE_reg_jit(ctx, r, "fpu_fsub")
- }
- pub fn instr_DE_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fsubr")
- }
- pub fn instr_DE_5_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DE_reg_jit(ctx, r, "fpu_fsubr")
- }
- pub fn instr_DE_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fdiv")
- }
- pub fn instr_DE_6_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DE_reg_jit(ctx, r, "fpu_fdiv")
- }
- pub fn instr_DE_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr_group_DE_mem_jit(ctx, modrm_byte, "fpu_fdivr")
- }
- pub fn instr_DE_7_reg_jit(ctx: &mut JitContext, r: u32) {
- instr_group_DE_reg_jit(ctx, r, "fpu_fdivr")
- }
- pub fn instr_DF_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_fpu_get_sti(ctx, 0);
- ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i16");
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write16(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- }
- pub fn instr_DF_2_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
- }
- pub fn instr_DF_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_fpu_get_sti(ctx, 0);
- ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i16");
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write16(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- codegen::gen_fn0_const(ctx.builder, "fpu_pop");
- }
- pub fn instr_DF_3_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r);
- }
- pub fn instr_DF_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- dbg_log!("fbld");
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_DF_4_reg_jit(ctx: &mut JitContext, r: u32) {
- if r == 0 {
- ctx.builder.call_fn0_ret("fpu_load_status_word");
- codegen::gen_set_reg16(ctx, regs::AX);
- }
- else {
- codegen::gen_trigger_ud(ctx);
- };
- }
- pub fn instr_DF_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_fpu_load_i64(ctx, modrm_byte);
- ctx.builder.call_fn2_i64_i32("fpu_push");
- }
- pub fn instr_DF_5_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_fn1_const(ctx.builder, "fpu_fucomip", r);
- }
- pub fn instr_DF_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- dbg_log!("fbstp");
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_DF_6_reg_jit(ctx: &mut JitContext, r: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn1("fpu_fcomip");
- }
- pub fn instr_DF_7_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx); }
- pub fn instr_DF_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_fpu_get_sti(ctx, 0);
- ctx.builder.call_fn2_i64_i32_ret_i64("fpu_convert_to_i64");
- let value_local = ctx.builder.set_new_local_i64();
- codegen::gen_safe_write64(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local_i64(value_local);
- codegen::gen_fn0_const(ctx.builder, "fpu_pop");
- }
- pub fn instr16_EB_jit(ctx: &mut JitContext, imm8: u32) {
- codegen::gen_jmp_rel16(ctx.builder, imm8 as u16);
- // dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
- }
- pub fn instr32_EB_jit(ctx: &mut JitContext, imm8: u32) {
- // jmp near
- codegen::gen_relative_jump(ctx.builder, imm8 as i32);
- // dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
- }
- define_instruction_read8!(gen_test8, instr_F6_0_mem_jit, instr_F6_0_reg_jit, imm8);
- define_instruction_read16!(
- gen_test16,
- instr16_F7_0_mem_jit,
- instr16_F7_0_reg_jit,
- imm16
- );
- define_instruction_read32!(
- gen_test32,
- instr32_F7_0_mem_jit,
- instr32_F7_0_reg_jit,
- imm32
- );
- pub fn instr_F6_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- instr_F6_0_mem_jit(ctx, modrm_byte, imm)
- }
- pub fn instr_F6_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
- instr_F6_0_reg_jit(ctx, r, imm)
- }
- pub fn instr16_F7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- instr16_F7_0_mem_jit(ctx, modrm_byte, imm)
- }
- pub fn instr16_F7_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
- instr16_F7_0_reg_jit(ctx, r, imm)
- }
- pub fn instr32_F7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- instr32_F7_0_mem_jit(ctx, modrm_byte, imm)
- }
- pub fn instr32_F7_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
- instr32_F7_0_reg_jit(ctx, r, imm)
- }
- define_instruction_read_write_mem16!(gen_not16, instr16_F7_2_mem_jit, instr16_F7_2_reg_jit, none);
- define_instruction_read_write_mem32!(gen_not32, instr32_F7_2_mem_jit, instr32_F7_2_reg_jit, none);
- define_instruction_read_write_mem16!(gen_neg16, instr16_F7_3_mem_jit, instr16_F7_3_reg_jit, none);
- define_instruction_read_write_mem32!(gen_neg32, instr32_F7_3_mem_jit, instr32_F7_3_reg_jit, none);
- pub fn instr16_F7_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1("mul16");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- }
- pub fn instr16_F7_4_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_reg16(ctx, r);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1("mul16");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- }
- pub fn instr32_F7_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- gen_mul32(ctx);
- }
- pub fn instr32_F7_4_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_reg32(ctx, r);
- gen_mul32(ctx);
- }
- pub fn instr16_F7_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- codegen::sign_extend_i16(ctx.builder);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1("imul16");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- }
- pub fn instr16_F7_5_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_reg16(ctx, r);
- codegen::sign_extend_i16(ctx.builder);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1("imul16");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- }
- pub fn instr32_F7_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- gen_imul32(ctx);
- }
- pub fn instr32_F7_5_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_reg32(ctx, r);
- gen_imul32(ctx);
- }
- pub fn instr16_F7_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1_ret("div16_without_fault");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- ctx.builder.eqz_i32();
- ctx.builder.if_void();
- codegen::gen_trigger_de(ctx);
- ctx.builder.block_end();
- }
- pub fn instr16_F7_6_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_reg16(ctx, r);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1_ret("div16_without_fault");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- ctx.builder.eqz_i32();
- ctx.builder.if_void();
- codegen::gen_trigger_de(ctx);
- ctx.builder.block_end();
- }
- pub fn instr32_F7_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- if false {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1_ret("div32_without_fault");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- ctx.builder.eqz_i32();
- ctx.builder.if_void();
- codegen::gen_trigger_de(ctx);
- ctx.builder.block_end();
- }
- else {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- let source_operand = ctx.builder.set_new_local();
- gen_div32(ctx, &source_operand);
- ctx.builder.free_local(source_operand);
- }
- }
- pub fn instr32_F7_6_reg_jit(ctx: &mut JitContext, r: u32) {
- if false {
- codegen::gen_get_reg32(ctx, r);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1_ret("div32_without_fault");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- ctx.builder.eqz_i32();
- ctx.builder.if_void();
- codegen::gen_trigger_de(ctx);
- ctx.builder.block_end();
- }
- else {
- gen_div32(ctx, &ctx.register_locals[r as usize].unsafe_clone());
- }
- }
- pub fn instr16_F7_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- codegen::sign_extend_i16(ctx.builder);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1_ret("idiv16_without_fault");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- ctx.builder.eqz_i32();
- ctx.builder.if_void();
- codegen::gen_trigger_de(ctx);
- ctx.builder.block_end();
- }
- pub fn instr16_F7_7_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_reg16(ctx, r);
- codegen::sign_extend_i16(ctx.builder);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1_ret("idiv16_without_fault");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- ctx.builder.eqz_i32();
- ctx.builder.if_void();
- codegen::gen_trigger_de(ctx);
- ctx.builder.block_end();
- }
- pub fn instr32_F7_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1_ret("idiv32_without_fault");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- ctx.builder.eqz_i32();
- ctx.builder.if_void();
- codegen::gen_trigger_de(ctx);
- ctx.builder.block_end();
- }
- pub fn instr32_F7_7_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_reg32(ctx, r);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn1_ret("idiv32_without_fault");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- ctx.builder.eqz_i32();
- ctx.builder.if_void();
- codegen::gen_trigger_de(ctx);
- ctx.builder.block_end();
- }
- pub fn instr_F8_jit(ctx: &mut JitContext) {
- codegen::gen_clear_flags_changed_bits(ctx.builder, 1);
- codegen::gen_clear_flags_bits(ctx.builder, 1);
- }
- pub fn instr_F9_jit(ctx: &mut JitContext) {
- codegen::gen_clear_flags_changed_bits(ctx.builder, 1);
- codegen::gen_set_flags_bits(ctx.builder, 1);
- }
- pub fn instr_FA_jit(ctx: &mut JitContext) {
- ctx.builder.call_fn0_ret("instr_FA_without_fault");
- ctx.builder.eqz_i32();
- ctx.builder.if_void();
- codegen::gen_trigger_gp(ctx, 0);
- ctx.builder.block_end();
- }
- pub fn instr_FB_jit(ctx: &mut JitContext) {
- ctx.builder.call_fn0_ret("instr_FB_without_fault");
- ctx.builder.eqz_i32();
- ctx.builder.if_void();
- codegen::gen_trigger_gp(ctx, 0);
- ctx.builder.block_end();
- // handle_irqs is specially handled in jit to be called one instruction after this one
- }
- pub fn instr_FC_jit(ctx: &mut JitContext) {
- ctx.builder.const_i32(global_pointers::flags as i32);
- codegen::gen_get_flags(ctx.builder);
- ctx.builder.const_i32(!FLAG_DIRECTION);
- ctx.builder.and_i32();
- ctx.builder.store_aligned_i32(0);
- }
- pub fn instr_FD_jit(ctx: &mut JitContext) {
- ctx.builder.const_i32(global_pointers::flags as i32);
- codegen::gen_get_flags(ctx.builder);
- ctx.builder.const_i32(FLAG_DIRECTION);
- ctx.builder.or_i32();
- ctx.builder.store_aligned_i32(0);
- }
- define_instruction_read_write_mem8!("inc8", instr_FE_0_mem_jit, instr_FE_0_reg_jit, none);
- define_instruction_read_write_mem8!("dec8", instr_FE_1_mem_jit, instr_FE_1_reg_jit, none);
- define_instruction_read_write_mem16!(gen_inc16, instr16_FF_0_mem_jit, instr16_FF_0_reg_jit, none);
- define_instruction_read_write_mem32!(gen_inc32, instr32_FF_0_mem_jit, instr32_FF_0_reg_jit, none);
- define_instruction_read_write_mem16!(gen_dec16, instr16_FF_1_mem_jit, instr16_FF_1_reg_jit, none);
- define_instruction_read_write_mem32!(gen_dec32, instr32_FF_1_mem_jit, instr32_FF_1_reg_jit, none);
- pub fn instr16_FF_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- codegen::gen_add_cs_offset(ctx);
- let new_eip = ctx.builder.set_new_local();
- codegen::gen_get_real_eip(ctx);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &value_local);
- ctx.builder.free_local(value_local);
- ctx.builder.const_i32(0);
- ctx.builder.get_local(&new_eip);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- ctx.builder.free_local(new_eip);
- }
- pub fn instr16_FF_2_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_real_eip(ctx);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &value_local);
- ctx.builder.free_local(value_local);
- ctx.builder.const_i32(0);
- codegen::gen_get_reg16(ctx, r);
- codegen::gen_add_cs_offset(ctx);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- }
- pub fn instr32_FF_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- codegen::gen_add_cs_offset(ctx);
- let new_eip = ctx.builder.set_new_local();
- codegen::gen_get_real_eip(ctx);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &value_local);
- ctx.builder.free_local(value_local);
- ctx.builder.const_i32(0);
- ctx.builder.get_local(&new_eip);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- ctx.builder.free_local(new_eip);
- }
- pub fn instr32_FF_2_reg_jit(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_real_eip(ctx);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &value_local);
- ctx.builder.free_local(value_local);
- ctx.builder.const_i32(0);
- codegen::gen_get_reg32(ctx, r);
- codegen::gen_add_cs_offset(ctx);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- }
- pub fn instr16_FF_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- ctx.builder.const_i32(0);
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- codegen::gen_add_cs_offset(ctx);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- }
- pub fn instr16_FF_4_reg_jit(ctx: &mut JitContext, r: u32) {
- ctx.builder.const_i32(0);
- codegen::gen_get_reg16(ctx, r);
- codegen::gen_add_cs_offset(ctx);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- }
- pub fn instr32_FF_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- ctx.builder.const_i32(0);
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- codegen::gen_add_cs_offset(ctx);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- }
- pub fn instr32_FF_4_reg_jit(ctx: &mut JitContext, r: u32) {
- ctx.builder.const_i32(0);
- codegen::gen_get_reg32(ctx, r);
- codegen::gen_add_cs_offset(ctx);
- ctx.builder
- .store_aligned_i32(global_pointers::instruction_pointer as u32);
- }
- pub fn instr16_FF_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- push16_mem_jit(ctx, modrm_byte)
- }
- pub fn instr16_FF_6_reg_jit(ctx: &mut JitContext, r: u32) { push16_reg_jit(ctx, r) }
- pub fn instr32_FF_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- push32_mem_jit(ctx, modrm_byte)
- }
- pub fn instr32_FF_6_reg_jit(ctx: &mut JitContext, r: u32) { push32_reg_jit(ctx, r) }
- // Code for conditional jumps is generated automatically by the basic block codegen
- pub fn instr16_0F80_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F81_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F82_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F83_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F84_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F85_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F86_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F87_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F88_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F89_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F8A_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F8B_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F8C_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F8D_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F8E_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr16_0F8F_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F80_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F81_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F82_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F83_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F84_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F85_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F86_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F87_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F88_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F89_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F8A_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F8B_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F8C_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F8D_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F8E_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr32_0F8F_jit(_ctx: &mut JitContext, _imm: u32) {}
- pub fn instr_90_jit(_ctx: &mut JitContext) {}
- fn gen_xchg_reg16(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_reg16(ctx, r);
- let tmp = ctx.builder.set_new_local();
- codegen::gen_get_reg16(ctx, regs::AX);
- codegen::gen_set_reg16(ctx, r);
- ctx.builder.get_local(&tmp);
- codegen::gen_set_reg16(ctx, regs::AX);
- ctx.builder.free_local(tmp);
- }
- fn gen_xchg_reg32(ctx: &mut JitContext, r: u32) {
- codegen::gen_get_reg32(ctx, r);
- let tmp = ctx.builder.set_new_local();
- codegen::gen_get_reg32(ctx, regs::EAX);
- codegen::gen_set_reg32(ctx, r);
- ctx.builder.get_local(&tmp);
- codegen::gen_set_reg32(ctx, regs::EAX);
- ctx.builder.free_local(tmp);
- }
- pub fn instr16_91_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::CX); }
- pub fn instr16_92_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::DX); }
- pub fn instr16_93_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::BX); }
- pub fn instr16_94_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::SP); }
- pub fn instr16_95_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::BP); }
- pub fn instr16_96_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::SI); }
- pub fn instr16_97_jit(ctx: &mut JitContext) { gen_xchg_reg16(ctx, regs::DI); }
- pub fn instr32_91_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::CX); }
- pub fn instr32_92_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::DX); }
- pub fn instr32_93_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::BX); }
- pub fn instr32_94_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::SP); }
- pub fn instr32_95_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::BP); }
- pub fn instr32_96_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::SI); }
- pub fn instr32_97_jit(ctx: &mut JitContext) { gen_xchg_reg32(ctx, regs::DI); }
- pub fn instr16_98_jit(ctx: &mut JitContext) {
- codegen::gen_get_reg8(ctx, regs::AL);
- codegen::sign_extend_i8(ctx.builder);
- codegen::gen_set_reg16(ctx, regs::AX);
- }
- pub fn instr32_98_jit(ctx: &mut JitContext) {
- codegen::gen_get_reg16(ctx, regs::AX);
- codegen::sign_extend_i16(ctx.builder);
- codegen::gen_set_reg32(ctx, regs::EAX);
- }
- pub fn instr16_99_jit(ctx: &mut JitContext) {
- codegen::gen_get_reg16(ctx, regs::AX);
- ctx.builder.const_i32(16);
- ctx.builder.shl_i32();
- ctx.builder.const_i32(31);
- ctx.builder.shr_s_i32();
- codegen::gen_set_reg16(ctx, regs::DX);
- }
- pub fn instr32_99_jit(ctx: &mut JitContext) {
- codegen::gen_get_reg32(ctx, regs::EAX);
- ctx.builder.const_i32(31);
- ctx.builder.shr_s_i32();
- codegen::gen_set_reg32(ctx, regs::EDX);
- }
- pub fn instr16_9C_jit(ctx: &mut JitContext) {
- ctx.builder.call_fn0_ret("instr_9C_check");
- ctx.builder.if_void();
- codegen::gen_trigger_gp(ctx, 0);
- ctx.builder.else_();
- ctx.builder.call_fn0_ret("get_eflags");
- let value = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &value);
- ctx.builder.block_end();
- ctx.builder.free_local(value);
- }
- pub fn instr32_9C_jit(ctx: &mut JitContext) {
- ctx.builder.call_fn0_ret("instr_9C_check");
- ctx.builder.if_void();
- codegen::gen_trigger_gp(ctx, 0);
- ctx.builder.else_();
- ctx.builder.call_fn0_ret("get_eflags");
- ctx.builder.const_i32(0xFCFFFF);
- ctx.builder.and_i32();
- let value = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &value);
- ctx.builder.block_end();
- ctx.builder.free_local(value);
- }
- fn gen_popf(ctx: &mut JitContext, is_32: bool) {
- ctx.builder.call_fn0_ret("instr_9C_check");
- ctx.builder.if_void();
- codegen::gen_trigger_gp(ctx, 0);
- ctx.builder.else_();
- codegen::gen_get_flags(ctx.builder);
- let old_eflags = ctx.builder.set_new_local();
- if is_32 {
- codegen::gen_pop32s(ctx);
- }
- else {
- ctx.builder.get_local(&old_eflags);
- ctx.builder.const_i32(!0xFFFF);
- ctx.builder.and_i32();
- codegen::gen_pop16(ctx);
- ctx.builder.or_i32();
- }
- ctx.builder.call_fn1("update_eflags");
- ctx.builder.get_local(&old_eflags);
- ctx.builder.free_local(old_eflags);
- ctx.builder.const_i32(FLAG_INTERRUPT);
- ctx.builder.and_i32();
- ctx.builder.eqz_i32();
- codegen::gen_get_flags(ctx.builder);
- ctx.builder.const_i32(FLAG_INTERRUPT);
- ctx.builder.and_i32();
- ctx.builder.eqz_i32();
- ctx.builder.eqz_i32();
- ctx.builder.and_i32();
- ctx.builder.if_void();
- {
- codegen::gen_set_eip_to_after_current_instruction(ctx);
- codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- codegen::gen_fn0_const(ctx.builder, "handle_irqs");
- ctx.builder.return_();
- }
- ctx.builder.block_end();
- ctx.builder.block_end();
- }
- pub fn instr16_9D_jit(ctx: &mut JitContext) { gen_popf(ctx, false) }
- pub fn instr32_9D_jit(ctx: &mut JitContext) { gen_popf(ctx, true) }
- pub fn instr_9E_jit(ctx: &mut JitContext) {
- ctx.builder.const_i32(global_pointers::flags as i32);
- codegen::gen_get_flags(ctx.builder);
- ctx.builder.const_i32(!0xFF);
- ctx.builder.and_i32();
- codegen::gen_get_reg8(ctx, regs::AH);
- ctx.builder.or_i32();
- ctx.builder.const_i32(FLAGS_MASK);
- ctx.builder.and_i32();
- ctx.builder.const_i32(FLAGS_DEFAULT);
- ctx.builder.or_i32();
- ctx.builder.store_aligned_i32(0);
- codegen::gen_clear_flags_changed_bits(ctx.builder, 0xFF);
- }
- pub fn instr_9F_jit(ctx: &mut JitContext) {
- ctx.builder.call_fn0_ret("get_eflags");
- codegen::gen_set_reg8(ctx, regs::AH);
- }
- pub fn instr_A0_jit(ctx: &mut JitContext, immaddr: u32) {
- ctx.builder.const_i32(immaddr as i32);
- jit_add_seg_offset(ctx, regs::DS);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read8(ctx, &address_local);
- ctx.builder.free_local(address_local);
- codegen::gen_set_reg8(ctx, regs::AL);
- }
- pub fn instr16_A1_jit(ctx: &mut JitContext, immaddr: u32) {
- ctx.builder.const_i32(immaddr as i32);
- jit_add_seg_offset(ctx, regs::DS);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read16(ctx, &address_local);
- ctx.builder.free_local(address_local);
- codegen::gen_set_reg16(ctx, regs::AX);
- }
- pub fn instr32_A1_jit(ctx: &mut JitContext, immaddr: u32) {
- ctx.builder.const_i32(immaddr as i32);
- jit_add_seg_offset(ctx, regs::DS);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read32(ctx, &address_local);
- ctx.builder.free_local(address_local);
- codegen::gen_set_reg32(ctx, regs::EAX);
- }
- pub fn instr_A2_jit(ctx: &mut JitContext, immaddr: u32) {
- ctx.builder.const_i32(immaddr as i32);
- jit_add_seg_offset(ctx, regs::DS);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_write8(
- ctx,
- &address_local,
- &ctx.register_locals[regs::EAX as usize].unsafe_clone(),
- );
- ctx.builder.free_local(address_local);
- }
- pub fn instr16_A3_jit(ctx: &mut JitContext, immaddr: u32) {
- ctx.builder.const_i32(immaddr as i32);
- jit_add_seg_offset(ctx, regs::DS);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_write16(
- ctx,
- &address_local,
- &ctx.register_locals[regs::EAX as usize].unsafe_clone(),
- );
- ctx.builder.free_local(address_local);
- }
- pub fn instr32_A3_jit(ctx: &mut JitContext, immaddr: u32) {
- ctx.builder.const_i32(immaddr as i32);
- jit_add_seg_offset(ctx, regs::DS);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_write32(
- ctx,
- &address_local,
- &ctx.register_locals[regs::EAX as usize].unsafe_clone(),
- );
- ctx.builder.free_local(address_local);
- }
- pub fn instr_A8_jit(ctx: &mut JitContext, imm8: u32) {
- gen_test8(
- ctx.builder,
- &ctx.register_locals[0],
- &LocalOrImmediate::Immediate(imm8 as i32),
- );
- }
- pub fn instr16_A9_jit(ctx: &mut JitContext, imm16: u32) {
- gen_test16(
- ctx.builder,
- &ctx.register_locals[0],
- &LocalOrImmediate::Immediate(imm16 as i32),
- );
- }
- pub fn instr32_A9_jit(ctx: &mut JitContext, imm32: u32) {
- gen_test32(
- ctx.builder,
- &ctx.register_locals[0],
- &LocalOrImmediate::Immediate(imm32 as i32),
- );
- }
- #[derive(PartialEq)]
- enum String {
- INS,
- OUTS,
- MOVS,
- CMPS,
- STOS,
- LODS,
- SCAS,
- }
- fn gen_string_ins(ctx: &mut JitContext, ins: String, size: u8, prefix: u8) {
- dbg_assert!(prefix == 0 || prefix == 0xF2 || prefix == 0xF3);
- dbg_assert!(size == 8 || size == 16 || size == 32);
- let mut args = 0;
- args += 1;
- ctx.builder.const_i32(ctx.cpu.asize_32() as i32);
- if ins == String::OUTS || ins == String::CMPS || ins == String::LODS || ins == String::MOVS {
- args += 1;
- ctx.builder.const_i32(0);
- jit_add_seg_offset(ctx, regs::DS);
- }
- let name = format!(
- "{}{}{}",
- match ins {
- String::INS => "ins",
- String::OUTS => "outs",
- String::MOVS => "movs",
- String::CMPS => "cmps",
- String::STOS => "stos",
- String::LODS => "lods",
- String::SCAS => "scas",
- },
- if size == 8 {
- "b"
- }
- else if size == 16 {
- "w"
- }
- else {
- "d"
- },
- if prefix == 0xF2 || prefix == 0xF3 {
- match ins {
- String::CMPS | String::SCAS => {
- if prefix == 0xF2 {
- "_repnz"
- }
- else {
- "_repz"
- }
- },
- _ => "_rep",
- }
- }
- else {
- "_no_rep"
- }
- );
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- if args == 1 {
- ctx.builder.call_fn1(&name)
- }
- else if args == 2 {
- ctx.builder.call_fn2(&name)
- }
- else {
- dbg_assert!(false);
- }
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- }
- pub fn instr_6C_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 8, 0) }
- pub fn instr_F26C_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 8, 0xF2) }
- pub fn instr_F36C_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 8, 0xF3) }
- pub fn instr16_6D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 16, 0) }
- pub fn instr16_F26D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 16, 0xF2) }
- pub fn instr16_F36D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 16, 0xF3) }
- pub fn instr32_6D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 32, 0) }
- pub fn instr32_F26D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 32, 0xF2) }
- pub fn instr32_F36D_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::INS, 32, 0xF3) }
- pub fn instr_6E_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 8, 0) }
- pub fn instr_F26E_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 8, 0xF2) }
- pub fn instr_F36E_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 8, 0xF3) }
- pub fn instr16_6F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 16, 0) }
- pub fn instr16_F26F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 16, 0xF2) }
- pub fn instr16_F36F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 16, 0xF3) }
- pub fn instr32_6F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 32, 0) }
- pub fn instr32_F26F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 32, 0xF2) }
- pub fn instr32_F36F_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::OUTS, 32, 0xF3) }
- pub fn instr_A4_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 8, 0) }
- pub fn instr_F2A4_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 8, 0xF2) }
- pub fn instr_F3A4_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 8, 0xF3) }
- pub fn instr16_A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 16, 0) }
- pub fn instr16_F2A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 16, 0xF2) }
- pub fn instr16_F3A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 16, 0xF3) }
- pub fn instr32_A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 32, 0) }
- pub fn instr32_F2A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 32, 0xF2) }
- pub fn instr32_F3A5_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::MOVS, 32, 0xF3) }
- pub fn instr_A6_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 8, 0) }
- pub fn instr_F2A6_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 8, 0xF2) }
- pub fn instr_F3A6_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 8, 0xF3) }
- pub fn instr16_A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 16, 0) }
- pub fn instr16_F2A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 16, 0xF2) }
- pub fn instr16_F3A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 16, 0xF3) }
- pub fn instr32_A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 32, 0) }
- pub fn instr32_F2A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 32, 0xF2) }
- pub fn instr32_F3A7_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::CMPS, 32, 0xF3) }
- pub fn instr_AA_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 8, 0) }
- pub fn instr_F2AA_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 8, 0xF2) }
- pub fn instr_F3AA_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 8, 0xF3) }
- pub fn instr16_AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 16, 0) }
- pub fn instr16_F2AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 16, 0xF2) }
- pub fn instr16_F3AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 16, 0xF3) }
- pub fn instr32_AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 32, 0) }
- pub fn instr32_F2AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 32, 0xF2) }
- pub fn instr32_F3AB_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::STOS, 32, 0xF3) }
- pub fn instr_AC_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 8, 0) }
- pub fn instr_F2AC_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 8, 0xF2) }
- pub fn instr_F3AC_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 8, 0xF3) }
- pub fn instr16_AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 16, 0) }
- pub fn instr16_F2AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 16, 0xF2) }
- pub fn instr16_F3AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 16, 0xF3) }
- pub fn instr32_AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 32, 0) }
- pub fn instr32_F2AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 32, 0xF2) }
- pub fn instr32_F3AD_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::LODS, 32, 0xF3) }
- pub fn instr_AE_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 8, 0) }
- pub fn instr_F2AE_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 8, 0xF2) }
- pub fn instr_F3AE_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 8, 0xF3) }
- pub fn instr16_AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 16, 0) }
- pub fn instr16_F2AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 16, 0xF2) }
- pub fn instr16_F3AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 16, 0xF3) }
- pub fn instr32_AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 32, 0) }
- pub fn instr32_F2AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 32, 0xF2) }
- pub fn instr32_F3AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 32, 0xF3) }
- pub fn instr_0F31_jit(ctx: &mut JitContext) {
- ctx.builder.load_fixed_u8(global_pointers::cpl as u32);
- ctx.builder.eqz_i32();
- dbg_assert!(regs::CR4_TSD < 0x100);
- ctx.builder
- .load_fixed_u8(global_pointers::get_creg_offset(4));
- ctx.builder.const_i32(regs::CR4_TSD as i32);
- ctx.builder.and_i32();
- ctx.builder.eqz_i32();
- ctx.builder.or_i32();
- ctx.builder.if_void();
- ctx.builder.call_fn0_ret_i64("read_tsc");
- let tsc = ctx.builder.tee_new_local_i64();
- ctx.builder.wrap_i64_to_i32();
- codegen::gen_set_reg32(ctx, regs::EAX);
- ctx.builder.get_local_i64(&tsc);
- ctx.builder.const_i64(32);
- ctx.builder.shr_u_i64();
- ctx.builder.wrap_i64_to_i32();
- codegen::gen_set_reg32(ctx, regs::EDX);
- ctx.builder.free_local_i64(tsc);
- ctx.builder.else_();
- codegen::gen_trigger_gp(ctx, 0);
- ctx.builder.block_end();
- }
- pub fn instr_0F18_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
- pub fn instr_0F18_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
- pub fn instr_0F19_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
- pub fn instr_0F19_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
- pub fn instr_0F1C_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
- pub fn instr_0F1C_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
- pub fn instr_0F1D_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
- pub fn instr_0F1D_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
- pub fn instr_0F1E_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
- pub fn instr_0F1E_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
- pub fn instr_0F1F_mem_jit(_ctx: &mut JitContext, _modrm_byte: ModrmByte, _reg: u32) {}
- pub fn instr_0F1F_reg_jit(_ctx: &mut JitContext, _r1: u32, _r2: u32) {}
- define_instruction_read_write_mem16!(
- "shld16",
- instr16_0FA4_mem_jit,
- instr16_0FA4_reg_jit,
- reg,
- imm8_5bits
- );
- define_instruction_read_write_mem32!(
- "shld32",
- instr32_0FA4_mem_jit,
- instr32_0FA4_reg_jit,
- reg,
- imm8_5bits
- );
- define_instruction_read_write_mem16!(
- "shld16",
- instr16_0FA5_mem_jit,
- instr16_0FA5_reg_jit,
- reg,
- cl
- );
- define_instruction_read_write_mem32!(
- "shld32",
- instr32_0FA5_mem_jit,
- instr32_0FA5_reg_jit,
- reg,
- cl
- );
- define_instruction_read_write_mem16!(
- "shrd16",
- instr16_0FAC_mem_jit,
- instr16_0FAC_reg_jit,
- reg,
- imm8_5bits
- );
- define_instruction_read_write_mem32!(
- "shrd32",
- instr32_0FAC_mem_jit,
- instr32_0FAC_reg_jit,
- reg,
- imm8_5bits
- );
- define_instruction_read_write_mem16!(
- "shrd16",
- instr16_0FAD_mem_jit,
- instr16_0FAD_reg_jit,
- reg,
- cl
- );
- define_instruction_read_write_mem32!(
- "shrd32",
- instr32_0FAD_mem_jit,
- instr32_0FAD_reg_jit,
- reg,
- cl
- );
- pub fn instr16_0FB1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg16(ctx, r1);
- ctx.builder.const_i32(r2 as i32);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn2_ret("cmpxchg16");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- codegen::gen_set_reg16(ctx, r1);
- }
- pub fn instr16_0FB1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
- ctx.builder.const_i32(r as i32);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn2_ret("cmpxchg16");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn instr32_0FB1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg32(ctx, r1);
- gen_cmpxchg32(ctx, r2);
- codegen::gen_set_reg32(ctx, r1);
- }
- pub fn instr32_0FB1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
- gen_cmpxchg32(ctx, r);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn instr16_0FB6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg8(ctx, r1);
- codegen::gen_set_reg16(ctx, r2);
- }
- pub fn instr16_0FB6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
- codegen::gen_set_reg16(ctx, r);
- }
- pub fn instr32_0FB6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg8(ctx, r1);
- codegen::gen_set_reg32(ctx, r2);
- }
- pub fn instr32_0FB6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr16_0FB7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- codegen::gen_set_reg16(ctx, r);
- }
- pub fn instr16_0FB7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg16(ctx, r1);
- codegen::gen_set_reg16(ctx, r2);
- }
- pub fn instr32_0FB7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr32_0FB7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg16(ctx, r1);
- codegen::gen_set_reg32(ctx, r2);
- }
- pub fn instr16_F30FB8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- ctx.builder.call_fn1_ret("popcnt");
- codegen::gen_set_reg16(ctx, r);
- }
- pub fn instr16_F30FB8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg16(ctx, r1);
- ctx.builder.call_fn1_ret("popcnt");
- codegen::gen_set_reg16(ctx, r2);
- }
- pub fn instr32_F30FB8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- ctx.builder.call_fn1_ret("popcnt");
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr32_F30FB8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg32(ctx, r1);
- ctx.builder.call_fn1_ret("popcnt");
- codegen::gen_set_reg32(ctx, r2);
- }
- define_instruction_write_reg16!("bsf16", instr16_0FBC_mem_jit, instr16_0FBC_reg_jit);
- define_instruction_write_reg32!(gen_bsf32, instr32_0FBC_mem_jit, instr32_0FBC_reg_jit);
- define_instruction_write_reg16!("bsr16", instr16_0FBD_mem_jit, instr16_0FBD_reg_jit);
- define_instruction_write_reg32!(gen_bsr32, instr32_0FBD_mem_jit, instr32_0FBD_reg_jit);
- pub fn instr16_0FBE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg8(ctx, r1);
- codegen::sign_extend_i8(ctx.builder);
- codegen::gen_set_reg16(ctx, r2);
- }
- pub fn instr16_0FBE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
- codegen::sign_extend_i8(ctx.builder);
- codegen::gen_set_reg16(ctx, r);
- }
- pub fn instr32_0FBE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg8(ctx, r1);
- codegen::sign_extend_i8(ctx.builder);
- codegen::gen_set_reg32(ctx, r2);
- }
- pub fn instr32_0FBE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
- codegen::sign_extend_i8(ctx.builder);
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr16_0FBF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg16(ctx, r1);
- codegen::sign_extend_i16(ctx.builder);
- codegen::gen_set_reg16(ctx, r2);
- }
- pub fn instr16_0FBF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- codegen::sign_extend_i16(ctx.builder);
- codegen::gen_set_reg16(ctx, r);
- }
- pub fn instr32_0FBF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg16(ctx, r1);
- codegen::sign_extend_i16(ctx.builder);
- codegen::gen_set_reg32(ctx, r2);
- }
- pub fn instr32_0FBF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- codegen::sign_extend_i16(ctx.builder);
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr16_0FC1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
- ctx.builder.const_i32(r as i32);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn2_ret("xadd16");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn instr16_0FC1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg16(ctx, r1);
- ctx.builder.const_i32(r2 as i32);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.call_fn2_ret("xadd16");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- codegen::gen_set_reg16(ctx, r1);
- }
- pub fn instr32_0FC1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
- let dest_operand = ctx.builder.set_new_local();
- gen_xadd32(ctx, &dest_operand, r);
- ctx.builder.get_local(&dest_operand);
- ctx.builder.free_local(dest_operand);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn instr32_0FC1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg32(ctx, r1);
- let dest_operand = ctx.builder.set_new_local();
- gen_xadd32(ctx, &dest_operand, r2);
- ctx.builder.get_local(&dest_operand);
- codegen::gen_set_reg32(ctx, r1);
- ctx.builder.free_local(dest_operand);
- }
- pub fn instr_0FC3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_write32(
- ctx,
- &address_local,
- &ctx.register_locals[r as usize].unsafe_clone(),
- );
- ctx.builder.free_local(address_local);
- }
- pub fn instr_0FC3_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) { codegen::gen_trigger_ud(ctx) }
- pub fn instr16_0FC7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- // cmpxchg8b
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read_write(ctx, BitSize::QWORD, &address_local, &|ref mut ctx| {
- let dest_operand = ctx.builder.tee_new_local_i64();
- codegen::gen_get_reg32(ctx, regs::EDX);
- ctx.builder.extend_unsigned_i32_to_i64();
- ctx.builder.const_i64(32);
- ctx.builder.shl_i64();
- codegen::gen_get_reg32(ctx, regs::EAX);
- ctx.builder.extend_unsigned_i32_to_i64();
- ctx.builder.or_i64();
- ctx.builder.eq_i64();
- ctx.builder.if_i64();
- {
- codegen::gen_set_flags_bits(ctx.builder, FLAG_ZERO);
- codegen::gen_get_reg32(ctx, regs::ECX);
- ctx.builder.extend_unsigned_i32_to_i64();
- ctx.builder.const_i64(32);
- ctx.builder.shl_i64();
- codegen::gen_get_reg32(ctx, regs::EBX);
- ctx.builder.extend_unsigned_i32_to_i64();
- ctx.builder.or_i64();
- }
- ctx.builder.else_();
- {
- codegen::gen_clear_flags_bits(ctx.builder, FLAG_ZERO);
- ctx.builder.get_local_i64(&dest_operand);
- ctx.builder.wrap_i64_to_i32();
- codegen::gen_set_reg32(ctx, regs::EAX);
- ctx.builder.get_local_i64(&dest_operand);
- ctx.builder.const_i64(32);
- ctx.builder.shr_u_i64();
- ctx.builder.wrap_i64_to_i32();
- codegen::gen_set_reg32(ctx, regs::EDX);
- ctx.builder.get_local_i64(&dest_operand);
- }
- ctx.builder.block_end();
- codegen::gen_clear_flags_changed_bits(ctx.builder, FLAG_ZERO);
- ctx.builder.free_local_i64(dest_operand);
- });
- ctx.builder.free_local(address_local);
- }
- pub fn instr16_0FC7_1_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx); }
- pub fn instr32_0FC7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
- instr16_0FC7_1_mem_jit(ctx, modrm_byte);
- }
- pub fn instr32_0FC7_1_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx); }
- pub fn instr_C6_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
- // reg8[r] = imm;
- ctx.builder.const_i32(imm as i32);
- codegen::gen_set_reg8(ctx, r);
- }
- pub fn instr_C6_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- ctx.builder.const_i32(imm as i32);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write8(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- }
- pub fn instr16_C7_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
- // reg16[r] = imm;
- ctx.builder.const_i32(imm as i32);
- codegen::gen_set_reg16(ctx, r);
- }
- pub fn instr16_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- ctx.builder.const_i32(imm as i32);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write16(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- }
- pub fn instr32_C7_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
- // reg32[r] = imm;
- ctx.builder.const_i32(imm as i32);
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr32_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- ctx.builder.const_i32(imm as i32);
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write32(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- }
- pub fn instr_0FC8_jit(ctx: &mut JitContext) { gen_bswap(ctx, 0) }
- pub fn instr_0FC9_jit(ctx: &mut JitContext) { gen_bswap(ctx, 1) }
- pub fn instr_0FCA_jit(ctx: &mut JitContext) { gen_bswap(ctx, 2) }
- pub fn instr_0FCB_jit(ctx: &mut JitContext) { gen_bswap(ctx, 3) }
- pub fn instr_0FCC_jit(ctx: &mut JitContext) { gen_bswap(ctx, 4) }
- pub fn instr_0FCD_jit(ctx: &mut JitContext) { gen_bswap(ctx, 5) }
- pub fn instr_0FCE_jit(ctx: &mut JitContext) { gen_bswap(ctx, 6) }
- pub fn instr_0FCF_jit(ctx: &mut JitContext) { gen_bswap(ctx, 7) }
- define_instruction_write_reg16!("imul_reg16", instr16_0FAF_mem_jit, instr16_0FAF_reg_jit);
- define_instruction_write_reg32!(gen_imul_reg32, instr32_0FAF_mem_jit, instr32_0FAF_reg_jit);
- macro_rules! define_cmovcc16(
- ($cond:expr, $name_mem:ident, $name_reg:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
- let value = ctx.builder.set_new_local();
- codegen::gen_condition_fn(ctx, $cond);
- ctx.builder.if_void();
- ctx.builder.get_local(&value);
- codegen::gen_set_reg16(ctx, r);
- ctx.builder.block_end();
- ctx.builder.free_local(value);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_condition_fn(ctx, $cond);
- ctx.builder.if_void();
- codegen::gen_get_reg16(ctx, r1);
- codegen::gen_set_reg16(ctx, r2);
- ctx.builder.block_end();
- }
- );
- );
- macro_rules! define_cmovcc32(
- ($cond:expr, $name_mem:ident, $name_reg:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- let value = ctx.builder.set_new_local();
- codegen::gen_condition_fn(ctx, $cond);
- ctx.builder.if_void();
- ctx.builder.get_local(&value);
- codegen::gen_set_reg32(ctx, r);
- ctx.builder.block_end();
- ctx.builder.free_local(value);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_condition_fn(ctx, $cond);
- ctx.builder.if_void();
- codegen::gen_get_reg32(ctx, r1);
- codegen::gen_set_reg32(ctx, r2);
- ctx.builder.block_end();
- }
- );
- );
- define_cmovcc16!(0x0, instr16_0F40_mem_jit, instr16_0F40_reg_jit);
- define_cmovcc16!(0x1, instr16_0F41_mem_jit, instr16_0F41_reg_jit);
- define_cmovcc16!(0x2, instr16_0F42_mem_jit, instr16_0F42_reg_jit);
- define_cmovcc16!(0x3, instr16_0F43_mem_jit, instr16_0F43_reg_jit);
- define_cmovcc16!(0x4, instr16_0F44_mem_jit, instr16_0F44_reg_jit);
- define_cmovcc16!(0x5, instr16_0F45_mem_jit, instr16_0F45_reg_jit);
- define_cmovcc16!(0x6, instr16_0F46_mem_jit, instr16_0F46_reg_jit);
- define_cmovcc16!(0x7, instr16_0F47_mem_jit, instr16_0F47_reg_jit);
- define_cmovcc16!(0x8, instr16_0F48_mem_jit, instr16_0F48_reg_jit);
- define_cmovcc16!(0x9, instr16_0F49_mem_jit, instr16_0F49_reg_jit);
- define_cmovcc16!(0xA, instr16_0F4A_mem_jit, instr16_0F4A_reg_jit);
- define_cmovcc16!(0xB, instr16_0F4B_mem_jit, instr16_0F4B_reg_jit);
- define_cmovcc16!(0xC, instr16_0F4C_mem_jit, instr16_0F4C_reg_jit);
- define_cmovcc16!(0xD, instr16_0F4D_mem_jit, instr16_0F4D_reg_jit);
- define_cmovcc16!(0xE, instr16_0F4E_mem_jit, instr16_0F4E_reg_jit);
- define_cmovcc16!(0xF, instr16_0F4F_mem_jit, instr16_0F4F_reg_jit);
- define_cmovcc32!(0x0, instr32_0F40_mem_jit, instr32_0F40_reg_jit);
- define_cmovcc32!(0x1, instr32_0F41_mem_jit, instr32_0F41_reg_jit);
- define_cmovcc32!(0x2, instr32_0F42_mem_jit, instr32_0F42_reg_jit);
- define_cmovcc32!(0x3, instr32_0F43_mem_jit, instr32_0F43_reg_jit);
- define_cmovcc32!(0x4, instr32_0F44_mem_jit, instr32_0F44_reg_jit);
- define_cmovcc32!(0x5, instr32_0F45_mem_jit, instr32_0F45_reg_jit);
- define_cmovcc32!(0x6, instr32_0F46_mem_jit, instr32_0F46_reg_jit);
- define_cmovcc32!(0x7, instr32_0F47_mem_jit, instr32_0F47_reg_jit);
- define_cmovcc32!(0x8, instr32_0F48_mem_jit, instr32_0F48_reg_jit);
- define_cmovcc32!(0x9, instr32_0F49_mem_jit, instr32_0F49_reg_jit);
- define_cmovcc32!(0xA, instr32_0F4A_mem_jit, instr32_0F4A_reg_jit);
- define_cmovcc32!(0xB, instr32_0F4B_mem_jit, instr32_0F4B_reg_jit);
- define_cmovcc32!(0xC, instr32_0F4C_mem_jit, instr32_0F4C_reg_jit);
- define_cmovcc32!(0xD, instr32_0F4D_mem_jit, instr32_0F4D_reg_jit);
- define_cmovcc32!(0xE, instr32_0F4E_mem_jit, instr32_0F4E_reg_jit);
- define_cmovcc32!(0xF, instr32_0F4F_mem_jit, instr32_0F4F_reg_jit);
- macro_rules! define_setcc(
- ($cond:expr, $name_mem:ident, $name_reg:ident) => (
- pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, _r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- codegen::gen_condition_fn(ctx, $cond);
- ctx.builder.const_i32(0);
- ctx.builder.ne_i32();
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write8(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- }
- pub fn $name_reg(ctx: &mut JitContext, r1: u32, _r2: u32) {
- codegen::gen_condition_fn(ctx, $cond);
- ctx.builder.const_i32(0);
- ctx.builder.ne_i32();
- codegen::gen_set_reg8(ctx, r1);
- }
- );
- );
- define_setcc!(0x0, instr_0F90_mem_jit, instr_0F90_reg_jit);
- define_setcc!(0x1, instr_0F91_mem_jit, instr_0F91_reg_jit);
- define_setcc!(0x2, instr_0F92_mem_jit, instr_0F92_reg_jit);
- define_setcc!(0x3, instr_0F93_mem_jit, instr_0F93_reg_jit);
- define_setcc!(0x4, instr_0F94_mem_jit, instr_0F94_reg_jit);
- define_setcc!(0x5, instr_0F95_mem_jit, instr_0F95_reg_jit);
- define_setcc!(0x6, instr_0F96_mem_jit, instr_0F96_reg_jit);
- define_setcc!(0x7, instr_0F97_mem_jit, instr_0F97_reg_jit);
- define_setcc!(0x8, instr_0F98_mem_jit, instr_0F98_reg_jit);
- define_setcc!(0x9, instr_0F99_mem_jit, instr_0F99_reg_jit);
- define_setcc!(0xA, instr_0F9A_mem_jit, instr_0F9A_reg_jit);
- define_setcc!(0xB, instr_0F9B_mem_jit, instr_0F9B_reg_jit);
- define_setcc!(0xC, instr_0F9C_mem_jit, instr_0F9C_reg_jit);
- define_setcc!(0xD, instr_0F9D_mem_jit, instr_0F9D_reg_jit);
- define_setcc!(0xE, instr_0F9E_mem_jit, instr_0F9E_reg_jit);
- define_setcc!(0xF, instr_0F9F_mem_jit, instr_0F9F_reg_jit);
- pub fn instr_0F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- let dest = global_pointers::get_reg_xmm_offset(r);
- codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
- }
- pub fn instr_0F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
- pub fn instr_660F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- let dest = global_pointers::get_reg_xmm_offset(r);
- codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
- }
- pub fn instr_660F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
- pub fn instr_F20F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- instr_F30F7E_mem_jit(ctx, modrm_byte, r)
- }
- pub fn instr_F20F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder.const_i32(r1 as i32);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2("instr_F20F10_reg");
- }
- pub fn instr_0F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- instr_0F29_mem_jit(ctx, modrm_byte, r)
- }
- pub fn instr_0F11_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
- pub fn instr_660F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- instr_660F29_mem_jit(ctx, modrm_byte, r)
- }
- pub fn instr_660F11_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
- pub fn instr_F20F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- instr_660FD6_mem_jit(ctx, modrm_byte, r)
- }
- pub fn instr_F20F11_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder.const_i32(r1 as i32);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2("instr_F20F11_reg");
- }
- pub fn instr_0F28_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- let dest = global_pointers::get_reg_xmm_offset(r);
- codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
- }
- pub fn instr_0F28_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
- pub fn instr_660F28_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- let dest = global_pointers::get_reg_xmm_offset(r);
- codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
- }
- pub fn instr_660F28_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
- pub fn instr_0F29_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- // XXX: Aligned write or #gp
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
- ctx.builder.load_aligned_i64(0);
- let value_local_low = ctx.builder.set_new_local_i64();
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r) as i32 + 8);
- ctx.builder.load_aligned_i64(0);
- let value_local_high = ctx.builder.set_new_local_i64();
- codegen::gen_safe_write128(ctx, &address_local, &value_local_low, &value_local_high);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local_i64(value_local_low);
- ctx.builder.free_local_i64(value_local_high);
- }
- pub fn instr_0F29_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
- pub fn instr_660F29_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- instr_0F29_mem_jit(ctx, modrm_byte, r);
- }
- pub fn instr_660F29_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
- pub fn instr_0F2B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- instr_0F29_mem_jit(ctx, modrm_byte, r)
- }
- pub fn instr_0F2B_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660F2B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- instr_0F29_mem_jit(ctx, modrm_byte, r)
- }
- pub fn instr_660F2B_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_F20F2C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
- ctx.builder.reinterpret_i64_as_f64();
- ctx.builder
- .call_fn1_f64_ret("sse_convert_with_truncation_f64_to_i32");
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr_F20F2C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
- ctx.builder.load_aligned_f64(0);
- ctx.builder
- .call_fn1_f64_ret("sse_convert_with_truncation_f64_to_i32");
- codegen::gen_set_reg32(ctx, r2);
- }
- pub fn instr_F30F2C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- ctx.builder.reinterpret_i32_as_f32();
- ctx.builder
- .call_fn1_f32_ret("sse_convert_with_truncation_f32_to_i32");
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr_F30F2C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
- ctx.builder.load_aligned_f32(0);
- ctx.builder
- .call_fn1_f32_ret("sse_convert_with_truncation_f32_to_i32");
- codegen::gen_set_reg32(ctx, r2);
- }
- pub fn instr_F20F2D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
- ctx.builder.reinterpret_i64_as_f64();
- ctx.builder.call_fn1_f64_ret("sse_convert_f64_to_i32");
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr_F20F2D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
- ctx.builder.load_aligned_f64(0);
- ctx.builder.call_fn1_f64_ret("sse_convert_f64_to_i32");
- codegen::gen_set_reg32(ctx, r2);
- }
- pub fn instr_F30F2D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- ctx.builder.reinterpret_i32_as_f32();
- ctx.builder.call_fn1_f32_ret("sse_convert_f32_to_i32");
- codegen::gen_set_reg32(ctx, r);
- }
- pub fn instr_F30F2D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
- ctx.builder.load_aligned_f32(0);
- ctx.builder.call_fn1_f32_ret("sse_convert_f32_to_i32");
- codegen::gen_set_reg32(ctx, r2);
- }
- pub fn instr_0F60_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem32(ctx, "instr_0F60", modrm_byte, r);
- }
- pub fn instr_0F60_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm32(ctx, "instr_0F60", r1, r2);
- }
- pub fn instr_0F61_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem32(ctx, "instr_0F61", modrm_byte, r);
- }
- pub fn instr_0F61_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm32(ctx, "instr_0F61", r1, r2);
- }
- pub fn instr_0F62_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem32(ctx, "instr_0F62", modrm_byte, r);
- }
- pub fn instr_0F62_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm32(ctx, "instr_0F62", r1, r2);
- }
- pub fn instr_0F63_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0F63", modrm_byte, r);
- }
- pub fn instr_0F63_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0F63", r1, r2);
- }
- pub fn instr_0F64_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0F64", modrm_byte, r);
- }
- pub fn instr_0F64_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0F64", r1, r2);
- }
- pub fn instr_0F65_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0F65", modrm_byte, r);
- }
- pub fn instr_0F65_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0F65", r1, r2);
- }
- pub fn instr_0F66_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0F66", modrm_byte, r);
- }
- pub fn instr_0F66_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0F66", r1, r2);
- }
- pub fn instr_0F67_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0F67", modrm_byte, r);
- }
- pub fn instr_0F67_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0F67", r1, r2);
- }
- pub fn instr_0F68_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0F68", modrm_byte, r);
- }
- pub fn instr_0F68_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0F68", r1, r2);
- }
- pub fn instr_0F69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0F69", modrm_byte, r);
- }
- pub fn instr_0F69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0F69", r1, r2);
- }
- pub fn instr_0F6A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0F6A", modrm_byte, r);
- }
- pub fn instr_0F6A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0F6A", r1, r2);
- }
- pub fn instr_0F6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0F6B", modrm_byte, r);
- }
- pub fn instr_0F6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0F6B", r1, r2);
- }
- pub fn instr_660F60_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- // Note: Only requires 64-bit read, but is allowed to do 128-bit read
- sse_read128_xmm_mem(ctx, "instr_660F60", modrm_byte, r);
- }
- pub fn instr_660F60_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F60", r1, r2);
- }
- pub fn instr_660F61_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- // Note: Only requires 64-bit read, but is allowed to do 128-bit read
- sse_read128_xmm_mem(ctx, "instr_660F61", modrm_byte, r);
- }
- pub fn instr_660F61_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F61", r1, r2);
- }
- pub fn instr_660F62_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F62", modrm_byte, r);
- }
- pub fn instr_660F62_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F62", r1, r2);
- }
- pub fn instr_660F63_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F63", modrm_byte, r);
- }
- pub fn instr_660F63_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F63", r1, r2);
- }
- pub fn instr_660F64_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F64", modrm_byte, r);
- }
- pub fn instr_660F64_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F64", r1, r2);
- }
- pub fn instr_660F65_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F65", modrm_byte, r);
- }
- pub fn instr_660F65_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F65", r1, r2);
- }
- pub fn instr_660F66_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F66", modrm_byte, r);
- }
- pub fn instr_660F66_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F66", r1, r2);
- }
- pub fn instr_660F67_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F67", modrm_byte, r);
- }
- pub fn instr_660F67_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F67", r1, r2);
- }
- pub fn instr_660F68_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F68", modrm_byte, r);
- }
- pub fn instr_660F68_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F68", r1, r2);
- }
- pub fn instr_660F69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F69", modrm_byte, r);
- }
- pub fn instr_660F69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F69", r1, r2);
- }
- pub fn instr_660F6A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F6A", modrm_byte, r);
- }
- pub fn instr_660F6A_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F6A", r1, r2);
- }
- pub fn instr_660F6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F6B", modrm_byte, r);
- }
- pub fn instr_660F6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F6B", r1, r2);
- }
- pub fn instr_660F6C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F6C", modrm_byte, r);
- }
- pub fn instr_660F6C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F6C", r1, r2);
- }
- pub fn instr_660F6D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F6D", modrm_byte, r);
- }
- pub fn instr_660F6D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F6D", r1, r2);
- }
- pub fn instr_0F6E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn2("instr_0F6E")
- }
- pub fn instr_0F6E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg32(ctx, r1);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2("instr_0F6E")
- }
- pub fn instr_660F6E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn2("instr_660F6E")
- }
- pub fn instr_660F6E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_get_reg32(ctx, r1);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2("instr_660F6E")
- }
- pub fn instr_0F6F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- // XXX: Aligned read or #gp
- codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn2_i64_i32("instr_0F6F")
- }
- pub fn instr_0F6F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder.const_i32(r1 as i32);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2("instr_0F6F_reg")
- }
- pub fn instr_660F6F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- // XXX: Aligned read or #gp
- let dest = global_pointers::get_reg_xmm_offset(r);
- codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
- }
- pub fn instr_660F6F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
- pub fn instr_F30F6F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- let dest = global_pointers::get_reg_xmm_offset(r);
- codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
- }
- pub fn instr_F30F6F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r1, r2) }
- pub fn instr_0F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
- codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn3_i64_i32_i32("instr_0F70");
- }
- pub fn instr_0F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
- ctx.builder
- .const_i32(global_pointers::get_reg_mmx_offset(r1) as i32);
- ctx.builder.load_aligned_i64(0);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn3_i64_i32_i32("instr_0F70");
- }
- pub fn instr_660F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
- let dest = global_pointers::sse_scratch_register as u32;
- codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
- ctx.builder.const_i32(dest as i32);
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn3("instr_660F70");
- }
- pub fn instr_660F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
- codegen::gen_read_reg_xmm128_into_scratch(ctx, r1);
- let dest = global_pointers::sse_scratch_register;
- ctx.builder.const_i32(dest as i32);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn3("instr_660F70");
- }
- pub fn instr_F20F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
- let dest = global_pointers::sse_scratch_register as u32;
- codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
- ctx.builder.const_i32(dest as i32);
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn3("instr_F20F70");
- }
- pub fn instr_F20F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
- codegen::gen_read_reg_xmm128_into_scratch(ctx, r1);
- let dest = global_pointers::sse_scratch_register;
- ctx.builder.const_i32(dest as i32);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn3("instr_F20F70");
- }
- pub fn instr_F30F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
- let dest = global_pointers::sse_scratch_register as u32;
- codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
- ctx.builder.const_i32(dest as i32);
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn3("instr_F30F70");
- }
- pub fn instr_F30F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
- codegen::gen_read_reg_xmm128_into_scratch(ctx, r1);
- let dest = global_pointers::sse_scratch_register;
- ctx.builder.const_i32(dest as i32);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn3("instr_F30F70");
- }
- pub fn instr_0F71_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_0F71_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_0F71_2_reg");
- }
- pub fn instr_0F71_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_0F71_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_0F71_4_reg");
- }
- pub fn instr_0F71_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_0F71_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_0F71_6_reg");
- }
- pub fn instr_0F72_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_0F72_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_0F72_2_reg");
- }
- pub fn instr_0F72_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_0F72_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_0F72_4_reg");
- }
- pub fn instr_0F72_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_0F72_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_0F72_6_reg");
- }
- pub fn instr_0F73_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_0F73_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_0F73_2_reg");
- }
- pub fn instr_0F73_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_0F73_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_0F73_6_reg");
- }
- pub fn instr_660F71_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660F71_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_660F71_2_reg");
- }
- pub fn instr_660F71_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660F71_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_660F71_4_reg");
- }
- pub fn instr_660F71_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660F71_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_660F71_6_reg");
- }
- pub fn instr_660F72_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660F72_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_660F72_2_reg");
- }
- pub fn instr_660F72_4_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660F72_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_660F72_4_reg");
- }
- pub fn instr_660F72_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660F72_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_660F72_6_reg");
- }
- pub fn instr_660F73_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660F73_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_660F73_2_reg");
- }
- pub fn instr_660F73_3_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660F73_3_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_660F73_3_reg");
- }
- pub fn instr_660F73_6_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660F73_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_660F73_6_reg");
- }
- pub fn instr_660F73_7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660F73_7_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- ctx.builder.const_i32(r as i32);
- ctx.builder.const_i32(imm8 as i32);
- ctx.builder.call_fn2("instr_660F73_7_reg");
- }
- pub fn instr_660F74_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660F74", modrm_byte, r);
- }
- pub fn instr_660F74_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660F74", r1, r2);
- }
- pub fn instr_0F7E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn1_ret("instr_0F7E");
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write32(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- }
- pub fn instr_0F7E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn1_ret("instr_0F7E");
- codegen::gen_set_reg32(ctx, r1);
- }
- pub fn instr_660F7E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- ctx.builder
- .load_fixed_i32(global_pointers::get_reg_xmm_offset(r));
- let value_local = ctx.builder.set_new_local();
- codegen::gen_safe_write32(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local(value_local);
- }
- pub fn instr_660F7E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder
- .load_fixed_i32(global_pointers::get_reg_xmm_offset(r2));
- codegen::gen_set_reg32(ctx, r1);
- }
- pub fn instr_0F7F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn1_ret_i64("instr_0F7F");
- let value_local = ctx.builder.set_new_local_i64();
- codegen::gen_safe_write64(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local_i64(value_local);
- }
- pub fn instr_0F7F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder.const_i32(r1 as i32);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2("instr_0F7F_reg")
- }
- pub fn instr_F30F7E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
- codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
- ctx.builder.store_aligned_i64(0);
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r) as i32 + 8);
- ctx.builder.const_i64(0);
- ctx.builder.store_aligned_i64(0);
- }
- pub fn instr_F30F7E_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder.const_i32(r1 as i32);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2("instr_F30F7E_reg");
- }
- pub fn instr_660F7F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- instr_0F29_mem_jit(ctx, modrm_byte, r);
- }
- pub fn instr_660F7F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
- pub fn instr_F30F7F_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- instr_0F29_mem_jit(ctx, modrm_byte, r);
- }
- pub fn instr_F30F7F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_mov_xmm_xmm(ctx, r2, r1) }
- pub fn instr16_0FA0_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::FS);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr32_0FA0_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::FS);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr16_0FA8_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::GS);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push16(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr32_0FA8_jit(ctx: &mut JitContext) {
- codegen::gen_get_sreg(ctx, regs::GS);
- let sreg = ctx.builder.set_new_local();
- codegen::gen_push32(ctx, &sreg);
- ctx.builder.free_local(sreg);
- }
- pub fn instr16_0FA3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- gen_bt(
- &mut ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
- 15,
- )
- }
- pub fn instr16_0FA3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- codegen::gen_get_reg16(ctx, r);
- codegen::sign_extend_i16(ctx.builder);
- ctx.builder.const_i32(3);
- ctx.builder.shr_s_i32();
- ctx.builder.add_i32();
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read8(ctx, &address_local);
- ctx.builder.free_local(address_local);
- let value = ctx.builder.set_new_local();
- gen_bt(
- &mut ctx.builder,
- &value,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize]),
- 7,
- );
- ctx.builder.free_local(value);
- }
- pub fn instr32_0FA3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- gen_bt(
- &mut ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
- 31,
- )
- }
- pub fn instr32_0FA3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- codegen::gen_get_reg32(ctx, r);
- ctx.builder.const_i32(3);
- ctx.builder.shr_s_i32();
- ctx.builder.add_i32();
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read8(ctx, &address_local);
- ctx.builder.free_local(address_local);
- let value = ctx.builder.set_new_local();
- gen_bt(
- &mut ctx.builder,
- &value,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize]),
- 7,
- );
- ctx.builder.free_local(value);
- }
- pub fn instr16_0FAB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- gen_bts(
- &mut ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
- 15,
- )
- }
- pub fn instr16_0FAB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_bts,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize].unsafe_clone()),
- 16,
- );
- }
- pub fn instr32_0FAB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- gen_bts(
- &mut ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
- 31,
- )
- }
- pub fn instr32_0FAB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_bts,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize].unsafe_clone()),
- 32,
- );
- }
- pub fn instr16_0FB3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- gen_btr(
- &mut ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
- 15,
- )
- }
- pub fn instr16_0FB3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_btr,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize].unsafe_clone()),
- 16,
- );
- }
- pub fn instr32_0FB3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- gen_btr(
- &mut ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
- 31,
- )
- }
- pub fn instr32_0FB3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_btr,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize].unsafe_clone()),
- 32,
- );
- }
- pub fn instr16_0FBB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- gen_btc(
- &mut ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
- 15,
- )
- }
- pub fn instr16_0FBB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_btc,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize].unsafe_clone()),
- 16,
- );
- }
- pub fn instr32_0FBB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- gen_btc(
- &mut ctx.builder,
- &ctx.register_locals[r1 as usize],
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r2 as usize]),
- 31,
- )
- }
- pub fn instr32_0FBB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_btc,
- &LocalOrImmediate::WasmLocal(&ctx.register_locals[r as usize].unsafe_clone()),
- 32,
- );
- }
- pub fn instr16_0FBA_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- gen_bt(
- &mut ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::Immediate(imm8 as i32),
- 15,
- )
- }
- pub fn instr16_0FBA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- ctx.builder.const_i32((imm8 as i32 & 15) >> 3);
- ctx.builder.add_i32();
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read8(ctx, &address_local);
- ctx.builder.free_local(address_local);
- let value = ctx.builder.set_new_local();
- gen_bt(
- &mut ctx.builder,
- &value,
- &LocalOrImmediate::Immediate(imm8 as i32),
- 7,
- );
- ctx.builder.free_local(value);
- }
- pub fn instr32_0FBA_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- gen_bt(
- &mut ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::Immediate(imm8 as i32),
- 31,
- )
- }
- pub fn instr32_0FBA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- ctx.builder.const_i32((imm8 as i32 & 31) >> 3);
- ctx.builder.add_i32();
- let address_local = ctx.builder.set_new_local();
- codegen::gen_safe_read8(ctx, &address_local);
- ctx.builder.free_local(address_local);
- let value = ctx.builder.set_new_local();
- gen_bt(
- &mut ctx.builder,
- &value,
- &LocalOrImmediate::Immediate(imm8 as i32),
- 7,
- );
- ctx.builder.free_local(value);
- }
- pub fn instr16_0FBA_5_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- gen_bts(
- &mut ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::Immediate(imm8 as i32),
- 15,
- )
- }
- pub fn instr16_0FBA_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_bts,
- &LocalOrImmediate::Immediate(imm8 as i32),
- 16,
- );
- }
- pub fn instr32_0FBA_5_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- gen_bts(
- &mut ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::Immediate(imm8 as i32),
- 31,
- )
- }
- pub fn instr32_0FBA_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_bts,
- &LocalOrImmediate::Immediate(imm8 as i32),
- 32,
- );
- }
- pub fn instr16_0FBA_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- gen_btr(
- &mut ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::Immediate(imm8 as i32),
- 15,
- )
- }
- pub fn instr16_0FBA_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_btr,
- &LocalOrImmediate::Immediate(imm8 as i32),
- 16,
- );
- }
- pub fn instr32_0FBA_6_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- gen_btr(
- &mut ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::Immediate(imm8 as i32),
- 31,
- )
- }
- pub fn instr32_0FBA_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_btr,
- &LocalOrImmediate::Immediate(imm8 as i32),
- 32,
- );
- }
- pub fn instr16_0FBA_7_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- gen_btc(
- &mut ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::Immediate(imm8 as i32),
- 15,
- )
- }
- pub fn instr16_0FBA_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_btc,
- &LocalOrImmediate::Immediate(imm8 as i32),
- 16,
- );
- }
- pub fn instr32_0FBA_7_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
- gen_btc(
- &mut ctx.builder,
- &ctx.register_locals[r as usize],
- &LocalOrImmediate::Immediate(imm8 as i32),
- 31,
- )
- }
- pub fn instr32_0FBA_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
- gen_bit_rmw(
- ctx,
- modrm_byte,
- &gen_btc,
- &LocalOrImmediate::Immediate(imm8 as i32),
- 32,
- );
- }
- pub fn instr_0FAE_5_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte) {
- dbg_log!("Generating #ud for unimplemented instruction: instr_0FAE_5_mem_jit");
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_0FAE_5_reg_jit(_ctx: &mut JitContext, _r: u32) {
- // For this instruction, the processor ignores the r/m field of the ModR/M byte.
- }
- pub fn instr_0FD1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FD1", modrm_byte, r);
- }
- pub fn instr_0FD1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FD1", r1, r2);
- }
- pub fn instr_0FD2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FD2", modrm_byte, r);
- }
- pub fn instr_0FD2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FD2", r1, r2);
- }
- pub fn instr_0FD3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FD3", modrm_byte, r);
- }
- pub fn instr_0FD3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FD3", r1, r2);
- }
- pub fn instr_0FD4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FD4", modrm_byte, r);
- }
- pub fn instr_0FD4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FD4", r1, r2);
- }
- pub fn instr_0FD5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FD5", modrm_byte, r);
- }
- pub fn instr_0FD5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FD5", r1, r2);
- }
- pub fn instr_0FD7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
- codegen::gen_trigger_ud(ctx)
- }
- pub fn instr_0FD7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder.const_i32(r1 as i32);
- ctx.builder.call_fn1_ret("instr_0FD7");
- codegen::gen_set_reg32(ctx, r2);
- }
- pub fn instr_0FD8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FD8", modrm_byte, r);
- }
- pub fn instr_0FD8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FD8", r1, r2);
- }
- pub fn instr_0FD9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FD9", modrm_byte, r);
- }
- pub fn instr_0FD9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FD9", r1, r2);
- }
- pub fn instr_0FDA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FDA", modrm_byte, r);
- }
- pub fn instr_0FDA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FDA", r1, r2);
- }
- pub fn instr_0FDB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FDB", modrm_byte, r);
- }
- pub fn instr_0FDB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FDB", r1, r2);
- }
- pub fn instr_0FDC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FDC", modrm_byte, r);
- }
- pub fn instr_0FDC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FDC", r1, r2);
- }
- pub fn instr_0FDD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FDD", modrm_byte, r);
- }
- pub fn instr_0FDD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FDD", r1, r2);
- }
- pub fn instr_0FDE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FDE", modrm_byte, r);
- }
- pub fn instr_0FDE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FDE", r1, r2);
- }
- pub fn instr_0FDF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FDF", modrm_byte, r);
- }
- pub fn instr_0FDF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FDF", r1, r2);
- }
- pub fn instr_660FD1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FD1", modrm_byte, r);
- }
- pub fn instr_660FD1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FD1", r1, r2);
- }
- pub fn instr_660FD2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FD2", modrm_byte, r);
- }
- pub fn instr_660FD2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FD2", r1, r2);
- }
- pub fn instr_660FD3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FD3", modrm_byte, r);
- }
- pub fn instr_660FD3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FD3", r1, r2);
- }
- pub fn instr_660FD4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FD4", modrm_byte, r);
- }
- pub fn instr_660FD4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FD4", r1, r2);
- }
- pub fn instr_660FD5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FD5", modrm_byte, r);
- }
- pub fn instr_660FD5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FD5", r1, r2);
- }
- pub fn instr_660FD6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve(ctx, modrm_byte);
- let address_local = ctx.builder.set_new_local();
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r) as i32);
- ctx.builder.load_aligned_i64(0);
- let value_local = ctx.builder.set_new_local_i64();
- codegen::gen_safe_write64(ctx, &address_local, &value_local);
- ctx.builder.free_local(address_local);
- ctx.builder.free_local_i64(value_local);
- }
- pub fn instr_660FD6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder.const_i32(r1 as i32);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2("instr_660FD6_reg");
- }
- pub fn instr_660FD7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
- codegen::gen_trigger_ud(ctx)
- }
- pub fn instr_660FD7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder.const_i32(r1 as i32);
- ctx.builder.call_fn1_ret("instr_660FD7");
- codegen::gen_set_reg32(ctx, r2);
- }
- pub fn instr_660FD8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FD8", modrm_byte, r);
- }
- pub fn instr_660FD8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FD8", r1, r2);
- }
- pub fn instr_660FD9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FD9", modrm_byte, r);
- }
- pub fn instr_660FD9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FD9", r1, r2);
- }
- pub fn instr_660FDA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FDA", modrm_byte, r);
- }
- pub fn instr_660FDA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FDA", r1, r2);
- }
- pub fn instr_660FDB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FDB", modrm_byte, r);
- }
- pub fn instr_660FDB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FDB", r1, r2);
- }
- pub fn instr_660FDC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FDC", modrm_byte, r);
- }
- pub fn instr_660FDC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FDC", r1, r2);
- }
- pub fn instr_660FDD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FDD", modrm_byte, r);
- }
- pub fn instr_660FDD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FDD", r1, r2);
- }
- pub fn instr_660FDE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FDE", modrm_byte, r);
- }
- pub fn instr_660FDE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FDE", r1, r2);
- }
- pub fn instr_660FDF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FDF", modrm_byte, r);
- }
- pub fn instr_660FDF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FDF", r1, r2);
- }
- pub fn instr_0FE0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FE0", modrm_byte, r);
- }
- pub fn instr_0FE0_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FE0", r1, r2);
- }
- pub fn instr_0FE1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FE1", modrm_byte, r);
- }
- pub fn instr_0FE1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FE1", r1, r2);
- }
- pub fn instr_0FE2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FE2", modrm_byte, r);
- }
- pub fn instr_0FE2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FE2", r1, r2);
- }
- pub fn instr_0FE3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FE3", modrm_byte, r);
- }
- pub fn instr_0FE3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FE3", r1, r2);
- }
- pub fn instr_0FE4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FE4", modrm_byte, r);
- }
- pub fn instr_0FE4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FE4", r1, r2);
- }
- pub fn instr_0FE5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FE5", modrm_byte, r);
- }
- pub fn instr_0FE5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FE5", r1, r2);
- }
- pub fn instr_0FE8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FE8", modrm_byte, r);
- }
- pub fn instr_0FE8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FE8", r1, r2);
- }
- pub fn instr_0FE9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FE9", modrm_byte, r);
- }
- pub fn instr_0FE9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FE9", r1, r2);
- }
- pub fn instr_0FEA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FEA", modrm_byte, r);
- }
- pub fn instr_0FEA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FEA", r1, r2);
- }
- pub fn instr_0FEB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FEB", modrm_byte, r);
- }
- pub fn instr_0FEB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FEB", r1, r2);
- }
- pub fn instr_0FEC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FEC", modrm_byte, r);
- }
- pub fn instr_0FEC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FEC", r1, r2);
- }
- pub fn instr_0FED_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FED", modrm_byte, r);
- }
- pub fn instr_0FED_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FED", r1, r2);
- }
- pub fn instr_0FEE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FEE", modrm_byte, r);
- }
- pub fn instr_0FEE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FEE", r1, r2);
- }
- pub fn instr_0FEF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FEF", modrm_byte, r);
- }
- pub fn instr_0FEF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FEF", r1, r2);
- }
- pub fn instr_660FE0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FE0", modrm_byte, r);
- }
- pub fn instr_660FE0_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FE0", r1, r2);
- }
- pub fn instr_660FE1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FE1", modrm_byte, r);
- }
- pub fn instr_660FE1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FE1", r1, r2);
- }
- pub fn instr_660FE2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FE2", modrm_byte, r);
- }
- pub fn instr_660FE2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FE2", r1, r2);
- }
- pub fn instr_660FE3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FE3", modrm_byte, r);
- }
- pub fn instr_660FE3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FE3", r1, r2);
- }
- pub fn instr_660FE4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FE4", modrm_byte, r);
- }
- pub fn instr_660FE4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FE4", r1, r2);
- }
- pub fn instr_660FE5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FE5", modrm_byte, r);
- }
- pub fn instr_660FE5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FE5", r1, r2);
- }
- pub fn instr_660FE6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FE6", modrm_byte, r);
- }
- pub fn instr_660FE6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FE6", r1, r2);
- }
- pub fn instr_F20FE6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_F20FE6", modrm_byte, r);
- }
- pub fn instr_F20FE6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_F20FE6", r1, r2);
- }
- pub fn instr_F30FE6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
- ctx.builder.const_i32(r as i32);
- ctx.builder.call_fn2_i64_i32("instr_F30FE6")
- }
- pub fn instr_F30FE6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- ctx.builder
- .const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
- ctx.builder.load_aligned_i64(0);
- ctx.builder.const_i32(r2 as i32);
- ctx.builder.call_fn2_i64_i32("instr_F30FE6")
- }
- pub fn instr_660FE7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- instr_0F29_mem_jit(ctx, modrm_byte, r);
- }
- pub fn instr_660FE7_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
- codegen::gen_trigger_ud(ctx);
- }
- pub fn instr_660FE8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FE8", modrm_byte, r);
- }
- pub fn instr_660FE8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FE8", r1, r2);
- }
- pub fn instr_660FE9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FE9", modrm_byte, r);
- }
- pub fn instr_660FE9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FE9", r1, r2);
- }
- pub fn instr_660FEA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FEA", modrm_byte, r);
- }
- pub fn instr_660FEA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FEA", r1, r2);
- }
- pub fn instr_660FEB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FEB", modrm_byte, r);
- }
- pub fn instr_660FEB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FEB", r1, r2);
- }
- pub fn instr_660FEC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FEC", modrm_byte, r);
- }
- pub fn instr_660FEC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FEC", r1, r2);
- }
- pub fn instr_660FED_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FED", modrm_byte, r);
- }
- pub fn instr_660FED_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FED", r1, r2);
- }
- pub fn instr_660FEE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FEE", modrm_byte, r);
- }
- pub fn instr_660FEE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FEE", r1, r2);
- }
- pub fn instr_660FEF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FEF", modrm_byte, r);
- }
- pub fn instr_660FEF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FEF", r1, r2);
- }
- pub fn instr_0FF1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FF1", modrm_byte, r);
- }
- pub fn instr_0FF1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FF1", r1, r2);
- }
- pub fn instr_0FF2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FF2", modrm_byte, r);
- }
- pub fn instr_0FF2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FF2", r1, r2);
- }
- pub fn instr_0FF3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FF3", modrm_byte, r);
- }
- pub fn instr_0FF3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FF3", r1, r2);
- }
- pub fn instr_0FF4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FF4", modrm_byte, r);
- }
- pub fn instr_0FF4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FF4", r1, r2);
- }
- pub fn instr_0FF5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FF5", modrm_byte, r);
- }
- pub fn instr_0FF5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FF5", r1, r2);
- }
- pub fn instr_0FF6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FF6", modrm_byte, r);
- }
- pub fn instr_0FF6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FF6", r1, r2);
- }
- pub fn instr_0FF7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
- codegen::gen_trigger_ud(ctx)
- }
- pub fn instr_0FF7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
- ctx.builder,
- ctx.start_of_current_instruction as i32 & 0xFFF,
- );
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.const_i32(r1 as i32);
- ctx.builder.const_i32(r2 as i32);
- if ctx.cpu.asize_32() {
- codegen::gen_get_reg32(ctx, regs::EDI);
- }
- else {
- codegen::gen_get_reg16(ctx, regs::DI);
- }
- jit_add_seg_offset(ctx, regs::DS);
- ctx.builder.call_fn3("maskmovq");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- codegen::gen_get_page_fault(ctx.builder);
- ctx.builder.if_void();
- codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.return_();
- ctx.builder.block_end();
- }
- pub fn instr_0FF8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FF8", modrm_byte, r);
- }
- pub fn instr_0FF8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FF8", r1, r2);
- }
- pub fn instr_0FF9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FF9", modrm_byte, r);
- }
- pub fn instr_0FF9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FF9", r1, r2);
- }
- pub fn instr_0FFA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FFA", modrm_byte, r);
- }
- pub fn instr_0FFA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FFA", r1, r2);
- }
- pub fn instr_0FFB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FFB", modrm_byte, r);
- }
- pub fn instr_0FFB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FFB", r1, r2);
- }
- pub fn instr_0FFC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FFC", modrm_byte, r);
- }
- pub fn instr_0FFC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FFC", r1, r2);
- }
- pub fn instr_0FFD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FFD", modrm_byte, r);
- }
- pub fn instr_0FFD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FFD", r1, r2);
- }
- pub fn instr_0FFE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- mmx_read64_mm_mem(ctx, "instr_0FFE", modrm_byte, r);
- }
- pub fn instr_0FFE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- mmx_read64_mm_mm(ctx, "instr_0FFE", r1, r2);
- }
- pub fn instr_660FF1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FF1", modrm_byte, r);
- }
- pub fn instr_660FF1_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FF1", r1, r2);
- }
- pub fn instr_660FF2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FF2", modrm_byte, r);
- }
- pub fn instr_660FF2_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FF2", r1, r2);
- }
- pub fn instr_660FF3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FF3", modrm_byte, r);
- }
- pub fn instr_660FF3_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FF3", r1, r2);
- }
- pub fn instr_660FF4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FF4", modrm_byte, r);
- }
- pub fn instr_660FF4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FF4", r1, r2);
- }
- pub fn instr_660FF5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FF5", modrm_byte, r);
- }
- pub fn instr_660FF5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FF5", r1, r2);
- }
- pub fn instr_660FF6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FF6", modrm_byte, r);
- }
- pub fn instr_660FF6_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FF6", r1, r2);
- }
- pub fn instr_660FF7_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32) {
- codegen::gen_trigger_ud(ctx)
- }
- pub fn instr_660FF7_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
- ctx.builder,
- ctx.start_of_current_instruction as i32 & 0xFFF,
- );
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.const_i32(r1 as i32);
- ctx.builder.const_i32(r2 as i32);
- if ctx.cpu.asize_32() {
- codegen::gen_get_reg32(ctx, regs::EDI);
- }
- else {
- codegen::gen_get_reg16(ctx, regs::DI);
- }
- jit_add_seg_offset(ctx, regs::DS);
- ctx.builder.call_fn3("maskmovdqu");
- codegen::gen_move_registers_from_memory_to_locals(ctx);
- codegen::gen_get_page_fault(ctx.builder);
- ctx.builder.if_void();
- codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
- codegen::gen_move_registers_from_locals_to_memory(ctx);
- ctx.builder.return_();
- ctx.builder.block_end();
- }
- pub fn instr_660FF8_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FF8", modrm_byte, r);
- }
- pub fn instr_660FF8_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FF8", r1, r2);
- }
- pub fn instr_660FF9_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FF9", modrm_byte, r);
- }
- pub fn instr_660FF9_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FF9", r1, r2);
- }
- pub fn instr_660FFA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FFA", modrm_byte, r);
- }
- pub fn instr_660FFA_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FFA", r1, r2);
- }
- pub fn instr_660FFB_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FFB", modrm_byte, r);
- }
- pub fn instr_660FFB_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FFB", r1, r2);
- }
- pub fn instr_660FFC_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FFC", modrm_byte, r);
- }
- pub fn instr_660FFC_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FFC", r1, r2);
- }
- pub fn instr_660FFD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FFD", modrm_byte, r);
- }
- pub fn instr_660FFD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FFD", r1, r2);
- }
- pub fn instr_660FFE_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
- sse_read128_xmm_mem(ctx, "instr_660FFE", modrm_byte, r);
- }
- pub fn instr_660FFE_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
- sse_read128_xmm_xmm(ctx, "instr_660FFE", r1, r2);
- }
|