Assembly.cpp 299 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448
  1. #include "Assembly.h"
  2. #include "Critical.h"
  3. #include "InMemoryBuffer.h"
  4. #ifndef WIN32
  5. # include <sys/mman.h>
  6. #endif
  7. enum OperandSizeOverwrite
  8. {
  9. NO_PREFIX = 0,
  10. X66 = 0x66,
  11. XF2 = 0xF2,
  12. XF3 = 0xF3
  13. };
  14. bool isVolatile(Framework::Assembly::GPRegister reg)
  15. {
  16. return reg == Framework::Assembly::RAX || reg == Framework::Assembly::RCX
  17. || reg == Framework::Assembly::RDX || reg == Framework::Assembly::R8
  18. || reg == Framework::Assembly::R9 || reg == Framework::Assembly::R10
  19. || reg == Framework::Assembly::R11;
  20. }
  21. bool isVolatile(Framework::Assembly::FPRegister reg)
  22. {
  23. return reg == Framework::Assembly::MM0 || reg == Framework::Assembly::MM1
  24. || reg == Framework::Assembly::MM2 || reg == Framework::Assembly::MM3
  25. || reg == Framework::Assembly::MM4 || reg == Framework::Assembly::MM5;
  26. }
  27. struct MachineCodeInstruction
  28. {
  29. bool needsRex;
  30. char opcode[3];
  31. char opcodeLength;
  32. bool needsModRM;
  33. char modRM;
  34. bool sibNeeded;
  35. char sib;
  36. char disp[4];
  37. char dispLength;
  38. char imm[8];
  39. char immLength;
  40. OperandSizeOverwrite operandSizeOverride;
  41. bool errIfRex;
  42. bool errIfNoRex;
  43. bool exR;
  44. bool exX;
  45. bool exB;
  46. bool vexL;
  47. bool exWE;
  48. int vexVVVV;
  49. char vexPP;
  50. bool needsVex;
  51. void write(Framework::StreamWriter& writer) const
  52. {
  53. if (operandSizeOverride)
  54. {
  55. char prefix = *(char*)&operandSizeOverride;
  56. writer.write(&prefix, 1);
  57. }
  58. if (needsRex && !needsVex)
  59. {
  60. char rex = 0b01000000 | ((exWE & 0b1) << 3) | ((exR & 0b1) << 2)
  61. | ((exX & 0b1) << 1) | (exB & 0b1);
  62. writer.write(&rex, 1);
  63. }
  64. int opCodeOffset = 0;
  65. if (needsVex)
  66. {
  67. char vexMapSelect = 0;
  68. if (opcode[0] == 0x0F)
  69. {
  70. opCodeOffset = 1;
  71. vexMapSelect = 1;
  72. if (opcode[1] == 0x38)
  73. {
  74. vexMapSelect = 2;
  75. opCodeOffset = 2;
  76. }
  77. else if (opcode[1] == 0x3A)
  78. {
  79. vexMapSelect = 3;
  80. opCodeOffset = 2;
  81. }
  82. }
  83. if (exX || exB || exWE || vexMapSelect != 1)
  84. {
  85. // 3-byte VEX
  86. char vex2[3];
  87. vex2[0] = (char)0xC4;
  88. vex2[1]
  89. = (((~(char)exR) & 0b1) << 7) | (((~(char)exX) & 0b1) << 6)
  90. | (((~(char)exB) & 0b1) << 5) | (vexMapSelect & 0b11111);
  91. vex2[2] = ((exWE & 0b1) << 7)
  92. | (((~(char)vexVVVV) & 0b1111) << 3)
  93. | ((vexL & 0b1) << 2) | (vexPP & 0b11);
  94. writer.write(vex2, 3);
  95. }
  96. else
  97. {
  98. // 2-byte VEX
  99. char vex2[2];
  100. vex2[0] = (char)0xC5;
  101. vex2[1] = (((~(char)exR) & 0b1) << 7)
  102. | (((~(char)vexVVVV) & 0b1111) << 3)
  103. | ((vexL & 0b1) << 2) | (vexPP & 0b11);
  104. writer.write(vex2, 2);
  105. }
  106. }
  107. writer.write(opcode + opCodeOffset, opcodeLength - opCodeOffset);
  108. if (needsModRM)
  109. {
  110. writer.write(&modRM, 1);
  111. }
  112. if (sibNeeded)
  113. {
  114. writer.write(&sib, 1);
  115. }
  116. if (dispLength > 0)
  117. {
  118. writer.write(disp, dispLength);
  119. }
  120. if (immLength > 0)
  121. {
  122. writer.write(imm, immLength);
  123. }
  124. }
  125. int calculateSize() const
  126. {
  127. int size = 0;
  128. if (operandSizeOverride)
  129. {
  130. size += 1;
  131. }
  132. if (needsRex && !needsVex)
  133. {
  134. size += 1;
  135. }
  136. int opCodeOffset = 0;
  137. if (needsVex)
  138. {
  139. char vexMapSelect = 0;
  140. if (opcode[0] == 0x0F)
  141. {
  142. opCodeOffset = 1;
  143. vexMapSelect = 1;
  144. if (opcode[1] == 0x38)
  145. {
  146. vexMapSelect = 2;
  147. opCodeOffset = 2;
  148. }
  149. else if (opcode[1] == 0x3A)
  150. {
  151. vexMapSelect = 3;
  152. opCodeOffset = 2;
  153. }
  154. }
  155. if (exX || exB || exWE || vexMapSelect != 1)
  156. {
  157. size += 3;
  158. }
  159. else
  160. {
  161. size += 2;
  162. }
  163. }
  164. size += opcodeLength - opCodeOffset;
  165. if (needsModRM)
  166. {
  167. size += 1;
  168. }
  169. if (sibNeeded)
  170. {
  171. size += 1;
  172. }
  173. size += dispLength;
  174. size += immLength;
  175. return size;
  176. }
  177. };
  178. enum OperandEncoding
  179. {
  180. UNDEFINED,
  181. MODRM_REG,
  182. MODRM_RM,
  183. VEX_VVVV,
  184. OPCODE_RD,
  185. // EVEX_VVVV,
  186. IMM8,
  187. IMM16,
  188. IMM32,
  189. IMM64,
  190. };
  191. enum OperandRW
  192. {
  193. NONE = 0,
  194. READ = 1,
  195. WRITE = 2,
  196. READWRITE = 3,
  197. };
  198. class MachineCodeTableEntry
  199. {
  200. private:
  201. int numArgs;
  202. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  203. op1Validator;
  204. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  205. op2Validator;
  206. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  207. op3Validator;
  208. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  209. op4Validator;
  210. bool vex;
  211. bool vexL;
  212. char vexPP;
  213. bool rexW;
  214. char rmReg;
  215. char opcode[3];
  216. char opcodeLength;
  217. OperandEncoding op1Encoding;
  218. OperandEncoding op2Encoding;
  219. OperandEncoding op3Encoding;
  220. OperandEncoding op4Encoding;
  221. OperandRW op1RW;
  222. OperandRW op2RW;
  223. OperandRW op3RW;
  224. OperandRW op4RW;
  225. std::vector<Framework::Assembly::GPRegister> impliedReadGPRegs;
  226. std::vector<Framework::Assembly::GPRegister> impliedWriteGPRegs;
  227. std::vector<Framework::Assembly::FPRegister> impliedReadFPRegs;
  228. std::vector<Framework::Assembly::FPRegister> impliedWriteFPRegs;
  229. OperandSizeOverwrite operandSizeOverride;
  230. public:
  231. MachineCodeTableEntry(bool rexW,
  232. int opcode,
  233. char opcodeLength,
  234. OperandSizeOverwrite operandSizeOverride,
  235. bool vex,
  236. bool vexL,
  237. char vexPP,
  238. char rmReg)
  239. : numArgs(0),
  240. vex(vex),
  241. vexL(vexL),
  242. vexPP(vexPP),
  243. rexW(rexW),
  244. rmReg(rmReg),
  245. opcodeLength(opcodeLength),
  246. op1Encoding(UNDEFINED),
  247. op2Encoding(UNDEFINED),
  248. op3Encoding(UNDEFINED),
  249. op4Encoding(UNDEFINED),
  250. op1RW(NONE),
  251. op2RW(NONE),
  252. op3RW(NONE),
  253. op4RW(NONE),
  254. operandSizeOverride(operandSizeOverride)
  255. {
  256. this->opcode[0] = (char)(opcode & 0xFF);
  257. this->opcode[1] = (char)((opcode >> 8) & 0xFF);
  258. this->opcode[2] = (char)((opcode >> 16) & 0xFF);
  259. }
  260. MachineCodeTableEntry(bool rexW,
  261. int opcode,
  262. char opcodeLength,
  263. OperandSizeOverwrite operandSizeOverride,
  264. bool vex,
  265. bool vexL,
  266. char vexPP,
  267. char rmReg,
  268. std::initializer_list<Framework::Assembly::GPRegister>
  269. impliedReadGPRegs,
  270. std::initializer_list<Framework::Assembly::GPRegister>
  271. impliedWriteGPRegs,
  272. std::initializer_list<Framework::Assembly::FPRegister>
  273. impliedReadFPRegs,
  274. std::initializer_list<Framework::Assembly::FPRegister>
  275. impliedWriteFPRegs)
  276. : MachineCodeTableEntry(rexW,
  277. opcode,
  278. opcodeLength,
  279. operandSizeOverride,
  280. vex,
  281. vexL,
  282. vexPP,
  283. rmReg)
  284. {
  285. this->opcode[0] = (char)(opcode & 0xFF);
  286. this->opcode[1] = (char)((opcode >> 8) & 0xFF);
  287. this->opcode[2] = (char)((opcode >> 16) & 0xFF);
  288. this->impliedReadGPRegs = impliedReadGPRegs;
  289. this->impliedWriteGPRegs = impliedWriteGPRegs;
  290. this->impliedReadFPRegs = impliedReadFPRegs;
  291. this->impliedWriteFPRegs = impliedWriteFPRegs;
  292. }
  293. MachineCodeTableEntry(bool rexW,
  294. int opcode,
  295. char opcodeLength,
  296. OperandSizeOverwrite operandSizeOverride,
  297. bool vex,
  298. bool vexL,
  299. char vexPP,
  300. char rmReg,
  301. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  302. op1Validator,
  303. OperandEncoding op1Encoding,
  304. OperandRW op1RW)
  305. : MachineCodeTableEntry(rexW,
  306. opcode,
  307. opcodeLength,
  308. operandSizeOverride,
  309. vex,
  310. vexL,
  311. vexPP,
  312. rmReg)
  313. {
  314. numArgs = 1;
  315. this->op1Validator = op1Validator;
  316. this->op1Encoding = op1Encoding;
  317. this->op1RW = op1RW;
  318. }
  319. MachineCodeTableEntry(bool rexW,
  320. int opcode,
  321. char opcodeLength,
  322. OperandSizeOverwrite operandSizeOverride,
  323. bool vex,
  324. bool vexL,
  325. char vexPP,
  326. char rmReg,
  327. std::initializer_list<Framework::Assembly::GPRegister>
  328. impliedReadGPRegs,
  329. std::initializer_list<Framework::Assembly::GPRegister>
  330. impliedWriteGPRegs,
  331. std::initializer_list<Framework::Assembly::FPRegister>
  332. impliedReadFPRegs,
  333. std::initializer_list<Framework::Assembly::FPRegister>
  334. impliedWriteFPRegs,
  335. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  336. op1Validator,
  337. OperandEncoding op1Encoding,
  338. OperandRW op1RW)
  339. : MachineCodeTableEntry(rexW,
  340. opcode,
  341. opcodeLength,
  342. operandSizeOverride,
  343. vex,
  344. vexL,
  345. vexPP,
  346. rmReg,
  347. impliedReadGPRegs,
  348. impliedWriteGPRegs,
  349. impliedReadFPRegs,
  350. impliedWriteFPRegs)
  351. {
  352. numArgs = 1;
  353. this->op1Validator = op1Validator;
  354. this->op1Encoding = op1Encoding;
  355. this->op1RW = op1RW;
  356. }
  357. MachineCodeTableEntry(bool rexW,
  358. int opcode,
  359. char opcodeLength,
  360. OperandSizeOverwrite operandSizeOverride,
  361. bool vex,
  362. bool vexL,
  363. char vexPP,
  364. char rmReg,
  365. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  366. op1Validator,
  367. OperandEncoding op1Encoding,
  368. OperandRW op1RW,
  369. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  370. op2Validator,
  371. OperandEncoding op2Encoding,
  372. OperandRW op2RW)
  373. : MachineCodeTableEntry(rexW,
  374. opcode,
  375. opcodeLength,
  376. operandSizeOverride,
  377. vex,
  378. vexL,
  379. vexPP,
  380. rmReg,
  381. op1Validator,
  382. op1Encoding,
  383. op1RW)
  384. {
  385. numArgs = 2;
  386. this->op2Validator = op2Validator;
  387. this->op2Encoding = op2Encoding;
  388. this->op2RW = op2RW;
  389. }
  390. MachineCodeTableEntry(bool rexW,
  391. int opcode,
  392. char opcodeLength,
  393. OperandSizeOverwrite operandSizeOverride,
  394. bool vex,
  395. bool vexL,
  396. char vexPP,
  397. char rmReg,
  398. std::initializer_list<Framework::Assembly::GPRegister>
  399. impliedReadGPRegs,
  400. std::initializer_list<Framework::Assembly::GPRegister>
  401. impliedWriteGPRegs,
  402. std::initializer_list<Framework::Assembly::FPRegister>
  403. impliedReadFPRegs,
  404. std::initializer_list<Framework::Assembly::FPRegister>
  405. impliedWriteFPRegs,
  406. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  407. op1Validator,
  408. OperandEncoding op1Encoding,
  409. OperandRW op1RW,
  410. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  411. op2Validator,
  412. OperandEncoding op2Encoding,
  413. OperandRW op2RW)
  414. : MachineCodeTableEntry(rexW,
  415. opcode,
  416. opcodeLength,
  417. operandSizeOverride,
  418. vex,
  419. vexL,
  420. vexPP,
  421. rmReg,
  422. impliedReadGPRegs,
  423. impliedWriteGPRegs,
  424. impliedReadFPRegs,
  425. impliedWriteFPRegs,
  426. op1Validator,
  427. op1Encoding,
  428. op1RW)
  429. {
  430. numArgs = 2;
  431. this->op2Validator = op2Validator;
  432. this->op2Encoding = op2Encoding;
  433. this->op2RW = op2RW;
  434. }
  435. MachineCodeTableEntry(bool rexW,
  436. int opcode,
  437. char opcodeLength,
  438. OperandSizeOverwrite operandSizeOverride,
  439. bool vex,
  440. bool vexL,
  441. char vexPP,
  442. char rmReg,
  443. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  444. op1Validator,
  445. OperandEncoding op1Encoding,
  446. OperandRW op1RW,
  447. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  448. op2Validator,
  449. OperandEncoding op2Encoding,
  450. OperandRW op2RW,
  451. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  452. op3Validator,
  453. OperandEncoding op3Encoding,
  454. OperandRW op3RW)
  455. : MachineCodeTableEntry(rexW,
  456. opcode,
  457. opcodeLength,
  458. operandSizeOverride,
  459. vex,
  460. vexL,
  461. vexPP,
  462. rmReg,
  463. op1Validator,
  464. op1Encoding,
  465. op1RW,
  466. op2Validator,
  467. op2Encoding,
  468. op2RW)
  469. {
  470. numArgs = 3;
  471. this->op3Validator = op3Validator;
  472. this->op3Encoding = op3Encoding;
  473. this->op3RW = op3RW;
  474. }
  475. MachineCodeTableEntry(bool rexW,
  476. int opcode,
  477. char opcodeLength,
  478. OperandSizeOverwrite operandSizeOverride,
  479. bool vex,
  480. bool vexL,
  481. char vexPP,
  482. char rmReg,
  483. std::initializer_list<Framework::Assembly::GPRegister>
  484. impliedReadGPRegs,
  485. std::initializer_list<Framework::Assembly::GPRegister>
  486. impliedWriteGPRegs,
  487. std::initializer_list<Framework::Assembly::FPRegister>
  488. impliedReadFPRegs,
  489. std::initializer_list<Framework::Assembly::FPRegister>
  490. impliedWriteFPRegs,
  491. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  492. op1Validator,
  493. OperandEncoding op1Encoding,
  494. OperandRW op1RW,
  495. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  496. op2Validator,
  497. OperandEncoding op2Encoding,
  498. OperandRW op2RW,
  499. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  500. op3Validator,
  501. OperandEncoding op3Encoding,
  502. OperandRW op3RW)
  503. : MachineCodeTableEntry(rexW,
  504. opcode,
  505. opcodeLength,
  506. operandSizeOverride,
  507. vex,
  508. vexL,
  509. vexPP,
  510. rmReg,
  511. impliedReadGPRegs,
  512. impliedWriteGPRegs,
  513. impliedReadFPRegs,
  514. impliedWriteFPRegs,
  515. op1Validator,
  516. op1Encoding,
  517. op1RW,
  518. op2Validator,
  519. op2Encoding,
  520. op2RW)
  521. {
  522. numArgs = 3;
  523. this->op3Validator = op3Validator;
  524. this->op3Encoding = op3Encoding;
  525. this->op3RW = op3RW;
  526. }
  527. MachineCodeTableEntry(bool rexW,
  528. int opcode,
  529. char opcodeLength,
  530. OperandSizeOverwrite operandSizeOverride,
  531. bool vex,
  532. bool vexL,
  533. char vexPP,
  534. char rmReg,
  535. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  536. op1Validator,
  537. OperandEncoding op1Encoding,
  538. OperandRW op1RW,
  539. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  540. op2Validator,
  541. OperandEncoding op2Encoding,
  542. OperandRW op2RW,
  543. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  544. op3Validator,
  545. OperandEncoding op3Encoding,
  546. OperandRW op3RW,
  547. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  548. op4Validator,
  549. OperandEncoding op4Encoding,
  550. OperandRW op4RW)
  551. : MachineCodeTableEntry(rexW,
  552. opcode,
  553. opcodeLength,
  554. operandSizeOverride,
  555. vex,
  556. vexL,
  557. vexPP,
  558. rmReg,
  559. op1Validator,
  560. op1Encoding,
  561. op1RW,
  562. op2Validator,
  563. op2Encoding,
  564. op2RW,
  565. op3Validator,
  566. op3Encoding,
  567. op3RW)
  568. {
  569. numArgs = 4;
  570. this->op4Validator = op4Validator;
  571. this->op4Encoding = op4Encoding;
  572. this->op4RW = op4RW;
  573. }
  574. MachineCodeTableEntry(bool rexW,
  575. int opcode,
  576. char opcodeLength,
  577. OperandSizeOverwrite operandSizeOverride,
  578. bool vex,
  579. bool vexL,
  580. char vexPP,
  581. char rmReg,
  582. std::initializer_list<Framework::Assembly::GPRegister>
  583. impliedReadGPRegs,
  584. std::initializer_list<Framework::Assembly::GPRegister>
  585. impliedWriteGPRegs,
  586. std::initializer_list<Framework::Assembly::FPRegister>
  587. impliedReadFPRegs,
  588. std::initializer_list<Framework::Assembly::FPRegister>
  589. impliedWriteFPRegs,
  590. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  591. op1Validator,
  592. OperandEncoding op1Encoding,
  593. OperandRW op1RW,
  594. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  595. op2Validator,
  596. OperandEncoding op2Encoding,
  597. OperandRW op2RW,
  598. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  599. op3Validator,
  600. OperandEncoding op3Encoding,
  601. OperandRW op3RW,
  602. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  603. op4Validator,
  604. OperandEncoding op4Encoding,
  605. OperandRW op4RW)
  606. : MachineCodeTableEntry(rexW,
  607. opcode,
  608. opcodeLength,
  609. operandSizeOverride,
  610. vex,
  611. vexL,
  612. vexPP,
  613. rmReg,
  614. impliedReadGPRegs,
  615. impliedWriteGPRegs,
  616. impliedReadFPRegs,
  617. impliedWriteFPRegs,
  618. op1Validator,
  619. op1Encoding,
  620. op1RW,
  621. op2Validator,
  622. op2Encoding,
  623. op2RW,
  624. op3Validator,
  625. op3Encoding,
  626. op3RW)
  627. {
  628. numArgs = 4;
  629. this->op4Validator = op4Validator;
  630. this->op4Encoding = op4Encoding;
  631. this->op4RW = op4RW;
  632. }
  633. MachineCodeTableEntry(const MachineCodeTableEntry& other) = default;
  634. bool matches(int numArgs,
  635. const std::vector<Framework::Assembly::OperationArgument*>& args) const
  636. {
  637. if (numArgs != this->numArgs)
  638. {
  639. return false;
  640. }
  641. if (numArgs >= 1 && !op1Validator(*args[0]))
  642. {
  643. return false;
  644. }
  645. if (numArgs >= 2 && !op2Validator(*args[1]))
  646. {
  647. return false;
  648. }
  649. if (numArgs >= 3 && !op3Validator(*args[2]))
  650. {
  651. return false;
  652. }
  653. if (numArgs >= 4 && !op4Validator(*args[3]))
  654. {
  655. return false;
  656. }
  657. return true;
  658. }
  659. OperandRW getOperandRW(int index) const
  660. {
  661. switch (index)
  662. {
  663. case 0:
  664. return op1RW;
  665. case 1:
  666. return op2RW;
  667. case 2:
  668. return op3RW;
  669. case 3:
  670. return op4RW;
  671. default:
  672. return NONE;
  673. }
  674. }
  675. const std::vector<Framework::Assembly::GPRegister>&
  676. getImpliedReadGPRegs() const
  677. {
  678. return impliedReadGPRegs;
  679. }
  680. const std::vector<Framework::Assembly::GPRegister>&
  681. getImpliedWriteGPRegs() const
  682. {
  683. return impliedWriteGPRegs;
  684. }
  685. const std::vector<Framework::Assembly::FPRegister>&
  686. getImpliedReadFPRegs() const
  687. {
  688. return impliedReadFPRegs;
  689. }
  690. const std::vector<Framework::Assembly::FPRegister>&
  691. getImpliedWriteFPRegs() const
  692. {
  693. return impliedWriteFPRegs;
  694. }
  695. friend class OperationCodeTable;
  696. };
  697. class OperationCodeTable : public Framework::ReferenceCounter
  698. {
  699. public:
  700. static Framework::RCArray<OperationCodeTable> machineCodeTranslationTable;
  701. static Framework::Critical machineCodeTranslationTableLock;
  702. private:
  703. Framework::Assembly::Operation op;
  704. std::vector<MachineCodeTableEntry> entries;
  705. public:
  706. OperationCodeTable(Framework::Assembly::Operation op,
  707. std::initializer_list<MachineCodeTableEntry> entries)
  708. : ReferenceCounter(),
  709. op(op),
  710. entries(entries)
  711. {}
  712. virtual MachineCodeInstruction getInstruction(
  713. const std::vector<Framework::Assembly::OperationArgument*>& args,
  714. const Framework::Assembly::AssemblyBlock* codeBlock,
  715. const Framework::Assembly::Instruction* current,
  716. Framework::Text& err)
  717. {
  718. MachineCodeInstruction result;
  719. memset(&result, 0, sizeof(MachineCodeInstruction));
  720. const MachineCodeTableEntry* entry
  721. = getEntry(args, codeBlock, current, err);
  722. if (!entry)
  723. {
  724. return result;
  725. }
  726. result.needsVex = entry->vex;
  727. result.vexL = entry->vexL;
  728. result.vexPP = entry->vexPP;
  729. result.needsRex = entry->rexW;
  730. result.exWE = entry->rexW;
  731. result.modRM = entry->rmReg << 3;
  732. if (entry->rmReg)
  733. {
  734. result.needsModRM = true;
  735. }
  736. memcpy(result.opcode, entry->opcode, 3);
  737. result.opcodeLength = entry->opcodeLength;
  738. result.operandSizeOverride = entry->operandSizeOverride;
  739. for (int i = 0; i < (int)args.size(); i++)
  740. {
  741. OperandEncoding encoding = UNDEFINED;
  742. switch (i)
  743. {
  744. case 0:
  745. encoding = entry->op1Encoding;
  746. break;
  747. case 1:
  748. encoding = entry->op2Encoding;
  749. break;
  750. case 2:
  751. encoding = entry->op3Encoding;
  752. break;
  753. case 3:
  754. encoding = entry->op4Encoding;
  755. break;
  756. }
  757. switch (encoding)
  758. {
  759. case MODRM_REG:
  760. encodeModRM_REG(result, args[i], i + 1, err);
  761. break;
  762. case MODRM_RM:
  763. encodeModRM_RM(result, args[i], i + 1, err);
  764. break;
  765. case VEX_VVVV:
  766. encodeVex_VVVV(result, args[i], i + 1, err);
  767. break;
  768. case OPCODE_RD:
  769. encodeOpcode_RD(result, args[i], i + 1, err);
  770. break;
  771. case IMM8:
  772. encodeIMM8(result, args[i], i + 1, err);
  773. break;
  774. case IMM16:
  775. encodeIMM16(result, args[i], i + 1, err);
  776. break;
  777. case IMM32:
  778. encodeIMM32(result, args[i], i + 1, err);
  779. break;
  780. case IMM64:
  781. encodeIMM64(result, args[i], i + 1, err);
  782. break;
  783. default:
  784. break;
  785. }
  786. }
  787. if (result.errIfNoRex && !result.needsRex)
  788. {
  789. err.append() << "Instruction " << op
  790. << " has no REX prefix and can not address "
  791. "LOWER8 of registers RSP, RBP, RSI or RDI\n";
  792. }
  793. if (result.errIfRex && result.needsRex)
  794. {
  795. err.append() << "Instruction " << op
  796. << " has a REX prefix and can not address "
  797. "HIGHER8 of registers RAX, RBX, RCX or RDX\n";
  798. }
  799. return result;
  800. }
  801. MachineCodeTableEntry* getEntry(
  802. const std::vector<Framework::Assembly::OperationArgument*>& args,
  803. const Framework::Assembly::AssemblyBlock* codeBlock,
  804. const Framework::Assembly::Instruction* current,
  805. Framework::Text& err)
  806. {
  807. MachineCodeInstruction result;
  808. memset(&result, 0, sizeof(MachineCodeInstruction));
  809. for (MachineCodeTableEntry& entry : entries)
  810. {
  811. if (entry.matches((int)args.size(), args))
  812. {
  813. return &entry;
  814. }
  815. }
  816. err.append() << "operation " << (int)op
  817. << " not found in translation table. args: \n";
  818. for (auto arg : args)
  819. {
  820. err.append() << " " << typeid(*arg).name() << "\n";
  821. }
  822. return 0;
  823. }
  824. Framework::Assembly::Operation getOperation() const
  825. {
  826. return op;
  827. }
  828. void encodeModRM_REG(MachineCodeInstruction& result,
  829. const Framework::Assembly::OperationArgument* arg,
  830. int index,
  831. Framework::Text& err) const
  832. {
  833. result.needsModRM = true;
  834. const Framework::Assembly::GPRegisterArgument* gpRegArg
  835. = arg->asGPRegisterArgument();
  836. const Framework::Assembly::FPRegisterArgument* fpRegArg
  837. = arg->asFPRegisterArgument();
  838. if (gpRegArg)
  839. {
  840. encodeModRM_REG_GP(result, gpRegArg, index, err);
  841. }
  842. else if (fpRegArg)
  843. {
  844. encodeModRM_REG_FP(result, fpRegArg, index, err);
  845. }
  846. else
  847. {
  848. err.append()
  849. << "Invalid argument type for operand " << index
  850. << " for operation " << op << " encoded as MODRM_REG: found "
  851. << typeid(*arg).name()
  852. << " but expected GPRegisterArgument or FPRegisterArgument\n";
  853. }
  854. }
  855. void encodeModRM_REG_GP(MachineCodeInstruction& result,
  856. const Framework::Assembly::GPRegisterArgument* arg,
  857. int index,
  858. Framework::Text& err) const
  859. {
  860. Framework::Assembly::GPRegister reg = arg->getRegister();
  861. if (reg >= Framework::Assembly::R8)
  862. {
  863. result.needsRex = true;
  864. result.exR = 1;
  865. }
  866. if (arg->getPart() == Framework::Assembly::GPRegisterPart::HIGHER8)
  867. {
  868. if (reg == Framework::Assembly::RAX)
  869. {
  870. result.modRM |= 0b100000;
  871. result.errIfRex = true;
  872. }
  873. else if (reg == Framework::Assembly::RBX)
  874. {
  875. result.modRM |= 0b111000;
  876. result.errIfRex = true;
  877. }
  878. else if (reg == Framework::Assembly::RCX)
  879. {
  880. result.modRM |= 0b101000;
  881. result.errIfRex = true;
  882. }
  883. else if (reg == Framework::Assembly::RDX)
  884. {
  885. result.modRM |= 0b110000;
  886. result.errIfRex = true;
  887. }
  888. else
  889. {
  890. err.append() << "Invalid argument for operand " << index
  891. << " for operation " << op
  892. << " HIGHER8 can only be used for registers RAX, "
  893. "RBX, RCX or RDX\n";
  894. }
  895. }
  896. else
  897. {
  898. result.modRM |= (reg & 0b111) << 3;
  899. }
  900. if (arg->getPart() == Framework::Assembly::GPRegisterPart::LOWER8
  901. && (reg == Framework::Assembly::RSP
  902. || reg == Framework::Assembly::RBP
  903. || reg == Framework::Assembly::RSI
  904. || reg == Framework::Assembly::RDI))
  905. {
  906. result.errIfNoRex = true;
  907. }
  908. }
  909. void encodeModRM_REG_FP(MachineCodeInstruction& result,
  910. const Framework::Assembly::FPRegisterArgument* arg,
  911. int index,
  912. Framework::Text& err) const
  913. {
  914. Framework::Assembly::FPRegister reg = arg->getRegister();
  915. if (reg >= Framework::Assembly::MM8)
  916. {
  917. result.needsRex = true;
  918. result.exR = 1;
  919. }
  920. result.modRM |= (reg & 0b111) << 3;
  921. }
  922. void encodeModRM_RM(MachineCodeInstruction& result,
  923. const Framework::Assembly::OperationArgument* arg,
  924. int index,
  925. Framework::Text& err) const
  926. {
  927. result.needsModRM = true;
  928. const Framework::Assembly::GPRegisterArgument* gpRegArg
  929. = arg->asGPRegisterArgument();
  930. const Framework::Assembly::FPRegisterArgument* fpRegArg
  931. = arg->asFPRegisterArgument();
  932. const Framework::Assembly::MemoryAccessArgument* memArg
  933. = arg->asMemoryAccessArgument();
  934. if (gpRegArg)
  935. {
  936. encodeModRM_RM_GP(result, gpRegArg, index, err);
  937. }
  938. else if (fpRegArg)
  939. {
  940. encodeModRM_RM_FP(result, fpRegArg, index, err);
  941. }
  942. else if (memArg)
  943. {
  944. encodeModRM_RM_Mem(result, memArg, index, err);
  945. }
  946. else
  947. {
  948. err.append()
  949. << "Invalid argument type for operand " << index
  950. << " for operation " << op << " encoded as MODRM_RM: found "
  951. << typeid(*arg).name()
  952. << " but expected GPRegisterArgument, FPRegisterArgument "
  953. "or MemoryAccessArgument\n";
  954. }
  955. }
  956. void encodeModRM_RM_GP(MachineCodeInstruction& result,
  957. const Framework::Assembly::GPRegisterArgument* arg,
  958. int index,
  959. Framework::Text& err) const
  960. {
  961. Framework::Assembly::GPRegister reg = arg->getRegister();
  962. if (reg >= Framework::Assembly::R8)
  963. {
  964. result.needsRex = true;
  965. result.exB = 1;
  966. }
  967. result.modRM |= (char)(0b11 << 6); // direct register access
  968. if (arg->getPart() == Framework::Assembly::GPRegisterPart::HIGHER8)
  969. {
  970. if (reg == Framework::Assembly::RAX)
  971. {
  972. result.modRM |= 0b100;
  973. result.errIfRex = true;
  974. }
  975. else if (reg == Framework::Assembly::RBX)
  976. {
  977. result.modRM |= 0b111;
  978. result.errIfRex = true;
  979. }
  980. else if (reg == Framework::Assembly::RCX)
  981. {
  982. result.modRM |= 0b101;
  983. result.errIfRex = true;
  984. }
  985. else if (reg == Framework::Assembly::RDX)
  986. {
  987. result.modRM |= 0b110;
  988. result.errIfRex = true;
  989. }
  990. else
  991. {
  992. err.append() << "Invalid argument for operand " << index
  993. << " for operation " << op
  994. << " HIGHER8 can only be used for registers RAX, "
  995. "RBX, RCX or RDX\n";
  996. }
  997. }
  998. else
  999. {
  1000. result.modRM |= reg & 0b111;
  1001. }
  1002. if (arg->getPart() == Framework::Assembly::GPRegisterPart::LOWER8
  1003. && (reg == Framework::Assembly::RSP
  1004. || reg == Framework::Assembly::RBP
  1005. || reg == Framework::Assembly::RSI
  1006. || reg == Framework::Assembly::RDI))
  1007. {
  1008. result.errIfNoRex = true;
  1009. }
  1010. }
  1011. void encodeModRM_RM_FP(MachineCodeInstruction& result,
  1012. const Framework::Assembly::FPRegisterArgument* arg,
  1013. int index,
  1014. Framework::Text& err) const
  1015. {
  1016. Framework::Assembly::FPRegister reg = arg->getRegister();
  1017. if (reg >= Framework::Assembly::MM8)
  1018. {
  1019. result.needsRex = true;
  1020. result.exB = 1;
  1021. }
  1022. result.modRM |= (char)(0b11 << 6); // direct register access
  1023. result.modRM |= reg & 0b111;
  1024. }
  1025. void encodeModRM_RM_Mem(MachineCodeInstruction& result,
  1026. const Framework::Assembly::MemoryAccessArgument* arg,
  1027. int index,
  1028. Framework::Text& err) const
  1029. {
  1030. if (arg->isUsingAddressRegister() || arg->isUsingOffsetRegister())
  1031. {
  1032. Framework::Assembly::GPRegister reg = arg->isUsingAddressRegister()
  1033. ? arg->getAddressRegister()
  1034. : arg->getOffsetRegister();
  1035. if (arg->isUsingAddressRegister() && arg->isUsingOffsetRegister())
  1036. {
  1037. // SIB needed
  1038. result.sibNeeded = true;
  1039. result.modRM |= 0b100; // indicate SIB
  1040. if (reg >= Framework::Assembly::R8)
  1041. {
  1042. result.needsRex = true;
  1043. result.exB = 1;
  1044. }
  1045. result.sib |= reg & 0b111;
  1046. Framework::Assembly::GPRegister offsetReg
  1047. = arg->getOffsetRegister();
  1048. if (offsetReg == Framework::Assembly::RSP)
  1049. {
  1050. err.append() << "Invalid argument for operand " << index
  1051. << " for operation " << op
  1052. << " RSP can not be used as index register\n";
  1053. }
  1054. if (offsetReg >= Framework::Assembly::R8)
  1055. {
  1056. result.needsRex = true;
  1057. result.exX = 1;
  1058. }
  1059. result.sib |= (offsetReg & 0b111) << 3; // index register
  1060. }
  1061. else if (reg == 0b100)
  1062. {
  1063. // SIB needed
  1064. result.sibNeeded = true;
  1065. result.modRM |= 0b100; // indicate SIB
  1066. result.sib |= reg & 0b111;
  1067. result.sib |= 0b100 << 3; // no index register
  1068. }
  1069. else
  1070. {
  1071. if (reg >= Framework::Assembly::R8)
  1072. {
  1073. result.needsRex = true;
  1074. result.exB = 1;
  1075. }
  1076. result.modRM |= reg & 0b111;
  1077. }
  1078. int offset = arg->getOffset();
  1079. if (offset)
  1080. {
  1081. if (offset <= 127 && offset >= -128)
  1082. {
  1083. result.modRM |= 0b01 << 6; // 8 bit displacement
  1084. result.disp[0] = (char)offset;
  1085. result.dispLength = 1;
  1086. }
  1087. else
  1088. {
  1089. result.modRM |= (char)(0b10 << 6); // 32 bit displacement
  1090. memcpy(result.disp, &offset, 4);
  1091. }
  1092. }
  1093. else
  1094. {
  1095. if ((result.modRM & 0b111) == 0b101)
  1096. {
  1097. // special case: EBP or R13 as
  1098. // address register needs disp8=0
  1099. result.modRM |= 0b01 << 6; // 8 bit displacement
  1100. result.disp[0] = 0;
  1101. result.dispLength = 1;
  1102. }
  1103. }
  1104. }
  1105. else
  1106. {
  1107. result.modRM |= 0b100;
  1108. result.sibNeeded = true;
  1109. result.sib = 0b00100101; // no base, no index only
  1110. // disp32
  1111. int offset = arg->getOffset();
  1112. memcpy(result.disp, &offset, 4);
  1113. result.dispLength = 4;
  1114. }
  1115. }
  1116. void encodeVex_VVVV(MachineCodeInstruction& result,
  1117. const Framework::Assembly::OperationArgument* arg,
  1118. int index,
  1119. Framework::Text& err) const
  1120. {
  1121. const Framework::Assembly::FPRegisterArgument* fpRegArg
  1122. = arg->asFPRegisterArgument();
  1123. if (fpRegArg)
  1124. {
  1125. encodeVex_VVVV_FP(result, fpRegArg, index, err);
  1126. }
  1127. else
  1128. {
  1129. err.append() << "Invalid argument type for operand " << index
  1130. << " for operation " << op
  1131. << " encoded as VEX_VVVV: found "
  1132. << typeid(*arg).name()
  1133. << " but expected FPRegisterArgument\n";
  1134. }
  1135. }
  1136. void encodeVex_VVVV_FP(MachineCodeInstruction& result,
  1137. const Framework::Assembly::FPRegisterArgument* arg,
  1138. int index,
  1139. Framework::Text& err) const
  1140. {
  1141. Framework::Assembly::FPRegister reg = arg->getRegister();
  1142. result.vexVVVV = reg & 0b1111;
  1143. result.needsVex = true;
  1144. }
  1145. void encodeOpcode_RD(MachineCodeInstruction& result,
  1146. const Framework::Assembly::OperationArgument* arg,
  1147. int index,
  1148. Framework::Text& err) const
  1149. {
  1150. const Framework::Assembly::GPRegisterArgument* gpRegArg
  1151. = arg->asGPRegisterArgument();
  1152. if (gpRegArg)
  1153. {
  1154. encodeOpcode_RD_GP(result, gpRegArg, index, err);
  1155. }
  1156. else
  1157. {
  1158. err.append() << "Invalid argument type for operand " << index
  1159. << " for operation " << op
  1160. << " encoded as OPCODE_RD: found "
  1161. << typeid(*arg).name()
  1162. << " but expected GPRegisterArgument\n";
  1163. }
  1164. }
  1165. void encodeOpcode_RD_GP(MachineCodeInstruction& result,
  1166. const Framework::Assembly::GPRegisterArgument* arg,
  1167. int index,
  1168. Framework::Text& err) const
  1169. {
  1170. Framework::Assembly::GPRegister reg = arg->getRegister();
  1171. if (reg >= Framework::Assembly::R8)
  1172. {
  1173. result.needsRex = true;
  1174. result.exB = 1;
  1175. }
  1176. result.opcode[result.opcodeLength - 1] |= reg & 0b111;
  1177. }
  1178. void encodeIMM8(MachineCodeInstruction& result,
  1179. Framework::Assembly::OperationArgument* arg,
  1180. int index,
  1181. Framework::Text& err) const
  1182. {
  1183. if (result.immLength >= 8)
  1184. {
  1185. err.append() << "Invalid argument type for operand " << index
  1186. << " for operation " << op
  1187. << " encoded as IMM8: imm bytes are already in use\n";
  1188. return;
  1189. }
  1190. const Framework::Assembly::ConstantArgument* constArg
  1191. = arg->asConstantArgument();
  1192. if (constArg == 0)
  1193. {
  1194. err.append() << "Invalid argument type for operand " << index
  1195. << " for operation " << op
  1196. << " encoded as IMM8: found " << typeid(*arg).name()
  1197. << " but expected ConstantArgument\n";
  1198. return;
  1199. }
  1200. int value = (int)constArg->getValue();
  1201. int len = (int)constArg->getSize();
  1202. if (len > 1)
  1203. {
  1204. err.append() << "Constant size too large for operand " << index
  1205. << " for operation " << op
  1206. << " encoded as IMM8: found size " << len
  1207. << " but expected size BYTE\n";
  1208. return;
  1209. }
  1210. result.imm[(int)result.immLength] = (char)(value);
  1211. result.immLength += 1;
  1212. }
  1213. void encodeIMM16(MachineCodeInstruction& result,
  1214. Framework::Assembly::OperationArgument* arg,
  1215. int index,
  1216. Framework::Text& err) const
  1217. {
  1218. if (result.immLength >= 7)
  1219. {
  1220. err.append() << "Invalid argument type for operand " << index
  1221. << " for operation " << op
  1222. << " encoded as IMM16: imm bytes are already in use\n";
  1223. return;
  1224. }
  1225. const Framework::Assembly::ConstantArgument* constArg
  1226. = arg->asConstantArgument();
  1227. if (constArg == 0)
  1228. {
  1229. err.append() << "Invalid argument type for operand " << index
  1230. << " for operation " << op
  1231. << " encoded as IMM16: found " << typeid(*arg).name()
  1232. << " but expected ConstantArgument\n";
  1233. return;
  1234. }
  1235. int value = (int)constArg->getValue();
  1236. int len = (int)constArg->getSize();
  1237. if (len > 2)
  1238. {
  1239. err.append() << "Constant size too large for operand " << index
  1240. << " for operation " << op
  1241. << " encoded as IMM16: found size " << len
  1242. << " but expected size range [BYTE, WORD]\n";
  1243. return;
  1244. }
  1245. short val = (short)(value);
  1246. memcpy(result.imm + result.immLength, &val, 2);
  1247. result.immLength += 2;
  1248. }
  1249. void encodeIMM32(MachineCodeInstruction& result,
  1250. Framework::Assembly::OperationArgument* arg,
  1251. int index,
  1252. Framework::Text& err) const
  1253. {
  1254. if (result.immLength >= 5)
  1255. {
  1256. err.append() << "Invalid argument type for operand " << index
  1257. << " for operation " << op
  1258. << " encoded as IMM32: imm bytes are already in use\n";
  1259. return;
  1260. }
  1261. const Framework::Assembly::ConstantArgument* constArg
  1262. = arg->asConstantArgument();
  1263. if (constArg == 0)
  1264. {
  1265. err.append() << "Invalid argument type for operand " << index
  1266. << " for operation " << op
  1267. << " encoded as IMM32: found " << typeid(*arg).name()
  1268. << " but expected ConstantArgument\n";
  1269. return;
  1270. }
  1271. int value = (int)constArg->getValue();
  1272. int len = (int)constArg->getSize();
  1273. if (len > 4)
  1274. {
  1275. err.append() << "Constant size too large for operand " << index
  1276. << " for operation " << op
  1277. << " encoded as IMM32: found size " << len
  1278. << " but expected size range [BYTE, DWORD]\n";
  1279. return;
  1280. }
  1281. memcpy(result.imm + result.immLength, &value, 4);
  1282. result.immLength += 4;
  1283. }
  1284. void encodeIMM64(MachineCodeInstruction& result,
  1285. Framework::Assembly::OperationArgument* arg,
  1286. int index,
  1287. Framework::Text& err) const
  1288. {
  1289. if (result.immLength >= 1)
  1290. {
  1291. err.append() << "Invalid argument type for operand " << index
  1292. << " for operation " << op
  1293. << " encoded as IMM64: imm bytes are already in use\n";
  1294. return;
  1295. }
  1296. const Framework::Assembly::ConstantArgument* constArg
  1297. = arg->asConstantArgument();
  1298. if (constArg == 0)
  1299. {
  1300. err.append() << "Invalid argument type for operand " << index
  1301. << " for operation " << op
  1302. << " encoded as IMM64: found " << typeid(*arg).name()
  1303. << " but expected ConstantArgument\n";
  1304. return;
  1305. }
  1306. __int64 value = constArg->getValue();
  1307. int len = (int)constArg->getSize();
  1308. if (len > 8)
  1309. {
  1310. err.append() << "Constant size too large for operand " << index
  1311. << " for operation " << op
  1312. << " encoded as IMM64: found size " << len
  1313. << " but expected size range [BYTE, QWORD]\n";
  1314. return;
  1315. }
  1316. memcpy(result.imm + result.immLength, &value, 8);
  1317. result.immLength += 8;
  1318. }
  1319. };
  1320. class JumpOperationCodeTable : public OperationCodeTable
  1321. {
  1322. private:
  1323. char opCodeLength;
  1324. bool inGetEntry;
  1325. public:
  1326. JumpOperationCodeTable(Framework::Assembly::Operation op,
  1327. char opCodeLength,
  1328. std::initializer_list<MachineCodeTableEntry> entries)
  1329. : OperationCodeTable(op, entries),
  1330. opCodeLength(opCodeLength),
  1331. inGetEntry(0)
  1332. {}
  1333. virtual MachineCodeInstruction getInstruction(
  1334. const std::vector<Framework::Assembly::OperationArgument*>& args,
  1335. const Framework::Assembly::AssemblyBlock* codeBlock,
  1336. const Framework::Assembly::Instruction* current,
  1337. Framework::Text& err) override
  1338. {
  1339. if (inGetEntry)
  1340. {
  1341. // recursion can only happen during size calculation so we just
  1342. // create a dummy const argument for each jump target
  1343. std::vector<Framework::Assembly::OperationArgument*> newArgs;
  1344. std::vector<Framework::Assembly::OperationArgument*>
  1345. transformedArgs;
  1346. for (Framework::Assembly::OperationArgument* arg : args)
  1347. {
  1348. if (arg->asJumpTargetArgument())
  1349. {
  1350. Framework::Assembly::ConstantArgument* constArg
  1351. = new Framework::Assembly::ConstantArgument(0);
  1352. transformedArgs.push_back(constArg);
  1353. newArgs.push_back(constArg);
  1354. }
  1355. else
  1356. {
  1357. transformedArgs.push_back(arg);
  1358. }
  1359. }
  1360. MachineCodeInstruction result = OperationCodeTable::getInstruction(
  1361. transformedArgs, codeBlock, current, err);
  1362. for (Framework::Assembly::OperationArgument* arg : newArgs)
  1363. {
  1364. delete arg;
  1365. }
  1366. return result;
  1367. }
  1368. inGetEntry = 1;
  1369. std::vector<Framework::Assembly::OperationArgument*> newArgs;
  1370. std::vector<Framework::Assembly::OperationArgument*> transformedArgs;
  1371. for (Framework::Assembly::OperationArgument* arg : args)
  1372. {
  1373. if (arg->asJumpTargetArgument())
  1374. {
  1375. Framework::Text label = arg->asJumpTargetArgument()->getLabel();
  1376. bool currentFound = false;
  1377. bool labelFound = false;
  1378. bool backwords = false;
  1379. int jumpLength = 0;
  1380. // search for the label
  1381. for (const Framework::Assembly::Instruction* instr :
  1382. codeBlock->getInstructions())
  1383. {
  1384. if (instr == current)
  1385. {
  1386. currentFound = true;
  1387. if (labelFound)
  1388. {
  1389. break;
  1390. }
  1391. continue;
  1392. }
  1393. if (instr->definesLabel(label))
  1394. {
  1395. labelFound = true;
  1396. if (currentFound)
  1397. {
  1398. break;
  1399. }
  1400. else
  1401. {
  1402. backwords = true;
  1403. }
  1404. continue;
  1405. }
  1406. if (labelFound || currentFound)
  1407. {
  1408. jumpLength += instr->compiledSize(codeBlock);
  1409. }
  1410. }
  1411. if (backwords)
  1412. {
  1413. jumpLength = -jumpLength - 4 - opCodeLength;
  1414. }
  1415. Framework::Assembly::ConstantArgument* constArg
  1416. = new Framework::Assembly::ConstantArgument(jumpLength);
  1417. transformedArgs.push_back(constArg);
  1418. newArgs.push_back(constArg);
  1419. }
  1420. else
  1421. {
  1422. transformedArgs.push_back(arg);
  1423. }
  1424. }
  1425. MachineCodeInstruction result = OperationCodeTable::getInstruction(
  1426. transformedArgs, codeBlock, current, err);
  1427. for (Framework::Assembly::OperationArgument* arg : newArgs)
  1428. {
  1429. delete arg;
  1430. }
  1431. inGetEntry = 0;
  1432. return result;
  1433. }
  1434. };
  1435. Framework::RCArray<OperationCodeTable>
  1436. OperationCodeTable::machineCodeTranslationTable;
  1437. Framework::Critical OperationCodeTable::machineCodeTranslationTableLock;
  1438. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  1439. isGPRegister(Framework::Assembly::MemoryBlockSize size)
  1440. {
  1441. return [size](const Framework::Assembly::OperationArgument& arg) {
  1442. return arg.asGPRegisterArgument() != 0
  1443. && ((size == Framework::Assembly::MemoryBlockSize::BYTE
  1444. && (arg.asGPRegisterArgument()->getPart()
  1445. == Framework::Assembly::LOWER8
  1446. || arg.asGPRegisterArgument()->getPart()
  1447. == Framework::Assembly::HIGHER8))
  1448. || (size == Framework::Assembly::MemoryBlockSize::WORD
  1449. && arg.asGPRegisterArgument()->getPart()
  1450. == Framework::Assembly::LOWER16)
  1451. || (size == Framework::Assembly::MemoryBlockSize::DWORD
  1452. && arg.asGPRegisterArgument()->getPart()
  1453. == Framework::Assembly::LOWER32)
  1454. || (size == Framework::Assembly::MemoryBlockSize::QWORD
  1455. && arg.asGPRegisterArgument()->getPart()
  1456. == Framework::Assembly::FULL64));
  1457. };
  1458. }
  1459. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  1460. isSpecificGPRegister(Framework::Assembly::GPRegister reg,
  1461. Framework::Assembly::GPRegisterPart part)
  1462. {
  1463. return [reg, part](const Framework::Assembly::OperationArgument& arg) {
  1464. return arg.asGPRegisterArgument() != 0
  1465. && arg.asGPRegisterArgument()->getRegister() == reg
  1466. && arg.asGPRegisterArgument()->getPart() == part;
  1467. };
  1468. }
  1469. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  1470. isGPRegisterOrMemoryAccess(Framework::Assembly::MemoryBlockSize size)
  1471. {
  1472. return [size](const Framework::Assembly::OperationArgument& arg) {
  1473. return isGPRegister(size)(arg)
  1474. || (arg.asMemoryAccessArgument()
  1475. && arg.asMemoryAccessArgument()->getBlockSize() == size);
  1476. };
  1477. }
  1478. std::function<bool(const Framework::Assembly::OperationArgument& arg)> isIMM()
  1479. {
  1480. return [](const Framework::Assembly::OperationArgument& arg) {
  1481. return arg.asConstantArgument();
  1482. };
  1483. }
  1484. std::function<bool(const Framework::Assembly::OperationArgument& arg)> isIMM(
  1485. Framework::Assembly::MemoryBlockSize maxSize)
  1486. {
  1487. return [maxSize](const Framework::Assembly::OperationArgument& arg) {
  1488. return arg.asConstantArgument()
  1489. && arg.asConstantArgument()->getSize() <= maxSize;
  1490. };
  1491. }
  1492. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  1493. isFPRegister(Framework::Assembly::MemoryBlockSize size)
  1494. {
  1495. return [size](const Framework::Assembly::OperationArgument& arg) {
  1496. return arg.asFPRegisterArgument() != 0
  1497. && ((size == Framework::Assembly::MemoryBlockSize::M128
  1498. && arg.asFPRegisterArgument()->getPart()
  1499. == Framework::Assembly::X)
  1500. || (size == Framework::Assembly::MemoryBlockSize::M256
  1501. && arg.asFPRegisterArgument()->getPart()
  1502. == Framework::Assembly::Y)
  1503. /*
  1504. || (size == Framework::Assembly::MemoryBlockSize::M512
  1505. && arg.asFPRegisterArgument()->getPart()
  1506. == Framework::Assembly::Z)*/);
  1507. };
  1508. }
  1509. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  1510. isFPRegisterOrMEmoryAccess(Framework::Assembly::MemoryBlockSize size)
  1511. {
  1512. return [size](const Framework::Assembly::OperationArgument& arg) {
  1513. return isFPRegister(size)
  1514. || (arg.asMemoryAccessArgument()
  1515. && arg.asMemoryAccessArgument()->getBlockSize() == size);
  1516. };
  1517. }
  1518. std::function<bool(const Framework::Assembly::OperationArgument& arg)>
  1519. isFPRegisterOrMEmoryAccess(Framework::Assembly::MemoryBlockSize regSize,
  1520. Framework::Assembly::MemoryBlockSize memSize)
  1521. {
  1522. return
  1523. [regSize, memSize](const Framework::Assembly::OperationArgument& arg) {
  1524. return isFPRegister(regSize)
  1525. || (arg.asMemoryAccessArgument()
  1526. && arg.asMemoryAccessArgument()->getBlockSize() == memSize);
  1527. };
  1528. }
  1529. void __intializeMachineCodeTranslationTable()
  1530. {
  1531. OperationCodeTable::machineCodeTranslationTableLock.lock();
  1532. if (!OperationCodeTable::machineCodeTranslationTable.getEntryCount())
  1533. {
  1534. OperationCodeTable::machineCodeTranslationTable.add(
  1535. new OperationCodeTable(Framework::Assembly::ADD,
  1536. {// ADD AL, IMM8
  1537. MachineCodeTableEntry(false,
  1538. 0x04,
  1539. (char)1,
  1540. NO_PREFIX,
  1541. false,
  1542. false,
  1543. 0,
  1544. 0,
  1545. isSpecificGPRegister(Framework::Assembly::RAX,
  1546. Framework::Assembly::LOWER8),
  1547. UNDEFINED,
  1548. READWRITE,
  1549. isIMM(),
  1550. IMM8,
  1551. READ),
  1552. // ADD AX, IMM16
  1553. MachineCodeTableEntry(false,
  1554. 0x05,
  1555. (char)1,
  1556. X66,
  1557. false,
  1558. false,
  1559. 0,
  1560. 0,
  1561. isSpecificGPRegister(Framework::Assembly::RAX,
  1562. Framework::Assembly::LOWER16),
  1563. UNDEFINED,
  1564. READWRITE,
  1565. isIMM(),
  1566. IMM16,
  1567. READ),
  1568. // ADD EAX, IMM32
  1569. MachineCodeTableEntry(
  1570. false,
  1571. 0x05,
  1572. (char)1,
  1573. NO_PREFIX,
  1574. false,
  1575. false,
  1576. 0,
  1577. 0,
  1578. isSpecificGPRegister(Framework::Assembly::RAX,
  1579. Framework::Assembly::LOWER32),
  1580. UNDEFINED,
  1581. READWRITE,
  1582. [](const Framework::Assembly::OperationArgument& arg) {
  1583. return arg.asConstantArgument() != 0;
  1584. },
  1585. IMM32,
  1586. READ),
  1587. // ADD RAX, IMM32
  1588. MachineCodeTableEntry(true,
  1589. 0x05,
  1590. (char)1,
  1591. NO_PREFIX,
  1592. false,
  1593. false,
  1594. 0,
  1595. 0,
  1596. isSpecificGPRegister(Framework::Assembly::RAX,
  1597. Framework::Assembly::FULL64),
  1598. UNDEFINED,
  1599. READWRITE,
  1600. isIMM(),
  1601. IMM32,
  1602. READ),
  1603. // ADD r/m8, IMM8
  1604. MachineCodeTableEntry(false,
  1605. 0x80,
  1606. (char)1,
  1607. NO_PREFIX,
  1608. false,
  1609. false,
  1610. 0,
  1611. 0,
  1612. isGPRegisterOrMemoryAccess(
  1613. Framework::Assembly::MemoryBlockSize::BYTE),
  1614. MODRM_RM,
  1615. READWRITE,
  1616. isIMM(),
  1617. IMM8,
  1618. READ),
  1619. // ADD r/m16, IMM8
  1620. MachineCodeTableEntry(false,
  1621. 0x83,
  1622. (char)1,
  1623. X66,
  1624. false,
  1625. false,
  1626. 0,
  1627. 0,
  1628. isGPRegisterOrMemoryAccess(
  1629. Framework::Assembly::MemoryBlockSize::WORD),
  1630. MODRM_RM,
  1631. READWRITE,
  1632. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  1633. IMM8,
  1634. READ),
  1635. // ADD r/m32, IMM8
  1636. MachineCodeTableEntry(false,
  1637. 0x83,
  1638. (char)1,
  1639. NO_PREFIX,
  1640. false,
  1641. false,
  1642. 0,
  1643. 0,
  1644. isGPRegisterOrMemoryAccess(
  1645. Framework::Assembly::MemoryBlockSize::DWORD),
  1646. MODRM_RM,
  1647. READWRITE,
  1648. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  1649. IMM8,
  1650. READ),
  1651. // ADD r/m64, IMM8
  1652. MachineCodeTableEntry(true,
  1653. 0x83,
  1654. (char)1,
  1655. NO_PREFIX,
  1656. false,
  1657. false,
  1658. 0,
  1659. 0,
  1660. isGPRegisterOrMemoryAccess(
  1661. Framework::Assembly::MemoryBlockSize::QWORD),
  1662. MODRM_RM,
  1663. READWRITE,
  1664. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  1665. IMM8,
  1666. READ),
  1667. // ADD r/m16, IMM16
  1668. MachineCodeTableEntry(
  1669. false,
  1670. 0x81,
  1671. (char)1,
  1672. X66,
  1673. false,
  1674. false,
  1675. 0,
  1676. 0,
  1677. isGPRegisterOrMemoryAccess(
  1678. Framework::Assembly::MemoryBlockSize::WORD),
  1679. MODRM_RM,
  1680. READWRITE,
  1681. [](const Framework::Assembly::OperationArgument& arg) {
  1682. return arg.asConstantArgument()
  1683. && arg.asConstantArgument()->getSize()
  1684. != Framework::Assembly::MemoryBlockSize::
  1685. BYTE;
  1686. },
  1687. IMM16,
  1688. READ),
  1689. // ADD r/m32, IMM32
  1690. MachineCodeTableEntry(
  1691. false,
  1692. 0x81,
  1693. (char)1,
  1694. NO_PREFIX,
  1695. false,
  1696. false,
  1697. 0,
  1698. 0,
  1699. isGPRegisterOrMemoryAccess(
  1700. Framework::Assembly::MemoryBlockSize::DWORD),
  1701. MODRM_RM,
  1702. READWRITE,
  1703. [](const Framework::Assembly::OperationArgument& arg) {
  1704. return arg.asConstantArgument() != 0
  1705. && arg.asConstantArgument()->getSize()
  1706. != Framework::Assembly::MemoryBlockSize::
  1707. BYTE;
  1708. },
  1709. IMM32,
  1710. READ),
  1711. // ADD r/m64, IMM32
  1712. MachineCodeTableEntry(
  1713. true,
  1714. 0x81,
  1715. (char)1,
  1716. NO_PREFIX,
  1717. false,
  1718. false,
  1719. 0,
  1720. 0,
  1721. isGPRegisterOrMemoryAccess(
  1722. Framework::Assembly::MemoryBlockSize::QWORD),
  1723. MODRM_RM,
  1724. READWRITE,
  1725. [](const Framework::Assembly::OperationArgument& arg) {
  1726. return arg.asConstantArgument() != 0
  1727. && arg.asConstantArgument()->getSize()
  1728. != Framework::Assembly::MemoryBlockSize::
  1729. BYTE;
  1730. },
  1731. IMM32,
  1732. READ),
  1733. // ADD r/m8, r8
  1734. MachineCodeTableEntry(false,
  1735. 0x00,
  1736. (char)1,
  1737. NO_PREFIX,
  1738. false,
  1739. false,
  1740. 0,
  1741. 0,
  1742. isGPRegisterOrMemoryAccess(
  1743. Framework::Assembly::MemoryBlockSize::BYTE),
  1744. MODRM_RM,
  1745. READWRITE,
  1746. isGPRegister(
  1747. Framework::Assembly::MemoryBlockSize::BYTE),
  1748. MODRM_REG,
  1749. READ),
  1750. // ADD r/m16, r16
  1751. MachineCodeTableEntry(false,
  1752. 0x01,
  1753. (char)1,
  1754. X66,
  1755. false,
  1756. false,
  1757. 0,
  1758. 0,
  1759. isGPRegisterOrMemoryAccess(
  1760. Framework::Assembly::MemoryBlockSize::WORD),
  1761. MODRM_RM,
  1762. READWRITE,
  1763. isGPRegister(
  1764. Framework::Assembly::MemoryBlockSize::WORD),
  1765. MODRM_REG,
  1766. READ),
  1767. // ADD r/m32, r32
  1768. MachineCodeTableEntry(false,
  1769. 0x01,
  1770. (char)1,
  1771. NO_PREFIX,
  1772. false,
  1773. false,
  1774. 0,
  1775. 0,
  1776. isGPRegisterOrMemoryAccess(
  1777. Framework::Assembly::MemoryBlockSize::DWORD),
  1778. MODRM_RM,
  1779. READWRITE,
  1780. isGPRegister(
  1781. Framework::Assembly::MemoryBlockSize::DWORD),
  1782. MODRM_REG,
  1783. READ),
  1784. // ADD r/m64, r64
  1785. MachineCodeTableEntry(true,
  1786. 0x01,
  1787. (char)1,
  1788. NO_PREFIX,
  1789. false,
  1790. false,
  1791. 0,
  1792. 0,
  1793. isGPRegisterOrMemoryAccess(
  1794. Framework::Assembly::MemoryBlockSize::QWORD),
  1795. MODRM_RM,
  1796. READWRITE,
  1797. isGPRegister(
  1798. Framework::Assembly::MemoryBlockSize::QWORD),
  1799. MODRM_REG,
  1800. READ),
  1801. // ADD r8, r/m8
  1802. MachineCodeTableEntry(false,
  1803. 0x02,
  1804. (char)1,
  1805. NO_PREFIX,
  1806. false,
  1807. false,
  1808. 0,
  1809. 0,
  1810. isGPRegister(
  1811. Framework::Assembly::MemoryBlockSize::BYTE),
  1812. MODRM_REG,
  1813. READWRITE,
  1814. isGPRegisterOrMemoryAccess(
  1815. Framework::Assembly::MemoryBlockSize::BYTE),
  1816. MODRM_RM,
  1817. READ),
  1818. // ADD r16, r/m16
  1819. MachineCodeTableEntry(false,
  1820. 0x03,
  1821. (char)1,
  1822. X66,
  1823. false,
  1824. false,
  1825. 0,
  1826. 0,
  1827. isGPRegister(
  1828. Framework::Assembly::MemoryBlockSize::WORD),
  1829. MODRM_REG,
  1830. READWRITE,
  1831. isGPRegisterOrMemoryAccess(
  1832. Framework::Assembly::MemoryBlockSize::WORD),
  1833. MODRM_RM,
  1834. READ),
  1835. // ADD r32, r/m32
  1836. MachineCodeTableEntry(false,
  1837. 0x03,
  1838. (char)1,
  1839. NO_PREFIX,
  1840. false,
  1841. false,
  1842. 0,
  1843. 0,
  1844. isGPRegister(
  1845. Framework::Assembly::MemoryBlockSize::DWORD),
  1846. MODRM_REG,
  1847. READWRITE,
  1848. isGPRegisterOrMemoryAccess(
  1849. Framework::Assembly::MemoryBlockSize::DWORD),
  1850. MODRM_RM,
  1851. READ),
  1852. // ADD r64, r/m64
  1853. MachineCodeTableEntry(true,
  1854. 0x03,
  1855. (char)1,
  1856. NO_PREFIX,
  1857. false,
  1858. false,
  1859. 0,
  1860. 0,
  1861. isGPRegister(
  1862. Framework::Assembly::MemoryBlockSize::QWORD),
  1863. MODRM_REG,
  1864. READWRITE,
  1865. isGPRegisterOrMemoryAccess(
  1866. Framework::Assembly::MemoryBlockSize::QWORD),
  1867. MODRM_RM,
  1868. READ)}));
  1869. OperationCodeTable::machineCodeTranslationTable.add(
  1870. new OperationCodeTable(Framework::Assembly::ADDPD,
  1871. {// ADDPD xmm1, xmm2/m128
  1872. MachineCodeTableEntry(false,
  1873. 0x580F,
  1874. (char)2,
  1875. X66,
  1876. false,
  1877. false,
  1878. 0,
  1879. 0,
  1880. isFPRegister(
  1881. Framework::Assembly::MemoryBlockSize::M128),
  1882. MODRM_REG,
  1883. READWRITE,
  1884. isFPRegisterOrMEmoryAccess(
  1885. Framework::Assembly::MemoryBlockSize::M128),
  1886. MODRM_RM,
  1887. READ),
  1888. // VADDPD xmm1,xmm2, xmm3/m128
  1889. MachineCodeTableEntry(false,
  1890. 0x580F,
  1891. (char)2,
  1892. NO_PREFIX,
  1893. true,
  1894. false,
  1895. 0b01,
  1896. 0,
  1897. isFPRegister(
  1898. Framework::Assembly::MemoryBlockSize::M128),
  1899. MODRM_REG,
  1900. WRITE,
  1901. isFPRegister(
  1902. Framework::Assembly::MemoryBlockSize::M128),
  1903. VEX_VVVV,
  1904. READ,
  1905. isFPRegisterOrMEmoryAccess(
  1906. Framework::Assembly::MemoryBlockSize::M128),
  1907. MODRM_RM,
  1908. READ),
  1909. // VADDPD ymm1,ymm2, ymm3/m256
  1910. MachineCodeTableEntry(false,
  1911. 0x580F,
  1912. (char)2,
  1913. NO_PREFIX,
  1914. true,
  1915. true,
  1916. 0b01,
  1917. 0,
  1918. isFPRegister(
  1919. Framework::Assembly::MemoryBlockSize::M256),
  1920. MODRM_REG,
  1921. WRITE,
  1922. isFPRegister(
  1923. Framework::Assembly::MemoryBlockSize::M256),
  1924. VEX_VVVV,
  1925. READ,
  1926. isFPRegisterOrMEmoryAccess(
  1927. Framework::Assembly::MemoryBlockSize::M256),
  1928. MODRM_RM,
  1929. READ)}));
  1930. OperationCodeTable::machineCodeTranslationTable.add(
  1931. new OperationCodeTable(Framework::Assembly::ADDPS,
  1932. {// ADDPS xmm1, xmm2/m128
  1933. MachineCodeTableEntry(false,
  1934. 0x580F,
  1935. (char)2,
  1936. NO_PREFIX,
  1937. false,
  1938. false,
  1939. 0,
  1940. 0,
  1941. isFPRegister(
  1942. Framework::Assembly::MemoryBlockSize::M128),
  1943. MODRM_REG,
  1944. READWRITE,
  1945. isFPRegisterOrMEmoryAccess(
  1946. Framework::Assembly::MemoryBlockSize::M128),
  1947. MODRM_RM,
  1948. READ),
  1949. // VADDPS xmm1,xmm2, xmm3/m128
  1950. MachineCodeTableEntry(false,
  1951. 0x580F,
  1952. (char)2,
  1953. NO_PREFIX,
  1954. true,
  1955. false,
  1956. 0,
  1957. 0,
  1958. isFPRegister(
  1959. Framework::Assembly::MemoryBlockSize::M128),
  1960. MODRM_REG,
  1961. WRITE,
  1962. isFPRegister(
  1963. Framework::Assembly::MemoryBlockSize::M128),
  1964. VEX_VVVV,
  1965. READ,
  1966. isFPRegisterOrMEmoryAccess(
  1967. Framework::Assembly::MemoryBlockSize::M128),
  1968. MODRM_RM,
  1969. READ),
  1970. // VADDPS ymm1, ymm2, ymm3/m256
  1971. MachineCodeTableEntry(false,
  1972. 0x580F,
  1973. (char)2,
  1974. NO_PREFIX,
  1975. true,
  1976. true,
  1977. 0,
  1978. 0,
  1979. isFPRegister(
  1980. Framework::Assembly::MemoryBlockSize::M256),
  1981. MODRM_REG,
  1982. WRITE,
  1983. isFPRegister(
  1984. Framework::Assembly::MemoryBlockSize::M256),
  1985. VEX_VVVV,
  1986. READ,
  1987. isFPRegisterOrMEmoryAccess(
  1988. Framework::Assembly::MemoryBlockSize::M256),
  1989. MODRM_RM,
  1990. READ)}));
  1991. OperationCodeTable::machineCodeTranslationTable.add(
  1992. new OperationCodeTable(Framework::Assembly::ADDSD,
  1993. {// ADDSD xmm1, xmm2/m64
  1994. MachineCodeTableEntry(false,
  1995. 0x580F,
  1996. (char)2,
  1997. XF2,
  1998. false,
  1999. false,
  2000. 0,
  2001. 0,
  2002. isFPRegister(
  2003. Framework::Assembly::MemoryBlockSize::M128),
  2004. MODRM_REG,
  2005. READWRITE,
  2006. isFPRegisterOrMEmoryAccess(
  2007. Framework::Assembly::MemoryBlockSize::M128,
  2008. Framework::Assembly::MemoryBlockSize::QWORD),
  2009. MODRM_RM,
  2010. READ),
  2011. // VADDPS VADDSD xmm1, xmm2, xmm3/m64
  2012. MachineCodeTableEntry(false,
  2013. 0x580F,
  2014. (char)2,
  2015. NO_PREFIX,
  2016. true,
  2017. false,
  2018. 0b11,
  2019. 0,
  2020. isFPRegister(
  2021. Framework::Assembly::MemoryBlockSize::M128),
  2022. MODRM_REG,
  2023. WRITE,
  2024. isFPRegister(
  2025. Framework::Assembly::MemoryBlockSize::M128),
  2026. VEX_VVVV,
  2027. READ,
  2028. isFPRegisterOrMEmoryAccess(
  2029. Framework::Assembly::MemoryBlockSize::M128,
  2030. Framework::Assembly::MemoryBlockSize::QWORD),
  2031. MODRM_RM,
  2032. READ)}));
  2033. OperationCodeTable::machineCodeTranslationTable.add(
  2034. new OperationCodeTable(Framework::Assembly::ADDSS,
  2035. {// ADDPS xmm1, xmm2/m32
  2036. MachineCodeTableEntry(false,
  2037. 0x580F,
  2038. (char)2,
  2039. XF3,
  2040. false,
  2041. false,
  2042. 0,
  2043. 0,
  2044. isFPRegister(
  2045. Framework::Assembly::MemoryBlockSize::M128),
  2046. MODRM_REG,
  2047. READWRITE,
  2048. isFPRegisterOrMEmoryAccess(
  2049. Framework::Assembly::MemoryBlockSize::M128,
  2050. Framework::Assembly::MemoryBlockSize::WORD),
  2051. MODRM_RM,
  2052. READ),
  2053. // VADDPS VADDSD xmm1, xmm2, xmm3/m64
  2054. MachineCodeTableEntry(false,
  2055. 0x580F,
  2056. (char)2,
  2057. NO_PREFIX,
  2058. true,
  2059. false,
  2060. 0b10,
  2061. 0,
  2062. isFPRegister(
  2063. Framework::Assembly::MemoryBlockSize::M128),
  2064. MODRM_REG,
  2065. WRITE,
  2066. isFPRegister(
  2067. Framework::Assembly::MemoryBlockSize::M128),
  2068. VEX_VVVV,
  2069. READ,
  2070. isFPRegisterOrMEmoryAccess(
  2071. Framework::Assembly::MemoryBlockSize::M128,
  2072. Framework::Assembly::MemoryBlockSize::WORD),
  2073. MODRM_RM,
  2074. READ)}));
  2075. OperationCodeTable::machineCodeTranslationTable.add(
  2076. new OperationCodeTable(Framework::Assembly::SUB,
  2077. {
  2078. // SUB AL, imm8
  2079. MachineCodeTableEntry(false,
  2080. 0x2C,
  2081. (char)1,
  2082. NO_PREFIX,
  2083. false,
  2084. false,
  2085. 0,
  2086. 0,
  2087. isSpecificGPRegister(Framework::Assembly::RAX,
  2088. Framework::Assembly::LOWER8),
  2089. UNDEFINED,
  2090. READWRITE,
  2091. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  2092. IMM8,
  2093. READ),
  2094. // SUB AX, imm16
  2095. MachineCodeTableEntry(false,
  2096. 0x2D,
  2097. (char)1,
  2098. X66,
  2099. false,
  2100. false,
  2101. 0,
  2102. 0,
  2103. isSpecificGPRegister(Framework::Assembly::RAX,
  2104. Framework::Assembly::LOWER16),
  2105. UNDEFINED,
  2106. READWRITE,
  2107. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  2108. IMM16,
  2109. READ),
  2110. // SUB EAX, imm32
  2111. MachineCodeTableEntry(false,
  2112. 0x2D,
  2113. (char)1,
  2114. NO_PREFIX,
  2115. false,
  2116. false,
  2117. 0,
  2118. 0,
  2119. isSpecificGPRegister(Framework::Assembly::RAX,
  2120. Framework::Assembly::LOWER32),
  2121. UNDEFINED,
  2122. READWRITE,
  2123. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  2124. IMM32,
  2125. READ),
  2126. // SUB RAX, imm32
  2127. MachineCodeTableEntry(true,
  2128. 0x2D,
  2129. (char)1,
  2130. NO_PREFIX,
  2131. false,
  2132. false,
  2133. 0,
  2134. 0,
  2135. isSpecificGPRegister(Framework::Assembly::RAX,
  2136. Framework::Assembly::FULL64),
  2137. UNDEFINED,
  2138. READWRITE,
  2139. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  2140. IMM32,
  2141. READ),
  2142. // SUB r/m8, imm8
  2143. MachineCodeTableEntry(false,
  2144. 0x80,
  2145. (char)1,
  2146. NO_PREFIX,
  2147. false,
  2148. false,
  2149. 0,
  2150. 0b101,
  2151. isGPRegisterOrMemoryAccess(
  2152. Framework::Assembly::MemoryBlockSize::BYTE),
  2153. MODRM_RM,
  2154. READWRITE,
  2155. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  2156. IMM8,
  2157. READ),
  2158. // SUB r/m16, imm8
  2159. MachineCodeTableEntry(false,
  2160. 0x83,
  2161. (char)1,
  2162. X66,
  2163. false,
  2164. false,
  2165. 0,
  2166. 0b101,
  2167. isGPRegisterOrMemoryAccess(
  2168. Framework::Assembly::MemoryBlockSize::WORD),
  2169. MODRM_RM,
  2170. READWRITE,
  2171. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  2172. IMM8,
  2173. READ),
  2174. // SUB r/m32, imm8
  2175. MachineCodeTableEntry(false,
  2176. 0x83,
  2177. (char)1,
  2178. NO_PREFIX,
  2179. false,
  2180. false,
  2181. 0,
  2182. 0b101,
  2183. isGPRegisterOrMemoryAccess(
  2184. Framework::Assembly::MemoryBlockSize::DWORD),
  2185. MODRM_RM,
  2186. READWRITE,
  2187. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  2188. IMM8,
  2189. READ),
  2190. // SUB r/m64, imm8
  2191. MachineCodeTableEntry(true,
  2192. 0x83,
  2193. (char)1,
  2194. NO_PREFIX,
  2195. false,
  2196. false,
  2197. 0,
  2198. 0b101,
  2199. isGPRegisterOrMemoryAccess(
  2200. Framework::Assembly::MemoryBlockSize::QWORD),
  2201. MODRM_RM,
  2202. READWRITE,
  2203. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  2204. IMM8,
  2205. READ),
  2206. // SUB r/m16, imm16
  2207. MachineCodeTableEntry(false,
  2208. 0x81,
  2209. (char)1,
  2210. X66,
  2211. false,
  2212. false,
  2213. 0,
  2214. 0b101,
  2215. isGPRegisterOrMemoryAccess(
  2216. Framework::Assembly::MemoryBlockSize::WORD),
  2217. MODRM_RM,
  2218. READWRITE,
  2219. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  2220. IMM16,
  2221. READ),
  2222. // SUB r/m32, imm32
  2223. MachineCodeTableEntry(false,
  2224. 0x81,
  2225. (char)1,
  2226. NO_PREFIX,
  2227. false,
  2228. false,
  2229. 0,
  2230. 0b101,
  2231. isGPRegisterOrMemoryAccess(
  2232. Framework::Assembly::MemoryBlockSize::DWORD),
  2233. MODRM_RM,
  2234. READWRITE,
  2235. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  2236. IMM32,
  2237. READ),
  2238. // SUB r/m64, imm32
  2239. MachineCodeTableEntry(true,
  2240. 0x81,
  2241. (char)1,
  2242. NO_PREFIX,
  2243. false,
  2244. false,
  2245. 0,
  2246. 0b101,
  2247. isGPRegisterOrMemoryAccess(
  2248. Framework::Assembly::MemoryBlockSize::QWORD),
  2249. MODRM_RM,
  2250. READWRITE,
  2251. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  2252. IMM32,
  2253. READ),
  2254. // SUB r/m8, r8
  2255. MachineCodeTableEntry(false,
  2256. 0x28,
  2257. (char)1,
  2258. NO_PREFIX,
  2259. false,
  2260. false,
  2261. 0,
  2262. 0,
  2263. isGPRegisterOrMemoryAccess(
  2264. Framework::Assembly::MemoryBlockSize::BYTE),
  2265. MODRM_RM,
  2266. READWRITE,
  2267. isGPRegister(
  2268. Framework::Assembly::MemoryBlockSize::BYTE),
  2269. MODRM_REG,
  2270. READ),
  2271. // SUB r/m16, r16
  2272. MachineCodeTableEntry(false,
  2273. 0x29,
  2274. (char)1,
  2275. X66,
  2276. false,
  2277. false,
  2278. 0,
  2279. 0,
  2280. isGPRegisterOrMemoryAccess(
  2281. Framework::Assembly::MemoryBlockSize::WORD),
  2282. MODRM_RM,
  2283. READWRITE,
  2284. isGPRegister(
  2285. Framework::Assembly::MemoryBlockSize::WORD),
  2286. MODRM_REG,
  2287. READ),
  2288. // SUB r/m32, r32
  2289. MachineCodeTableEntry(false,
  2290. 0x29,
  2291. (char)1,
  2292. NO_PREFIX,
  2293. false,
  2294. false,
  2295. 0,
  2296. 0,
  2297. isGPRegisterOrMemoryAccess(
  2298. Framework::Assembly::MemoryBlockSize::DWORD),
  2299. MODRM_RM,
  2300. READWRITE,
  2301. isGPRegister(
  2302. Framework::Assembly::MemoryBlockSize::DWORD),
  2303. MODRM_REG,
  2304. READ),
  2305. // SUB r/m64, r64
  2306. MachineCodeTableEntry(true,
  2307. 0x29,
  2308. (char)1,
  2309. NO_PREFIX,
  2310. false,
  2311. false,
  2312. 0,
  2313. 0,
  2314. isGPRegisterOrMemoryAccess(
  2315. Framework::Assembly::MemoryBlockSize::QWORD),
  2316. MODRM_RM,
  2317. READWRITE,
  2318. isGPRegister(
  2319. Framework::Assembly::MemoryBlockSize::QWORD),
  2320. MODRM_REG,
  2321. READ),
  2322. // SUB r8, r/m8
  2323. MachineCodeTableEntry(false,
  2324. 0x2A,
  2325. (char)1,
  2326. NO_PREFIX,
  2327. false,
  2328. false,
  2329. 0,
  2330. 0,
  2331. isGPRegister(
  2332. Framework::Assembly::MemoryBlockSize::BYTE),
  2333. MODRM_REG,
  2334. READWRITE,
  2335. isGPRegisterOrMemoryAccess(
  2336. Framework::Assembly::MemoryBlockSize::BYTE),
  2337. MODRM_RM,
  2338. READ),
  2339. // SUB r16, r/m16
  2340. MachineCodeTableEntry(false,
  2341. 0x2B,
  2342. (char)1,
  2343. X66,
  2344. false,
  2345. false,
  2346. 0,
  2347. 0,
  2348. isGPRegister(
  2349. Framework::Assembly::MemoryBlockSize::WORD),
  2350. MODRM_REG,
  2351. READWRITE,
  2352. isGPRegisterOrMemoryAccess(
  2353. Framework::Assembly::MemoryBlockSize::WORD),
  2354. MODRM_RM,
  2355. READ),
  2356. // SUB r32, r/m32
  2357. MachineCodeTableEntry(false,
  2358. 0x2B,
  2359. (char)1,
  2360. NO_PREFIX,
  2361. false,
  2362. false,
  2363. 0,
  2364. 0,
  2365. isGPRegister(
  2366. Framework::Assembly::MemoryBlockSize::DWORD),
  2367. MODRM_REG,
  2368. READWRITE,
  2369. isGPRegisterOrMemoryAccess(
  2370. Framework::Assembly::MemoryBlockSize::DWORD),
  2371. MODRM_RM,
  2372. READ),
  2373. // SUB SUB r64, r/m64
  2374. MachineCodeTableEntry(true,
  2375. 0x2B,
  2376. (char)1,
  2377. NO_PREFIX,
  2378. false,
  2379. false,
  2380. 0,
  2381. 0,
  2382. isGPRegister(
  2383. Framework::Assembly::MemoryBlockSize::QWORD),
  2384. MODRM_REG,
  2385. READWRITE,
  2386. isGPRegisterOrMemoryAccess(
  2387. Framework::Assembly::MemoryBlockSize::QWORD),
  2388. MODRM_RM,
  2389. READ),
  2390. }));
  2391. OperationCodeTable::machineCodeTranslationTable.add(
  2392. new OperationCodeTable(Framework::Assembly::SUBPD,
  2393. {
  2394. // SUBPD xmm1, xmm2/m128
  2395. MachineCodeTableEntry(false,
  2396. 0x5D0F,
  2397. (char)2,
  2398. X66,
  2399. false,
  2400. false,
  2401. 0,
  2402. 0,
  2403. isFPRegister(
  2404. Framework::Assembly::MemoryBlockSize::M128),
  2405. MODRM_REG,
  2406. READWRITE,
  2407. isFPRegisterOrMEmoryAccess(
  2408. Framework::Assembly::MemoryBlockSize::M128),
  2409. MODRM_RM,
  2410. READ),
  2411. // VSUBPD xmm1,xmm2, xmm3/m128
  2412. MachineCodeTableEntry(false,
  2413. 0x5C0F,
  2414. (char)2,
  2415. NO_PREFIX,
  2416. true,
  2417. false,
  2418. 0b01,
  2419. 0,
  2420. isFPRegister(
  2421. Framework::Assembly::MemoryBlockSize::M128),
  2422. MODRM_REG,
  2423. WRITE,
  2424. isFPRegister(
  2425. Framework::Assembly::MemoryBlockSize::M128),
  2426. VEX_VVVV,
  2427. READ,
  2428. isFPRegisterOrMEmoryAccess(
  2429. Framework::Assembly::MemoryBlockSize::M128),
  2430. MODRM_RM,
  2431. READ),
  2432. // VSUBPD ymm1, ymm2, ymm3/m256
  2433. MachineCodeTableEntry(false,
  2434. 0x5C0F,
  2435. (char)2,
  2436. NO_PREFIX,
  2437. true,
  2438. true,
  2439. 0b01,
  2440. 0,
  2441. isFPRegister(
  2442. Framework::Assembly::MemoryBlockSize::M256),
  2443. MODRM_REG,
  2444. WRITE,
  2445. isFPRegister(
  2446. Framework::Assembly::MemoryBlockSize::M256),
  2447. VEX_VVVV,
  2448. READ,
  2449. isFPRegisterOrMEmoryAccess(
  2450. Framework::Assembly::MemoryBlockSize::M256),
  2451. MODRM_RM,
  2452. READ),
  2453. }));
  2454. OperationCodeTable::machineCodeTranslationTable.add(
  2455. new OperationCodeTable(Framework::Assembly::SUBPS,
  2456. {
  2457. // SUBPS xmm1, xmm2/m128
  2458. MachineCodeTableEntry(false,
  2459. 0x5D0F,
  2460. (char)2,
  2461. NO_PREFIX,
  2462. false,
  2463. false,
  2464. 0,
  2465. 0,
  2466. isFPRegister(
  2467. Framework::Assembly::MemoryBlockSize::M128),
  2468. MODRM_REG,
  2469. READWRITE,
  2470. isFPRegisterOrMEmoryAccess(
  2471. Framework::Assembly::MemoryBlockSize::M128),
  2472. MODRM_RM,
  2473. READ),
  2474. // VSUBPS xmm1,xmm2, xmm3/m128
  2475. MachineCodeTableEntry(false,
  2476. 0x5C0F,
  2477. (char)2,
  2478. NO_PREFIX,
  2479. true,
  2480. false,
  2481. 0b00,
  2482. 0,
  2483. isFPRegister(
  2484. Framework::Assembly::MemoryBlockSize::M128),
  2485. MODRM_REG,
  2486. WRITE,
  2487. isFPRegister(
  2488. Framework::Assembly::MemoryBlockSize::M128),
  2489. VEX_VVVV,
  2490. READ,
  2491. isFPRegisterOrMEmoryAccess(
  2492. Framework::Assembly::MemoryBlockSize::M128),
  2493. MODRM_RM,
  2494. READ),
  2495. // VSUBPS ymm1, ymm2, ymm3/m256
  2496. MachineCodeTableEntry(false,
  2497. 0x5C0F,
  2498. (char)2,
  2499. NO_PREFIX,
  2500. true,
  2501. true,
  2502. 0b00,
  2503. 0,
  2504. isFPRegister(
  2505. Framework::Assembly::MemoryBlockSize::M256),
  2506. MODRM_REG,
  2507. WRITE,
  2508. isFPRegister(
  2509. Framework::Assembly::MemoryBlockSize::M256),
  2510. VEX_VVVV,
  2511. READ,
  2512. isFPRegisterOrMEmoryAccess(
  2513. Framework::Assembly::MemoryBlockSize::M256),
  2514. MODRM_RM,
  2515. READ),
  2516. }));
  2517. OperationCodeTable::machineCodeTranslationTable.add(
  2518. new OperationCodeTable(Framework::Assembly::SUBSD,
  2519. {
  2520. // SUBSD xmm1, xmm2/m64
  2521. MachineCodeTableEntry(false,
  2522. 0x5C0F,
  2523. (char)2,
  2524. XF2,
  2525. false,
  2526. false,
  2527. 0,
  2528. 0,
  2529. isFPRegister(
  2530. Framework::Assembly::MemoryBlockSize::M128),
  2531. MODRM_REG,
  2532. READWRITE,
  2533. isFPRegisterOrMEmoryAccess(
  2534. Framework::Assembly::MemoryBlockSize::M128,
  2535. Framework::Assembly::MemoryBlockSize::QWORD),
  2536. MODRM_RM,
  2537. READ),
  2538. // VSUBSD xmm1,xmm2, xmm3/m64
  2539. MachineCodeTableEntry(false,
  2540. 0x5C0F,
  2541. (char)2,
  2542. NO_PREFIX,
  2543. true,
  2544. false,
  2545. 0b11,
  2546. 0,
  2547. isFPRegister(
  2548. Framework::Assembly::MemoryBlockSize::M128),
  2549. MODRM_REG,
  2550. WRITE,
  2551. isFPRegister(
  2552. Framework::Assembly::MemoryBlockSize::M128),
  2553. VEX_VVVV,
  2554. READ,
  2555. isFPRegisterOrMEmoryAccess(
  2556. Framework::Assembly::MemoryBlockSize::M128,
  2557. Framework::Assembly::MemoryBlockSize::QWORD),
  2558. MODRM_RM,
  2559. READ),
  2560. }));
  2561. OperationCodeTable::machineCodeTranslationTable.add(
  2562. new OperationCodeTable(Framework::Assembly::SUBSS,
  2563. {
  2564. // SUBSS xmm1, xmm2/m32
  2565. MachineCodeTableEntry(false,
  2566. 0x5C0F,
  2567. (char)2,
  2568. XF3,
  2569. false,
  2570. false,
  2571. 0,
  2572. 0,
  2573. isFPRegister(
  2574. Framework::Assembly::MemoryBlockSize::M128),
  2575. MODRM_REG,
  2576. READWRITE,
  2577. isFPRegisterOrMEmoryAccess(
  2578. Framework::Assembly::MemoryBlockSize::M128,
  2579. Framework::Assembly::MemoryBlockSize::DWORD),
  2580. MODRM_RM,
  2581. READ),
  2582. // VSUBSD xmm1,xmm2, xmm3/m32
  2583. MachineCodeTableEntry(false,
  2584. 0x5C0F,
  2585. (char)2,
  2586. NO_PREFIX,
  2587. true,
  2588. false,
  2589. 0b10,
  2590. 0,
  2591. isFPRegister(
  2592. Framework::Assembly::MemoryBlockSize::M128),
  2593. MODRM_REG,
  2594. WRITE,
  2595. isFPRegister(
  2596. Framework::Assembly::MemoryBlockSize::M128),
  2597. VEX_VVVV,
  2598. READ,
  2599. isFPRegisterOrMEmoryAccess(
  2600. Framework::Assembly::MemoryBlockSize::M128,
  2601. Framework::Assembly::MemoryBlockSize::DWORD),
  2602. MODRM_RM,
  2603. READ),
  2604. }));
  2605. OperationCodeTable::machineCodeTranslationTable.add(
  2606. new OperationCodeTable(Framework::Assembly::MUL,
  2607. {
  2608. // MUL r/m8
  2609. MachineCodeTableEntry(false,
  2610. 0xF6,
  2611. (char)1,
  2612. NO_PREFIX,
  2613. false,
  2614. false,
  2615. 0,
  2616. 0b100,
  2617. {Framework::Assembly::RAX},
  2618. {Framework::Assembly::RAX},
  2619. {},
  2620. {},
  2621. isGPRegisterOrMemoryAccess(
  2622. Framework::Assembly::MemoryBlockSize::BYTE),
  2623. MODRM_RM,
  2624. READ),
  2625. // MUL r/m16
  2626. MachineCodeTableEntry(false,
  2627. 0xF7,
  2628. (char)1,
  2629. X66,
  2630. false,
  2631. false,
  2632. 0,
  2633. 0b100,
  2634. {Framework::Assembly::RAX},
  2635. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  2636. {},
  2637. {},
  2638. isGPRegisterOrMemoryAccess(
  2639. Framework::Assembly::MemoryBlockSize::WORD),
  2640. MODRM_RM,
  2641. READ),
  2642. // MUL r/m32
  2643. MachineCodeTableEntry(false,
  2644. 0xF7,
  2645. (char)1,
  2646. NO_PREFIX,
  2647. false,
  2648. false,
  2649. 0,
  2650. 0b100,
  2651. {Framework::Assembly::RAX},
  2652. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  2653. {},
  2654. {},
  2655. isGPRegisterOrMemoryAccess(
  2656. Framework::Assembly::MemoryBlockSize::DWORD),
  2657. MODRM_RM,
  2658. READ),
  2659. // MUL r/m64
  2660. MachineCodeTableEntry(true,
  2661. 0xF7,
  2662. (char)1,
  2663. NO_PREFIX,
  2664. false,
  2665. false,
  2666. 0,
  2667. 0b100,
  2668. {Framework::Assembly::RAX},
  2669. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  2670. {},
  2671. {},
  2672. isGPRegisterOrMemoryAccess(
  2673. Framework::Assembly::MemoryBlockSize::QWORD),
  2674. MODRM_RM,
  2675. READ),
  2676. }));
  2677. OperationCodeTable::machineCodeTranslationTable.add(
  2678. new OperationCodeTable(Framework::Assembly::IMUL,
  2679. {
  2680. // IMUL r/m8
  2681. MachineCodeTableEntry(false,
  2682. 0xF6,
  2683. (char)1,
  2684. NO_PREFIX,
  2685. false,
  2686. false,
  2687. 0,
  2688. 0b101,
  2689. {Framework::Assembly::RAX},
  2690. {Framework::Assembly::RAX},
  2691. {},
  2692. {},
  2693. isGPRegisterOrMemoryAccess(
  2694. Framework::Assembly::MemoryBlockSize::BYTE),
  2695. MODRM_RM,
  2696. READ),
  2697. // IMUL r/m16
  2698. MachineCodeTableEntry(false,
  2699. 0xF7,
  2700. (char)1,
  2701. X66,
  2702. false,
  2703. false,
  2704. 0,
  2705. 0b101,
  2706. {Framework::Assembly::RAX},
  2707. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  2708. {},
  2709. {},
  2710. isGPRegisterOrMemoryAccess(
  2711. Framework::Assembly::MemoryBlockSize::WORD),
  2712. MODRM_RM,
  2713. READ),
  2714. // IMUL r/m32
  2715. MachineCodeTableEntry(false,
  2716. 0xF7,
  2717. (char)1,
  2718. NO_PREFIX,
  2719. false,
  2720. false,
  2721. 0,
  2722. 0b101,
  2723. {Framework::Assembly::RAX},
  2724. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  2725. {},
  2726. {},
  2727. isGPRegisterOrMemoryAccess(
  2728. Framework::Assembly::MemoryBlockSize::DWORD),
  2729. MODRM_RM,
  2730. READ),
  2731. // IMUL r/m64
  2732. MachineCodeTableEntry(true,
  2733. 0xF7,
  2734. (char)1,
  2735. NO_PREFIX,
  2736. false,
  2737. false,
  2738. 0,
  2739. 0b101,
  2740. {Framework::Assembly::RAX},
  2741. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  2742. {},
  2743. {},
  2744. isGPRegisterOrMemoryAccess(
  2745. Framework::Assembly::MemoryBlockSize::QWORD),
  2746. MODRM_RM,
  2747. READ),
  2748. // IMUL r16, r/m16
  2749. MachineCodeTableEntry(false,
  2750. 0xAF0F,
  2751. (char)2,
  2752. X66,
  2753. false,
  2754. false,
  2755. 0,
  2756. 0,
  2757. isGPRegister(
  2758. Framework::Assembly::MemoryBlockSize::WORD),
  2759. MODRM_REG,
  2760. READWRITE,
  2761. isGPRegisterOrMemoryAccess(
  2762. Framework::Assembly::MemoryBlockSize::WORD),
  2763. MODRM_RM,
  2764. READ),
  2765. // IMUL r32, r/m32
  2766. MachineCodeTableEntry(false,
  2767. 0xAF0F,
  2768. (char)2,
  2769. NO_PREFIX,
  2770. false,
  2771. false,
  2772. 0,
  2773. 0,
  2774. isGPRegister(
  2775. Framework::Assembly::MemoryBlockSize::DWORD),
  2776. MODRM_REG,
  2777. READWRITE,
  2778. isGPRegisterOrMemoryAccess(
  2779. Framework::Assembly::MemoryBlockSize::DWORD),
  2780. MODRM_RM,
  2781. READ),
  2782. // IMUL r64, r/m64
  2783. MachineCodeTableEntry(true,
  2784. 0xAF0F,
  2785. (char)2,
  2786. NO_PREFIX,
  2787. false,
  2788. false,
  2789. 0,
  2790. 0,
  2791. isGPRegister(
  2792. Framework::Assembly::MemoryBlockSize::QWORD),
  2793. MODRM_REG,
  2794. READWRITE,
  2795. isGPRegisterOrMemoryAccess(
  2796. Framework::Assembly::MemoryBlockSize::QWORD),
  2797. MODRM_RM,
  2798. READ),
  2799. // IMUL r16, r/m16, imm8
  2800. MachineCodeTableEntry(false,
  2801. 0x6B,
  2802. (char)1,
  2803. X66,
  2804. false,
  2805. false,
  2806. 0,
  2807. 0,
  2808. isGPRegister(
  2809. Framework::Assembly::MemoryBlockSize::WORD),
  2810. MODRM_REG,
  2811. WRITE,
  2812. isGPRegisterOrMemoryAccess(
  2813. Framework::Assembly::MemoryBlockSize::WORD),
  2814. MODRM_RM,
  2815. READ,
  2816. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  2817. IMM8,
  2818. READ),
  2819. // IMUL r32, r/m32, imm8
  2820. MachineCodeTableEntry(false,
  2821. 0x6B,
  2822. (char)1,
  2823. NO_PREFIX,
  2824. false,
  2825. false,
  2826. 0,
  2827. 0,
  2828. isGPRegister(
  2829. Framework::Assembly::MemoryBlockSize::DWORD),
  2830. MODRM_REG,
  2831. READWRITE,
  2832. isGPRegisterOrMemoryAccess(
  2833. Framework::Assembly::MemoryBlockSize::DWORD),
  2834. MODRM_RM,
  2835. READ,
  2836. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  2837. IMM8,
  2838. READ),
  2839. // IMUL r64, r/m64, imm8
  2840. MachineCodeTableEntry(true,
  2841. 0x6B,
  2842. (char)1,
  2843. NO_PREFIX,
  2844. false,
  2845. false,
  2846. 0,
  2847. 0,
  2848. isGPRegister(
  2849. Framework::Assembly::MemoryBlockSize::QWORD),
  2850. MODRM_REG,
  2851. READWRITE,
  2852. isGPRegisterOrMemoryAccess(
  2853. Framework::Assembly::MemoryBlockSize::QWORD),
  2854. MODRM_RM,
  2855. READ,
  2856. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  2857. IMM8,
  2858. READ),
  2859. // IMUL r16, r/m16, imm16
  2860. MachineCodeTableEntry(false,
  2861. 0x69,
  2862. (char)1,
  2863. X66,
  2864. false,
  2865. false,
  2866. 0,
  2867. 0,
  2868. isGPRegister(
  2869. Framework::Assembly::MemoryBlockSize::WORD),
  2870. MODRM_REG,
  2871. WRITE,
  2872. isGPRegisterOrMemoryAccess(
  2873. Framework::Assembly::MemoryBlockSize::WORD),
  2874. MODRM_RM,
  2875. READ,
  2876. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  2877. IMM16,
  2878. READ),
  2879. // IMUL r32, r/m32, imm32
  2880. MachineCodeTableEntry(false,
  2881. 0x69,
  2882. (char)1,
  2883. NO_PREFIX,
  2884. false,
  2885. false,
  2886. 0,
  2887. 0,
  2888. isGPRegister(
  2889. Framework::Assembly::MemoryBlockSize::DWORD),
  2890. MODRM_REG,
  2891. READWRITE,
  2892. isGPRegisterOrMemoryAccess(
  2893. Framework::Assembly::MemoryBlockSize::DWORD),
  2894. MODRM_RM,
  2895. READ,
  2896. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  2897. IMM32,
  2898. READ),
  2899. // IMUL r64, r/m64
  2900. MachineCodeTableEntry(true,
  2901. 0x69,
  2902. (char)1,
  2903. NO_PREFIX,
  2904. false,
  2905. false,
  2906. 0,
  2907. 0,
  2908. isGPRegister(
  2909. Framework::Assembly::MemoryBlockSize::QWORD),
  2910. MODRM_REG,
  2911. READWRITE,
  2912. isGPRegisterOrMemoryAccess(
  2913. Framework::Assembly::MemoryBlockSize::QWORD),
  2914. MODRM_RM,
  2915. READ,
  2916. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  2917. IMM32,
  2918. READ),
  2919. }));
  2920. OperationCodeTable::machineCodeTranslationTable.add(
  2921. new OperationCodeTable(Framework::Assembly::MULPD,
  2922. {
  2923. // MULPD xmm1, xmm2/m128
  2924. MachineCodeTableEntry(false,
  2925. 0x590F,
  2926. (char)2,
  2927. X66,
  2928. false,
  2929. false,
  2930. 0,
  2931. 0,
  2932. isFPRegister(
  2933. Framework::Assembly::MemoryBlockSize::M128),
  2934. MODRM_REG,
  2935. READWRITE,
  2936. isFPRegisterOrMEmoryAccess(
  2937. Framework::Assembly::MemoryBlockSize::M128),
  2938. MODRM_RM,
  2939. READ),
  2940. // VMULPD xmm1,xmm2, xmm3/m128
  2941. MachineCodeTableEntry(false,
  2942. 0x590F,
  2943. (char)2,
  2944. NO_PREFIX,
  2945. true,
  2946. false,
  2947. 0b01,
  2948. 0,
  2949. isFPRegister(
  2950. Framework::Assembly::MemoryBlockSize::M128),
  2951. MODRM_REG,
  2952. WRITE,
  2953. isFPRegister(
  2954. Framework::Assembly::MemoryBlockSize::M128),
  2955. VEX_VVVV,
  2956. READ,
  2957. isFPRegisterOrMEmoryAccess(
  2958. Framework::Assembly::MemoryBlockSize::M128),
  2959. MODRM_RM,
  2960. READ),
  2961. // VMULPD ymm1, ymm2, ymm3/m256
  2962. MachineCodeTableEntry(false,
  2963. 0x590F,
  2964. (char)2,
  2965. NO_PREFIX,
  2966. true,
  2967. true,
  2968. 0b01,
  2969. 0,
  2970. isFPRegister(
  2971. Framework::Assembly::MemoryBlockSize::M256),
  2972. MODRM_REG,
  2973. WRITE,
  2974. isFPRegister(
  2975. Framework::Assembly::MemoryBlockSize::M256),
  2976. VEX_VVVV,
  2977. READ,
  2978. isFPRegisterOrMEmoryAccess(
  2979. Framework::Assembly::MemoryBlockSize::M256),
  2980. MODRM_RM,
  2981. READ),
  2982. }));
  2983. OperationCodeTable::machineCodeTranslationTable.add(
  2984. new OperationCodeTable(Framework::Assembly::MULPS,
  2985. {
  2986. // MULPS xmm1, xmm2/m128
  2987. MachineCodeTableEntry(false,
  2988. 0x590F,
  2989. (char)2,
  2990. NO_PREFIX,
  2991. false,
  2992. false,
  2993. 0,
  2994. 0,
  2995. isFPRegister(
  2996. Framework::Assembly::MemoryBlockSize::M128),
  2997. MODRM_REG,
  2998. READWRITE,
  2999. isFPRegisterOrMEmoryAccess(
  3000. Framework::Assembly::MemoryBlockSize::M128),
  3001. MODRM_RM,
  3002. READ),
  3003. // VMULPS xmm1,xmm2, xmm3/m128
  3004. MachineCodeTableEntry(false,
  3005. 0x590F,
  3006. (char)2,
  3007. NO_PREFIX,
  3008. true,
  3009. false,
  3010. 0,
  3011. 0,
  3012. isFPRegister(
  3013. Framework::Assembly::MemoryBlockSize::M128),
  3014. MODRM_REG,
  3015. WRITE,
  3016. isFPRegister(
  3017. Framework::Assembly::MemoryBlockSize::M128),
  3018. VEX_VVVV,
  3019. READ,
  3020. isFPRegisterOrMEmoryAccess(
  3021. Framework::Assembly::MemoryBlockSize::M128),
  3022. MODRM_RM,
  3023. READ),
  3024. // VMULPS ymm1, ymm2, ymm3/m256
  3025. MachineCodeTableEntry(false,
  3026. 0x590F,
  3027. (char)2,
  3028. NO_PREFIX,
  3029. true,
  3030. true,
  3031. 0,
  3032. 0,
  3033. isFPRegister(
  3034. Framework::Assembly::MemoryBlockSize::M256),
  3035. MODRM_REG,
  3036. WRITE,
  3037. isFPRegister(
  3038. Framework::Assembly::MemoryBlockSize::M256),
  3039. VEX_VVVV,
  3040. READ,
  3041. isFPRegisterOrMEmoryAccess(
  3042. Framework::Assembly::MemoryBlockSize::M256),
  3043. MODRM_RM,
  3044. READ),
  3045. }));
  3046. OperationCodeTable::machineCodeTranslationTable.add(
  3047. new OperationCodeTable(Framework::Assembly::MULSD,
  3048. {
  3049. // MULSD xmm1,xmm2/m64
  3050. MachineCodeTableEntry(false,
  3051. 0x590F,
  3052. (char)2,
  3053. XF2,
  3054. false,
  3055. false,
  3056. 0,
  3057. 0,
  3058. isFPRegister(
  3059. Framework::Assembly::MemoryBlockSize::M128),
  3060. MODRM_REG,
  3061. READWRITE,
  3062. isFPRegisterOrMEmoryAccess(
  3063. Framework::Assembly::MemoryBlockSize::M128),
  3064. MODRM_RM,
  3065. READ),
  3066. // VMULSD xmm1,xmm2, xmm3/m128
  3067. MachineCodeTableEntry(false,
  3068. 0x590F,
  3069. (char)2,
  3070. NO_PREFIX,
  3071. true,
  3072. false,
  3073. 0b11,
  3074. 0,
  3075. isFPRegister(
  3076. Framework::Assembly::MemoryBlockSize::M128),
  3077. MODRM_REG,
  3078. WRITE,
  3079. isFPRegister(
  3080. Framework::Assembly::MemoryBlockSize::M128),
  3081. VEX_VVVV,
  3082. READ,
  3083. isFPRegisterOrMEmoryAccess(
  3084. Framework::Assembly::MemoryBlockSize::M128),
  3085. MODRM_RM,
  3086. READ),
  3087. }));
  3088. OperationCodeTable::machineCodeTranslationTable.add(
  3089. new OperationCodeTable(Framework::Assembly::MULSS,
  3090. {
  3091. // MULSS xmm1,xmm2/m64
  3092. MachineCodeTableEntry(false,
  3093. 0x590F,
  3094. (char)2,
  3095. XF3,
  3096. false,
  3097. false,
  3098. 0,
  3099. 0,
  3100. isFPRegister(
  3101. Framework::Assembly::MemoryBlockSize::M128),
  3102. MODRM_REG,
  3103. READWRITE,
  3104. isFPRegisterOrMEmoryAccess(
  3105. Framework::Assembly::MemoryBlockSize::M128),
  3106. MODRM_RM,
  3107. READ),
  3108. // VMULSS xmm1,xmm2, xmm3/m128
  3109. MachineCodeTableEntry(false,
  3110. 0x590F,
  3111. (char)2,
  3112. NO_PREFIX,
  3113. true,
  3114. false,
  3115. 0b10,
  3116. 0,
  3117. isFPRegister(
  3118. Framework::Assembly::MemoryBlockSize::M128),
  3119. MODRM_REG,
  3120. WRITE,
  3121. isFPRegister(
  3122. Framework::Assembly::MemoryBlockSize::M128),
  3123. VEX_VVVV,
  3124. READ,
  3125. isFPRegisterOrMEmoryAccess(
  3126. Framework::Assembly::MemoryBlockSize::M128),
  3127. MODRM_RM,
  3128. READ),
  3129. }));
  3130. OperationCodeTable::machineCodeTranslationTable.add(
  3131. new OperationCodeTable(Framework::Assembly::DIV,
  3132. {
  3133. // DIV r/m8
  3134. MachineCodeTableEntry(false,
  3135. 0xF6,
  3136. (char)1,
  3137. NO_PREFIX,
  3138. false,
  3139. false,
  3140. 0,
  3141. 0b110,
  3142. {Framework::Assembly::RAX},
  3143. {Framework::Assembly::RAX},
  3144. {},
  3145. {},
  3146. isGPRegisterOrMemoryAccess(
  3147. Framework::Assembly::MemoryBlockSize::BYTE),
  3148. MODRM_RM,
  3149. READ),
  3150. // DIV r/m16
  3151. MachineCodeTableEntry(false,
  3152. 0xF7,
  3153. (char)1,
  3154. X66,
  3155. false,
  3156. false,
  3157. 0,
  3158. 0b110,
  3159. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3160. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3161. {},
  3162. {},
  3163. isGPRegisterOrMemoryAccess(
  3164. Framework::Assembly::MemoryBlockSize::WORD),
  3165. MODRM_RM,
  3166. READ),
  3167. // DIV r/m32
  3168. MachineCodeTableEntry(false,
  3169. 0xF7,
  3170. (char)1,
  3171. NO_PREFIX,
  3172. false,
  3173. false,
  3174. 0,
  3175. 0b110,
  3176. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3177. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3178. {},
  3179. {},
  3180. isGPRegisterOrMemoryAccess(
  3181. Framework::Assembly::MemoryBlockSize::DWORD),
  3182. MODRM_RM,
  3183. READ),
  3184. // DIV r/m64
  3185. MachineCodeTableEntry(true,
  3186. 0xF7,
  3187. (char)1,
  3188. NO_PREFIX,
  3189. false,
  3190. false,
  3191. 0,
  3192. 0b110,
  3193. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3194. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3195. {},
  3196. {},
  3197. isGPRegisterOrMemoryAccess(
  3198. Framework::Assembly::MemoryBlockSize::QWORD),
  3199. MODRM_RM,
  3200. READ),
  3201. }));
  3202. OperationCodeTable::machineCodeTranslationTable.add(
  3203. new OperationCodeTable(Framework::Assembly::IDIV,
  3204. {
  3205. // IDIV r/m8
  3206. MachineCodeTableEntry(false,
  3207. 0xF6,
  3208. (char)1,
  3209. NO_PREFIX,
  3210. false,
  3211. false,
  3212. 0,
  3213. 0b111,
  3214. {Framework::Assembly::RAX},
  3215. {Framework::Assembly::RAX},
  3216. {},
  3217. {},
  3218. isGPRegisterOrMemoryAccess(
  3219. Framework::Assembly::MemoryBlockSize::BYTE),
  3220. MODRM_RM,
  3221. READ),
  3222. // IDIV r/m16
  3223. MachineCodeTableEntry(false,
  3224. 0xF7,
  3225. (char)1,
  3226. X66,
  3227. false,
  3228. false,
  3229. 0,
  3230. 0b111,
  3231. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3232. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3233. {},
  3234. {},
  3235. isGPRegisterOrMemoryAccess(
  3236. Framework::Assembly::MemoryBlockSize::WORD),
  3237. MODRM_RM,
  3238. READ),
  3239. // IDIV r/m32
  3240. MachineCodeTableEntry(false,
  3241. 0xF7,
  3242. (char)1,
  3243. NO_PREFIX,
  3244. false,
  3245. false,
  3246. 0,
  3247. 0b111,
  3248. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3249. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3250. {},
  3251. {},
  3252. isGPRegisterOrMemoryAccess(
  3253. Framework::Assembly::MemoryBlockSize::DWORD),
  3254. MODRM_RM,
  3255. READ),
  3256. // IDIV r/m64
  3257. MachineCodeTableEntry(true,
  3258. 0xF7,
  3259. (char)1,
  3260. NO_PREFIX,
  3261. false,
  3262. false,
  3263. 0,
  3264. 0b111,
  3265. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3266. {Framework::Assembly::RAX, Framework::Assembly::RDX},
  3267. {},
  3268. {},
  3269. isGPRegisterOrMemoryAccess(
  3270. Framework::Assembly::MemoryBlockSize::QWORD),
  3271. MODRM_RM,
  3272. READ),
  3273. }));
  3274. OperationCodeTable::machineCodeTranslationTable.add(
  3275. new OperationCodeTable(Framework::Assembly::DIVPD,
  3276. {
  3277. // DIVPD xmm1, xmm2/m128
  3278. MachineCodeTableEntry(false,
  3279. 0x5E0F,
  3280. (char)2,
  3281. X66,
  3282. false,
  3283. false,
  3284. 0,
  3285. 0,
  3286. isFPRegister(
  3287. Framework::Assembly::MemoryBlockSize::M128),
  3288. MODRM_REG,
  3289. READWRITE,
  3290. isFPRegisterOrMEmoryAccess(
  3291. Framework::Assembly::MemoryBlockSize::M128),
  3292. MODRM_RM,
  3293. READ),
  3294. // VDIVPD xmm1,xmm2, xmm3/m128
  3295. MachineCodeTableEntry(false,
  3296. 0x5E0F,
  3297. (char)2,
  3298. NO_PREFIX,
  3299. true,
  3300. false,
  3301. 0b01,
  3302. 0,
  3303. isFPRegister(
  3304. Framework::Assembly::MemoryBlockSize::M128),
  3305. MODRM_REG,
  3306. WRITE,
  3307. isFPRegister(
  3308. Framework::Assembly::MemoryBlockSize::M128),
  3309. VEX_VVVV,
  3310. READ,
  3311. isFPRegisterOrMEmoryAccess(
  3312. Framework::Assembly::MemoryBlockSize::M128),
  3313. MODRM_RM,
  3314. READ),
  3315. // VDIVPD ymm1, ymm2, ymm3/m256
  3316. MachineCodeTableEntry(false,
  3317. 0x5E0F,
  3318. (char)2,
  3319. NO_PREFIX,
  3320. true,
  3321. true,
  3322. 0b01,
  3323. 0,
  3324. isFPRegister(
  3325. Framework::Assembly::MemoryBlockSize::M256),
  3326. MODRM_REG,
  3327. WRITE,
  3328. isFPRegister(
  3329. Framework::Assembly::MemoryBlockSize::M256),
  3330. VEX_VVVV,
  3331. READ,
  3332. isFPRegisterOrMEmoryAccess(
  3333. Framework::Assembly::MemoryBlockSize::M256),
  3334. MODRM_RM,
  3335. READ),
  3336. }));
  3337. OperationCodeTable::machineCodeTranslationTable.add(
  3338. new OperationCodeTable(Framework::Assembly::DIVPS,
  3339. {
  3340. // DIVPS xmm1, xmm2/m128
  3341. MachineCodeTableEntry(false,
  3342. 0x5E0F,
  3343. (char)2,
  3344. NO_PREFIX,
  3345. false,
  3346. false,
  3347. 0,
  3348. 0,
  3349. isFPRegister(
  3350. Framework::Assembly::MemoryBlockSize::M128),
  3351. MODRM_REG,
  3352. READWRITE,
  3353. isFPRegisterOrMEmoryAccess(
  3354. Framework::Assembly::MemoryBlockSize::M128),
  3355. MODRM_RM,
  3356. READ),
  3357. // VDIVPS xmm1,xmm2, xmm3/m128
  3358. MachineCodeTableEntry(false,
  3359. 0x5E0F,
  3360. (char)2,
  3361. NO_PREFIX,
  3362. true,
  3363. false,
  3364. 0,
  3365. 0,
  3366. isFPRegister(
  3367. Framework::Assembly::MemoryBlockSize::M128),
  3368. MODRM_REG,
  3369. WRITE,
  3370. isFPRegister(
  3371. Framework::Assembly::MemoryBlockSize::M128),
  3372. VEX_VVVV,
  3373. READ,
  3374. isFPRegisterOrMEmoryAccess(
  3375. Framework::Assembly::MemoryBlockSize::M128),
  3376. MODRM_RM,
  3377. READ),
  3378. // VDIVPS ymm1, ymm2, ymm3/m256
  3379. MachineCodeTableEntry(false,
  3380. 0x5E0F,
  3381. (char)2,
  3382. NO_PREFIX,
  3383. true,
  3384. true,
  3385. 0,
  3386. 0,
  3387. isFPRegister(
  3388. Framework::Assembly::MemoryBlockSize::M256),
  3389. MODRM_REG,
  3390. WRITE,
  3391. isFPRegister(
  3392. Framework::Assembly::MemoryBlockSize::M256),
  3393. VEX_VVVV,
  3394. READ,
  3395. isFPRegisterOrMEmoryAccess(
  3396. Framework::Assembly::MemoryBlockSize::M256),
  3397. MODRM_RM,
  3398. READ),
  3399. }));
  3400. OperationCodeTable::machineCodeTranslationTable.add(
  3401. new OperationCodeTable(Framework::Assembly::DIVSD,
  3402. {
  3403. // DIVSD xmm1, xmm2/m128
  3404. MachineCodeTableEntry(false,
  3405. 0x5E0F,
  3406. (char)2,
  3407. XF2,
  3408. false,
  3409. false,
  3410. 0,
  3411. 0,
  3412. isFPRegister(
  3413. Framework::Assembly::MemoryBlockSize::M128),
  3414. MODRM_REG,
  3415. READWRITE,
  3416. isFPRegisterOrMEmoryAccess(
  3417. Framework::Assembly::MemoryBlockSize::M128),
  3418. MODRM_RM,
  3419. READ),
  3420. // VDIVSD xmm1,xmm2, xmm3/m128
  3421. MachineCodeTableEntry(false,
  3422. 0x5E0F,
  3423. (char)2,
  3424. NO_PREFIX,
  3425. true,
  3426. false,
  3427. 0b11,
  3428. 0,
  3429. isFPRegister(
  3430. Framework::Assembly::MemoryBlockSize::M128),
  3431. MODRM_REG,
  3432. WRITE,
  3433. isFPRegister(
  3434. Framework::Assembly::MemoryBlockSize::M128),
  3435. VEX_VVVV,
  3436. READ,
  3437. isFPRegisterOrMEmoryAccess(
  3438. Framework::Assembly::MemoryBlockSize::M128),
  3439. MODRM_RM,
  3440. READ),
  3441. }));
  3442. OperationCodeTable::machineCodeTranslationTable.add(
  3443. new OperationCodeTable(Framework::Assembly::DIVSS,
  3444. {
  3445. // DIVSS xmm1, xmm2/m128
  3446. MachineCodeTableEntry(false,
  3447. 0x5E0F,
  3448. (char)2,
  3449. XF3,
  3450. false,
  3451. false,
  3452. 0,
  3453. 0,
  3454. isFPRegister(
  3455. Framework::Assembly::MemoryBlockSize::M128),
  3456. MODRM_REG,
  3457. READWRITE,
  3458. isFPRegisterOrMEmoryAccess(
  3459. Framework::Assembly::MemoryBlockSize::M128),
  3460. MODRM_RM,
  3461. READ),
  3462. // VDIVSS xmm1,xmm2, xmm3/m128
  3463. MachineCodeTableEntry(false,
  3464. 0x5E0F,
  3465. (char)2,
  3466. NO_PREFIX,
  3467. true,
  3468. false,
  3469. 0b10,
  3470. 0,
  3471. isFPRegister(
  3472. Framework::Assembly::MemoryBlockSize::M128),
  3473. MODRM_REG,
  3474. WRITE,
  3475. isFPRegister(
  3476. Framework::Assembly::MemoryBlockSize::M128),
  3477. VEX_VVVV,
  3478. READ,
  3479. isFPRegisterOrMEmoryAccess(
  3480. Framework::Assembly::MemoryBlockSize::M128),
  3481. MODRM_RM,
  3482. READ),
  3483. }));
  3484. OperationCodeTable::machineCodeTranslationTable.add(
  3485. new OperationCodeTable(Framework::Assembly::NEG,
  3486. {
  3487. // NEG r/m8
  3488. MachineCodeTableEntry(false,
  3489. 0xF6,
  3490. (char)1,
  3491. NO_PREFIX,
  3492. false,
  3493. false,
  3494. 0,
  3495. 0b011,
  3496. isGPRegisterOrMemoryAccess(
  3497. Framework::Assembly::MemoryBlockSize::BYTE),
  3498. MODRM_RM,
  3499. READWRITE),
  3500. // NEG r/m16
  3501. MachineCodeTableEntry(false,
  3502. 0xF7,
  3503. (char)1,
  3504. X66,
  3505. false,
  3506. false,
  3507. 0,
  3508. 0b011,
  3509. isGPRegisterOrMemoryAccess(
  3510. Framework::Assembly::MemoryBlockSize::WORD),
  3511. MODRM_RM,
  3512. READWRITE),
  3513. // NEG r/m32
  3514. MachineCodeTableEntry(false,
  3515. 0xF7,
  3516. (char)1,
  3517. NO_PREFIX,
  3518. false,
  3519. false,
  3520. 0,
  3521. 0b011,
  3522. isGPRegisterOrMemoryAccess(
  3523. Framework::Assembly::MemoryBlockSize::DWORD),
  3524. MODRM_RM,
  3525. READWRITE),
  3526. // NEG r/m64
  3527. MachineCodeTableEntry(true,
  3528. 0xF7,
  3529. (char)1,
  3530. NO_PREFIX,
  3531. false,
  3532. false,
  3533. 0,
  3534. 0b011,
  3535. isGPRegisterOrMemoryAccess(
  3536. Framework::Assembly::MemoryBlockSize::QWORD),
  3537. MODRM_RM,
  3538. READWRITE),
  3539. }));
  3540. OperationCodeTable::machineCodeTranslationTable.add(
  3541. new OperationCodeTable(Framework::Assembly::INC,
  3542. {
  3543. // INC r/m8
  3544. MachineCodeTableEntry(false,
  3545. 0xFE,
  3546. (char)1,
  3547. NO_PREFIX,
  3548. false,
  3549. false,
  3550. 0,
  3551. 0,
  3552. isGPRegisterOrMemoryAccess(
  3553. Framework::Assembly::MemoryBlockSize::BYTE),
  3554. MODRM_RM,
  3555. READWRITE),
  3556. // INC r/m16
  3557. MachineCodeTableEntry(false,
  3558. 0xF7,
  3559. (char)1,
  3560. X66,
  3561. false,
  3562. false,
  3563. 0,
  3564. 0,
  3565. isGPRegisterOrMemoryAccess(
  3566. Framework::Assembly::MemoryBlockSize::WORD),
  3567. MODRM_RM,
  3568. READWRITE),
  3569. // INC r/m32
  3570. MachineCodeTableEntry(false,
  3571. 0xF7,
  3572. (char)1,
  3573. NO_PREFIX,
  3574. false,
  3575. false,
  3576. 0,
  3577. 0,
  3578. isGPRegisterOrMemoryAccess(
  3579. Framework::Assembly::MemoryBlockSize::DWORD),
  3580. MODRM_RM,
  3581. READWRITE),
  3582. // INC r/m64
  3583. MachineCodeTableEntry(true,
  3584. 0xF7,
  3585. (char)1,
  3586. NO_PREFIX,
  3587. false,
  3588. false,
  3589. 0,
  3590. 0,
  3591. isGPRegisterOrMemoryAccess(
  3592. Framework::Assembly::MemoryBlockSize::QWORD),
  3593. MODRM_RM,
  3594. READWRITE),
  3595. }));
  3596. OperationCodeTable::machineCodeTranslationTable.add(
  3597. new OperationCodeTable(Framework::Assembly::AND,
  3598. {
  3599. // AND AL, imm8
  3600. MachineCodeTableEntry(false,
  3601. 0x24,
  3602. (char)1,
  3603. NO_PREFIX,
  3604. false,
  3605. false,
  3606. 0,
  3607. 0,
  3608. isSpecificGPRegister(Framework::Assembly::RAX,
  3609. Framework::Assembly::LOWER8),
  3610. UNDEFINED,
  3611. READWRITE,
  3612. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  3613. IMM8,
  3614. READ),
  3615. // AND AX, imm16
  3616. MachineCodeTableEntry(false,
  3617. 0x25,
  3618. (char)1,
  3619. X66,
  3620. false,
  3621. false,
  3622. 0,
  3623. 0,
  3624. isSpecificGPRegister(Framework::Assembly::RAX,
  3625. Framework::Assembly::LOWER16),
  3626. UNDEFINED,
  3627. READWRITE,
  3628. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  3629. IMM16,
  3630. READ),
  3631. // AND EAX, imm32
  3632. MachineCodeTableEntry(false,
  3633. 0x25,
  3634. (char)1,
  3635. NO_PREFIX,
  3636. false,
  3637. false,
  3638. 0,
  3639. 0,
  3640. isSpecificGPRegister(Framework::Assembly::RAX,
  3641. Framework::Assembly::LOWER32),
  3642. UNDEFINED,
  3643. READWRITE,
  3644. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  3645. IMM32,
  3646. READ),
  3647. // AND RAX, imm32
  3648. MachineCodeTableEntry(true,
  3649. 0x25,
  3650. (char)1,
  3651. NO_PREFIX,
  3652. false,
  3653. false,
  3654. 0,
  3655. 0,
  3656. isSpecificGPRegister(Framework::Assembly::RAX,
  3657. Framework::Assembly::FULL64),
  3658. UNDEFINED,
  3659. READWRITE,
  3660. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  3661. IMM32,
  3662. READ),
  3663. // AND r/m8, imm8
  3664. MachineCodeTableEntry(false,
  3665. 0x80,
  3666. (char)1,
  3667. NO_PREFIX,
  3668. false,
  3669. false,
  3670. 0,
  3671. 0b100,
  3672. isGPRegisterOrMemoryAccess(
  3673. Framework::Assembly::MemoryBlockSize::BYTE),
  3674. MODRM_RM,
  3675. READWRITE,
  3676. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  3677. IMM8,
  3678. READ),
  3679. // AND r/m16, imm8
  3680. MachineCodeTableEntry(false,
  3681. 0x83,
  3682. (char)1,
  3683. X66,
  3684. false,
  3685. false,
  3686. 0,
  3687. 0b100,
  3688. isGPRegisterOrMemoryAccess(
  3689. Framework::Assembly::MemoryBlockSize::WORD),
  3690. MODRM_RM,
  3691. READWRITE,
  3692. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  3693. IMM8,
  3694. READ),
  3695. // AND r/m32, imm8
  3696. MachineCodeTableEntry(false,
  3697. 0x83,
  3698. (char)1,
  3699. NO_PREFIX,
  3700. false,
  3701. false,
  3702. 0,
  3703. 0b100,
  3704. isGPRegisterOrMemoryAccess(
  3705. Framework::Assembly::MemoryBlockSize::DWORD),
  3706. MODRM_RM,
  3707. READWRITE,
  3708. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  3709. IMM8,
  3710. READ),
  3711. // AND r/m64, imm8
  3712. MachineCodeTableEntry(true,
  3713. 0x83,
  3714. (char)1,
  3715. NO_PREFIX,
  3716. false,
  3717. false,
  3718. 0,
  3719. 0b100,
  3720. isGPRegisterOrMemoryAccess(
  3721. Framework::Assembly::MemoryBlockSize::QWORD),
  3722. MODRM_RM,
  3723. READWRITE,
  3724. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  3725. IMM8,
  3726. READ),
  3727. // AND r/m16, imm16
  3728. MachineCodeTableEntry(false,
  3729. 0x81,
  3730. (char)1,
  3731. X66,
  3732. false,
  3733. false,
  3734. 0,
  3735. 0b100,
  3736. isGPRegisterOrMemoryAccess(
  3737. Framework::Assembly::MemoryBlockSize::WORD),
  3738. MODRM_RM,
  3739. READWRITE,
  3740. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  3741. IMM16,
  3742. READ),
  3743. // AND r/m32, imm32
  3744. MachineCodeTableEntry(false,
  3745. 0x81,
  3746. (char)1,
  3747. NO_PREFIX,
  3748. false,
  3749. false,
  3750. 0,
  3751. 0b100,
  3752. isGPRegisterOrMemoryAccess(
  3753. Framework::Assembly::MemoryBlockSize::DWORD),
  3754. MODRM_RM,
  3755. READWRITE,
  3756. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  3757. IMM32,
  3758. READ),
  3759. // AND r/m64, imm32
  3760. MachineCodeTableEntry(true,
  3761. 0x81,
  3762. (char)1,
  3763. NO_PREFIX,
  3764. false,
  3765. false,
  3766. 0,
  3767. 0b100,
  3768. isGPRegisterOrMemoryAccess(
  3769. Framework::Assembly::MemoryBlockSize::QWORD),
  3770. MODRM_RM,
  3771. READWRITE,
  3772. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  3773. IMM32,
  3774. READ),
  3775. // AND r/m8, r8
  3776. MachineCodeTableEntry(false,
  3777. 0x20,
  3778. (char)1,
  3779. NO_PREFIX,
  3780. false,
  3781. false,
  3782. 0,
  3783. 0,
  3784. isGPRegisterOrMemoryAccess(
  3785. Framework::Assembly::MemoryBlockSize::BYTE),
  3786. MODRM_RM,
  3787. READWRITE,
  3788. isGPRegister(
  3789. Framework::Assembly::MemoryBlockSize::BYTE),
  3790. MODRM_REG,
  3791. READ),
  3792. // AND r/m16, r16
  3793. MachineCodeTableEntry(false,
  3794. 0x21,
  3795. (char)1,
  3796. X66,
  3797. false,
  3798. false,
  3799. 0,
  3800. 0,
  3801. isGPRegisterOrMemoryAccess(
  3802. Framework::Assembly::MemoryBlockSize::WORD),
  3803. MODRM_RM,
  3804. READWRITE,
  3805. isGPRegister(
  3806. Framework::Assembly::MemoryBlockSize::WORD),
  3807. MODRM_REG,
  3808. READ),
  3809. // AND r/m32, r32
  3810. MachineCodeTableEntry(false,
  3811. 0x21,
  3812. (char)1,
  3813. NO_PREFIX,
  3814. false,
  3815. false,
  3816. 0,
  3817. 0,
  3818. isGPRegisterOrMemoryAccess(
  3819. Framework::Assembly::MemoryBlockSize::DWORD),
  3820. MODRM_RM,
  3821. READWRITE,
  3822. isGPRegister(
  3823. Framework::Assembly::MemoryBlockSize::DWORD),
  3824. MODRM_REG,
  3825. READ),
  3826. // AND r/m64, r64
  3827. MachineCodeTableEntry(true,
  3828. 0x21,
  3829. (char)1,
  3830. NO_PREFIX,
  3831. false,
  3832. false,
  3833. 0,
  3834. 0,
  3835. isGPRegisterOrMemoryAccess(
  3836. Framework::Assembly::MemoryBlockSize::QWORD),
  3837. MODRM_RM,
  3838. READWRITE,
  3839. isGPRegister(
  3840. Framework::Assembly::MemoryBlockSize::QWORD),
  3841. MODRM_REG,
  3842. READ),
  3843. // AND r8, r/m8
  3844. MachineCodeTableEntry(false,
  3845. 0x22,
  3846. (char)1,
  3847. NO_PREFIX,
  3848. false,
  3849. false,
  3850. 0,
  3851. 0,
  3852. isGPRegister(
  3853. Framework::Assembly::MemoryBlockSize::BYTE),
  3854. MODRM_REG,
  3855. READWRITE,
  3856. isGPRegisterOrMemoryAccess(
  3857. Framework::Assembly::MemoryBlockSize::BYTE),
  3858. MODRM_RM,
  3859. READ),
  3860. // AND r16, r/m16
  3861. MachineCodeTableEntry(false,
  3862. 0x23,
  3863. (char)1,
  3864. X66,
  3865. false,
  3866. false,
  3867. 0,
  3868. 0,
  3869. isGPRegister(
  3870. Framework::Assembly::MemoryBlockSize::WORD),
  3871. MODRM_REG,
  3872. READWRITE,
  3873. isGPRegisterOrMemoryAccess(
  3874. Framework::Assembly::MemoryBlockSize::WORD),
  3875. MODRM_RM,
  3876. READ),
  3877. // AND r32, r/m32
  3878. MachineCodeTableEntry(false,
  3879. 0x23,
  3880. (char)1,
  3881. NO_PREFIX,
  3882. false,
  3883. false,
  3884. 0,
  3885. 0,
  3886. isGPRegister(
  3887. Framework::Assembly::MemoryBlockSize::DWORD),
  3888. MODRM_REG,
  3889. READWRITE,
  3890. isGPRegisterOrMemoryAccess(
  3891. Framework::Assembly::MemoryBlockSize::DWORD),
  3892. MODRM_RM,
  3893. READ),
  3894. // AND r64, r/m64
  3895. MachineCodeTableEntry(true,
  3896. 0x23,
  3897. (char)1,
  3898. NO_PREFIX,
  3899. false,
  3900. false,
  3901. 0,
  3902. 0,
  3903. isGPRegister(
  3904. Framework::Assembly::MemoryBlockSize::QWORD),
  3905. MODRM_REG,
  3906. READWRITE,
  3907. isGPRegisterOrMemoryAccess(
  3908. Framework::Assembly::MemoryBlockSize::QWORD),
  3909. MODRM_RM,
  3910. READ),
  3911. }));
  3912. OperationCodeTable::machineCodeTranslationTable.add(
  3913. new OperationCodeTable(Framework::Assembly::OR,
  3914. {
  3915. // OR AL, imm8
  3916. MachineCodeTableEntry(false,
  3917. 0x0C,
  3918. (char)1,
  3919. NO_PREFIX,
  3920. false,
  3921. false,
  3922. 0,
  3923. 0,
  3924. isSpecificGPRegister(Framework::Assembly::RAX,
  3925. Framework::Assembly::LOWER8),
  3926. UNDEFINED,
  3927. READWRITE,
  3928. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  3929. IMM8,
  3930. READ),
  3931. // OR AX, imm16
  3932. MachineCodeTableEntry(false,
  3933. 0x0D,
  3934. (char)1,
  3935. X66,
  3936. false,
  3937. false,
  3938. 0,
  3939. 0,
  3940. isSpecificGPRegister(Framework::Assembly::RAX,
  3941. Framework::Assembly::LOWER16),
  3942. UNDEFINED,
  3943. READWRITE,
  3944. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  3945. IMM16,
  3946. READ),
  3947. // OR EAX, imm32
  3948. MachineCodeTableEntry(false,
  3949. 0x0D,
  3950. (char)1,
  3951. NO_PREFIX,
  3952. false,
  3953. false,
  3954. 0,
  3955. 0,
  3956. isSpecificGPRegister(Framework::Assembly::RAX,
  3957. Framework::Assembly::LOWER32),
  3958. UNDEFINED,
  3959. READWRITE,
  3960. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  3961. IMM32,
  3962. READ),
  3963. // OR RAX, imm32
  3964. MachineCodeTableEntry(true,
  3965. 0x0D,
  3966. (char)1,
  3967. NO_PREFIX,
  3968. false,
  3969. false,
  3970. 0,
  3971. 0,
  3972. isSpecificGPRegister(Framework::Assembly::RAX,
  3973. Framework::Assembly::FULL64),
  3974. UNDEFINED,
  3975. READWRITE,
  3976. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  3977. IMM32,
  3978. READ),
  3979. // OR r/m8, imm8
  3980. MachineCodeTableEntry(false,
  3981. 0x80,
  3982. (char)1,
  3983. NO_PREFIX,
  3984. false,
  3985. false,
  3986. 0,
  3987. 0b001,
  3988. isGPRegisterOrMemoryAccess(
  3989. Framework::Assembly::MemoryBlockSize::BYTE),
  3990. MODRM_RM,
  3991. READWRITE,
  3992. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  3993. IMM8,
  3994. READ),
  3995. // OR r/m16, imm8
  3996. MachineCodeTableEntry(false,
  3997. 0x83,
  3998. (char)1,
  3999. X66,
  4000. false,
  4001. false,
  4002. 0,
  4003. 0b001,
  4004. isGPRegisterOrMemoryAccess(
  4005. Framework::Assembly::MemoryBlockSize::WORD),
  4006. MODRM_RM,
  4007. READWRITE,
  4008. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4009. IMM8,
  4010. READ),
  4011. // OR r/m32, imm8
  4012. MachineCodeTableEntry(false,
  4013. 0x83,
  4014. (char)1,
  4015. NO_PREFIX,
  4016. false,
  4017. false,
  4018. 0,
  4019. 0b001,
  4020. isGPRegisterOrMemoryAccess(
  4021. Framework::Assembly::MemoryBlockSize::DWORD),
  4022. MODRM_RM,
  4023. READWRITE,
  4024. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4025. IMM8,
  4026. READ),
  4027. // OR r/m64, imm8
  4028. MachineCodeTableEntry(true,
  4029. 0x83,
  4030. (char)1,
  4031. NO_PREFIX,
  4032. false,
  4033. false,
  4034. 0,
  4035. 0b001,
  4036. isGPRegisterOrMemoryAccess(
  4037. Framework::Assembly::MemoryBlockSize::QWORD),
  4038. MODRM_RM,
  4039. READWRITE,
  4040. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4041. IMM8,
  4042. READ),
  4043. // OR r/m16, imm16
  4044. MachineCodeTableEntry(false,
  4045. 0x81,
  4046. (char)1,
  4047. X66,
  4048. false,
  4049. false,
  4050. 0,
  4051. 0b001,
  4052. isGPRegisterOrMemoryAccess(
  4053. Framework::Assembly::MemoryBlockSize::WORD),
  4054. MODRM_RM,
  4055. READWRITE,
  4056. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  4057. IMM16,
  4058. READ),
  4059. // OR r/m32, imm32
  4060. MachineCodeTableEntry(false,
  4061. 0x81,
  4062. (char)1,
  4063. NO_PREFIX,
  4064. false,
  4065. false,
  4066. 0,
  4067. 0b001,
  4068. isGPRegisterOrMemoryAccess(
  4069. Framework::Assembly::MemoryBlockSize::DWORD),
  4070. MODRM_RM,
  4071. READWRITE,
  4072. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4073. IMM32,
  4074. READ),
  4075. // OR r/m64, imm32
  4076. MachineCodeTableEntry(true,
  4077. 0x81,
  4078. (char)1,
  4079. NO_PREFIX,
  4080. false,
  4081. false,
  4082. 0,
  4083. 0b001,
  4084. isGPRegisterOrMemoryAccess(
  4085. Framework::Assembly::MemoryBlockSize::QWORD),
  4086. MODRM_RM,
  4087. READWRITE,
  4088. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4089. IMM32,
  4090. READ),
  4091. // OR r/m8, r8
  4092. MachineCodeTableEntry(false,
  4093. 0x08,
  4094. (char)1,
  4095. NO_PREFIX,
  4096. false,
  4097. false,
  4098. 0,
  4099. 0,
  4100. isGPRegisterOrMemoryAccess(
  4101. Framework::Assembly::MemoryBlockSize::BYTE),
  4102. MODRM_RM,
  4103. READWRITE,
  4104. isGPRegister(
  4105. Framework::Assembly::MemoryBlockSize::BYTE),
  4106. MODRM_REG,
  4107. READ),
  4108. // OR r/m16, r16
  4109. MachineCodeTableEntry(false,
  4110. 0x09,
  4111. (char)1,
  4112. X66,
  4113. false,
  4114. false,
  4115. 0,
  4116. 0,
  4117. isGPRegisterOrMemoryAccess(
  4118. Framework::Assembly::MemoryBlockSize::WORD),
  4119. MODRM_RM,
  4120. READWRITE,
  4121. isGPRegister(
  4122. Framework::Assembly::MemoryBlockSize::WORD),
  4123. MODRM_REG,
  4124. READ),
  4125. // OR r/m32, r32
  4126. MachineCodeTableEntry(false,
  4127. 0x09,
  4128. (char)1,
  4129. NO_PREFIX,
  4130. false,
  4131. false,
  4132. 0,
  4133. 0,
  4134. isGPRegisterOrMemoryAccess(
  4135. Framework::Assembly::MemoryBlockSize::DWORD),
  4136. MODRM_RM,
  4137. READWRITE,
  4138. isGPRegister(
  4139. Framework::Assembly::MemoryBlockSize::DWORD),
  4140. MODRM_REG,
  4141. READ),
  4142. // OR r/m64, r64
  4143. MachineCodeTableEntry(true,
  4144. 0x09,
  4145. (char)1,
  4146. NO_PREFIX,
  4147. false,
  4148. false,
  4149. 0,
  4150. 0,
  4151. isGPRegisterOrMemoryAccess(
  4152. Framework::Assembly::MemoryBlockSize::QWORD),
  4153. MODRM_RM,
  4154. READWRITE,
  4155. isGPRegister(
  4156. Framework::Assembly::MemoryBlockSize::QWORD),
  4157. MODRM_REG,
  4158. READ),
  4159. // OR r8, r/m8
  4160. MachineCodeTableEntry(false,
  4161. 0x0A,
  4162. (char)1,
  4163. NO_PREFIX,
  4164. false,
  4165. false,
  4166. 0,
  4167. 0,
  4168. isGPRegister(
  4169. Framework::Assembly::MemoryBlockSize::BYTE),
  4170. MODRM_REG,
  4171. READWRITE,
  4172. isGPRegisterOrMemoryAccess(
  4173. Framework::Assembly::MemoryBlockSize::BYTE),
  4174. MODRM_RM,
  4175. READ),
  4176. // OR r16, r/m16
  4177. MachineCodeTableEntry(false,
  4178. 0x0B,
  4179. (char)1,
  4180. X66,
  4181. false,
  4182. false,
  4183. 0,
  4184. 0,
  4185. isGPRegister(
  4186. Framework::Assembly::MemoryBlockSize::WORD),
  4187. MODRM_REG,
  4188. READWRITE,
  4189. isGPRegisterOrMemoryAccess(
  4190. Framework::Assembly::MemoryBlockSize::WORD),
  4191. MODRM_RM,
  4192. READ),
  4193. // OR r32, r/m32
  4194. MachineCodeTableEntry(false,
  4195. 0x0B,
  4196. (char)1,
  4197. NO_PREFIX,
  4198. false,
  4199. false,
  4200. 0,
  4201. 0,
  4202. isGPRegister(
  4203. Framework::Assembly::MemoryBlockSize::DWORD),
  4204. MODRM_REG,
  4205. READWRITE,
  4206. isGPRegisterOrMemoryAccess(
  4207. Framework::Assembly::MemoryBlockSize::DWORD),
  4208. MODRM_RM,
  4209. READ),
  4210. // OR r64, r/m64
  4211. MachineCodeTableEntry(true,
  4212. 0x0B,
  4213. (char)1,
  4214. NO_PREFIX,
  4215. false,
  4216. false,
  4217. 0,
  4218. 0,
  4219. isGPRegister(
  4220. Framework::Assembly::MemoryBlockSize::QWORD),
  4221. MODRM_REG,
  4222. READWRITE,
  4223. isGPRegisterOrMemoryAccess(
  4224. Framework::Assembly::MemoryBlockSize::QWORD),
  4225. MODRM_RM,
  4226. READ),
  4227. }));
  4228. OperationCodeTable::machineCodeTranslationTable.add(
  4229. new OperationCodeTable(Framework::Assembly::XOR,
  4230. {
  4231. // XOR AL, imm8
  4232. MachineCodeTableEntry(false,
  4233. 0x34,
  4234. (char)1,
  4235. NO_PREFIX,
  4236. false,
  4237. false,
  4238. 0,
  4239. 0,
  4240. isSpecificGPRegister(Framework::Assembly::RAX,
  4241. Framework::Assembly::LOWER8),
  4242. UNDEFINED,
  4243. READWRITE,
  4244. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4245. IMM8,
  4246. READ),
  4247. // XOR AX, imm16
  4248. MachineCodeTableEntry(false,
  4249. 0x35,
  4250. (char)1,
  4251. X66,
  4252. false,
  4253. false,
  4254. 0,
  4255. 0,
  4256. isSpecificGPRegister(Framework::Assembly::RAX,
  4257. Framework::Assembly::LOWER16),
  4258. UNDEFINED,
  4259. READWRITE,
  4260. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  4261. IMM16,
  4262. READ),
  4263. // XOR EAX, imm32
  4264. MachineCodeTableEntry(false,
  4265. 0x35,
  4266. (char)1,
  4267. NO_PREFIX,
  4268. false,
  4269. false,
  4270. 0,
  4271. 0,
  4272. isSpecificGPRegister(Framework::Assembly::RAX,
  4273. Framework::Assembly::LOWER32),
  4274. UNDEFINED,
  4275. READWRITE,
  4276. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4277. IMM32,
  4278. READ),
  4279. // XOR RAX, imm32
  4280. MachineCodeTableEntry(true,
  4281. 0x35,
  4282. (char)1,
  4283. NO_PREFIX,
  4284. false,
  4285. false,
  4286. 0,
  4287. 0,
  4288. isSpecificGPRegister(Framework::Assembly::RAX,
  4289. Framework::Assembly::FULL64),
  4290. UNDEFINED,
  4291. READWRITE,
  4292. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4293. IMM32,
  4294. READ),
  4295. // XOR r/m8, imm8
  4296. MachineCodeTableEntry(false,
  4297. 0x80,
  4298. (char)1,
  4299. NO_PREFIX,
  4300. false,
  4301. false,
  4302. 0,
  4303. 0b110,
  4304. isGPRegisterOrMemoryAccess(
  4305. Framework::Assembly::MemoryBlockSize::BYTE),
  4306. MODRM_RM,
  4307. READWRITE,
  4308. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4309. IMM8,
  4310. READ),
  4311. // XOR r/m16, imm8
  4312. MachineCodeTableEntry(false,
  4313. 0x83,
  4314. (char)1,
  4315. X66,
  4316. false,
  4317. false,
  4318. 0,
  4319. 0b110,
  4320. isGPRegisterOrMemoryAccess(
  4321. Framework::Assembly::MemoryBlockSize::WORD),
  4322. MODRM_RM,
  4323. READWRITE,
  4324. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4325. IMM8,
  4326. READ),
  4327. // XOR r/m32, imm8
  4328. MachineCodeTableEntry(false,
  4329. 0x83,
  4330. (char)1,
  4331. NO_PREFIX,
  4332. false,
  4333. false,
  4334. 0,
  4335. 0b110,
  4336. isGPRegisterOrMemoryAccess(
  4337. Framework::Assembly::MemoryBlockSize::DWORD),
  4338. MODRM_RM,
  4339. READWRITE,
  4340. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4341. IMM8,
  4342. READ),
  4343. // XOR r/m64, imm8
  4344. MachineCodeTableEntry(true,
  4345. 0x83,
  4346. (char)1,
  4347. NO_PREFIX,
  4348. false,
  4349. false,
  4350. 0,
  4351. 0b110,
  4352. isGPRegisterOrMemoryAccess(
  4353. Framework::Assembly::MemoryBlockSize::QWORD),
  4354. MODRM_RM,
  4355. READWRITE,
  4356. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4357. IMM8,
  4358. READ),
  4359. // XOR r/m16, imm16
  4360. MachineCodeTableEntry(false,
  4361. 0x81,
  4362. (char)1,
  4363. X66,
  4364. false,
  4365. false,
  4366. 0,
  4367. 0b110,
  4368. isGPRegisterOrMemoryAccess(
  4369. Framework::Assembly::MemoryBlockSize::WORD),
  4370. MODRM_RM,
  4371. READWRITE,
  4372. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  4373. IMM16,
  4374. READ),
  4375. // XOR r/m32, imm32
  4376. MachineCodeTableEntry(false,
  4377. 0x81,
  4378. (char)1,
  4379. NO_PREFIX,
  4380. false,
  4381. false,
  4382. 0,
  4383. 0b110,
  4384. isGPRegisterOrMemoryAccess(
  4385. Framework::Assembly::MemoryBlockSize::DWORD),
  4386. MODRM_RM,
  4387. READWRITE,
  4388. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4389. IMM32,
  4390. READ),
  4391. // XOR r/m64, imm32
  4392. MachineCodeTableEntry(true,
  4393. 0x81,
  4394. (char)1,
  4395. NO_PREFIX,
  4396. false,
  4397. false,
  4398. 0,
  4399. 0b110,
  4400. isGPRegisterOrMemoryAccess(
  4401. Framework::Assembly::MemoryBlockSize::QWORD),
  4402. MODRM_RM,
  4403. READWRITE,
  4404. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4405. IMM32,
  4406. READ),
  4407. // XOR r/m8, r8
  4408. MachineCodeTableEntry(false,
  4409. 0x30,
  4410. (char)1,
  4411. NO_PREFIX,
  4412. false,
  4413. false,
  4414. 0,
  4415. 0,
  4416. isGPRegisterOrMemoryAccess(
  4417. Framework::Assembly::MemoryBlockSize::BYTE),
  4418. MODRM_RM,
  4419. READWRITE,
  4420. isGPRegister(
  4421. Framework::Assembly::MemoryBlockSize::BYTE),
  4422. MODRM_REG,
  4423. READ),
  4424. // XOR r/m16, r16
  4425. MachineCodeTableEntry(false,
  4426. 0x31,
  4427. (char)1,
  4428. X66,
  4429. false,
  4430. false,
  4431. 0,
  4432. 0,
  4433. isGPRegisterOrMemoryAccess(
  4434. Framework::Assembly::MemoryBlockSize::WORD),
  4435. MODRM_RM,
  4436. READWRITE,
  4437. isGPRegister(
  4438. Framework::Assembly::MemoryBlockSize::WORD),
  4439. MODRM_REG,
  4440. READ),
  4441. // XOR r/m32, r32
  4442. MachineCodeTableEntry(false,
  4443. 0x31,
  4444. (char)1,
  4445. NO_PREFIX,
  4446. false,
  4447. false,
  4448. 0,
  4449. 0,
  4450. isGPRegisterOrMemoryAccess(
  4451. Framework::Assembly::MemoryBlockSize::DWORD),
  4452. MODRM_RM,
  4453. READWRITE,
  4454. isGPRegister(
  4455. Framework::Assembly::MemoryBlockSize::DWORD),
  4456. MODRM_REG,
  4457. READ),
  4458. // XOR r/m64, r64
  4459. MachineCodeTableEntry(true,
  4460. 0x31,
  4461. (char)1,
  4462. NO_PREFIX,
  4463. false,
  4464. false,
  4465. 0,
  4466. 0,
  4467. isGPRegisterOrMemoryAccess(
  4468. Framework::Assembly::MemoryBlockSize::QWORD),
  4469. MODRM_RM,
  4470. READWRITE,
  4471. isGPRegister(
  4472. Framework::Assembly::MemoryBlockSize::QWORD),
  4473. MODRM_REG,
  4474. READ),
  4475. // XOR r8, r/m8
  4476. MachineCodeTableEntry(false,
  4477. 0x32,
  4478. (char)1,
  4479. NO_PREFIX,
  4480. false,
  4481. false,
  4482. 0,
  4483. 0,
  4484. isGPRegister(
  4485. Framework::Assembly::MemoryBlockSize::BYTE),
  4486. MODRM_REG,
  4487. READWRITE,
  4488. isGPRegisterOrMemoryAccess(
  4489. Framework::Assembly::MemoryBlockSize::BYTE),
  4490. MODRM_RM,
  4491. READ),
  4492. // XOR r16, r/m16
  4493. MachineCodeTableEntry(false,
  4494. 0x33,
  4495. (char)1,
  4496. X66,
  4497. false,
  4498. false,
  4499. 0,
  4500. 0,
  4501. isGPRegister(
  4502. Framework::Assembly::MemoryBlockSize::WORD),
  4503. MODRM_REG,
  4504. READWRITE,
  4505. isGPRegisterOrMemoryAccess(
  4506. Framework::Assembly::MemoryBlockSize::WORD),
  4507. MODRM_RM,
  4508. READ),
  4509. // XOR r32, r/m32
  4510. MachineCodeTableEntry(false,
  4511. 0x33,
  4512. (char)1,
  4513. NO_PREFIX,
  4514. false,
  4515. false,
  4516. 0,
  4517. 0,
  4518. isGPRegister(
  4519. Framework::Assembly::MemoryBlockSize::DWORD),
  4520. MODRM_REG,
  4521. READWRITE,
  4522. isGPRegisterOrMemoryAccess(
  4523. Framework::Assembly::MemoryBlockSize::DWORD),
  4524. MODRM_RM,
  4525. READ),
  4526. // XOR r64, r/m64
  4527. MachineCodeTableEntry(true,
  4528. 0x33,
  4529. (char)1,
  4530. NO_PREFIX,
  4531. false,
  4532. false,
  4533. 0,
  4534. 0,
  4535. isGPRegister(
  4536. Framework::Assembly::MemoryBlockSize::QWORD),
  4537. MODRM_REG,
  4538. READWRITE,
  4539. isGPRegisterOrMemoryAccess(
  4540. Framework::Assembly::MemoryBlockSize::QWORD),
  4541. MODRM_RM,
  4542. READ),
  4543. }));
  4544. OperationCodeTable::machineCodeTranslationTable.add(
  4545. new OperationCodeTable(Framework::Assembly::NOT,
  4546. {
  4547. // NOT r/m8
  4548. MachineCodeTableEntry(false,
  4549. 0xF6,
  4550. (char)1,
  4551. NO_PREFIX,
  4552. false,
  4553. false,
  4554. 0,
  4555. 0b010,
  4556. isGPRegisterOrMemoryAccess(
  4557. Framework::Assembly::MemoryBlockSize::BYTE),
  4558. MODRM_RM,
  4559. READWRITE),
  4560. // NOT r/m16
  4561. MachineCodeTableEntry(false,
  4562. 0xF7,
  4563. (char)1,
  4564. X66,
  4565. false,
  4566. false,
  4567. 0,
  4568. 0b010,
  4569. isGPRegisterOrMemoryAccess(
  4570. Framework::Assembly::MemoryBlockSize::WORD),
  4571. MODRM_RM,
  4572. READWRITE),
  4573. // NOT r/m32
  4574. MachineCodeTableEntry(false,
  4575. 0xF7,
  4576. (char)1,
  4577. NO_PREFIX,
  4578. false,
  4579. false,
  4580. 0,
  4581. 0b010,
  4582. isGPRegisterOrMemoryAccess(
  4583. Framework::Assembly::MemoryBlockSize::DWORD),
  4584. MODRM_RM,
  4585. READWRITE),
  4586. // NOT r/m64
  4587. MachineCodeTableEntry(true,
  4588. 0xF7,
  4589. (char)1,
  4590. NO_PREFIX,
  4591. false,
  4592. false,
  4593. 0,
  4594. 0b010,
  4595. isGPRegisterOrMemoryAccess(
  4596. Framework::Assembly::MemoryBlockSize::DWORD),
  4597. MODRM_RM,
  4598. READWRITE),
  4599. }));
  4600. OperationCodeTable::machineCodeTranslationTable.add(
  4601. new OperationCodeTable(Framework::Assembly::TEST,
  4602. {
  4603. // TEST AL, imm8
  4604. MachineCodeTableEntry(false,
  4605. 0xA8,
  4606. (char)1,
  4607. NO_PREFIX,
  4608. false,
  4609. false,
  4610. 0,
  4611. 0,
  4612. isSpecificGPRegister(Framework::Assembly::RAX,
  4613. Framework::Assembly::LOWER8),
  4614. UNDEFINED,
  4615. READ,
  4616. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4617. IMM8,
  4618. READ),
  4619. // TEST AX, imm16
  4620. MachineCodeTableEntry(false,
  4621. 0xA9,
  4622. (char)1,
  4623. X66,
  4624. false,
  4625. false,
  4626. 0,
  4627. 0,
  4628. isSpecificGPRegister(Framework::Assembly::RAX,
  4629. Framework::Assembly::LOWER16),
  4630. UNDEFINED,
  4631. READ,
  4632. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  4633. IMM16,
  4634. READ),
  4635. // TEST EAX, imm32
  4636. MachineCodeTableEntry(false,
  4637. 0xA9,
  4638. (char)1,
  4639. NO_PREFIX,
  4640. false,
  4641. false,
  4642. 0,
  4643. 0,
  4644. isSpecificGPRegister(Framework::Assembly::RAX,
  4645. Framework::Assembly::LOWER32),
  4646. UNDEFINED,
  4647. READ,
  4648. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4649. IMM32,
  4650. READ),
  4651. // TEST RAX, imm32
  4652. MachineCodeTableEntry(true,
  4653. 0xA9,
  4654. (char)1,
  4655. NO_PREFIX,
  4656. false,
  4657. false,
  4658. 0,
  4659. 0,
  4660. isSpecificGPRegister(Framework::Assembly::RAX,
  4661. Framework::Assembly::FULL64),
  4662. UNDEFINED,
  4663. READ,
  4664. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4665. IMM32,
  4666. READ),
  4667. // TEST r/m8, imm8
  4668. MachineCodeTableEntry(false,
  4669. 0xF6,
  4670. (char)1,
  4671. NO_PREFIX,
  4672. false,
  4673. false,
  4674. 0,
  4675. 0,
  4676. isGPRegisterOrMemoryAccess(
  4677. Framework::Assembly::MemoryBlockSize::BYTE),
  4678. MODRM_RM,
  4679. READ,
  4680. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4681. IMM8,
  4682. READ),
  4683. // TEST r/m16, imm16
  4684. MachineCodeTableEntry(false,
  4685. 0xF7,
  4686. (char)1,
  4687. X66,
  4688. false,
  4689. false,
  4690. 0,
  4691. 0,
  4692. isGPRegisterOrMemoryAccess(
  4693. Framework::Assembly::MemoryBlockSize::WORD),
  4694. MODRM_RM,
  4695. READ,
  4696. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  4697. IMM16,
  4698. READ),
  4699. // TEST r/m32, imm32
  4700. MachineCodeTableEntry(false,
  4701. 0xF7,
  4702. (char)1,
  4703. NO_PREFIX,
  4704. false,
  4705. false,
  4706. 0,
  4707. 0,
  4708. isGPRegisterOrMemoryAccess(
  4709. Framework::Assembly::MemoryBlockSize::DWORD),
  4710. MODRM_RM,
  4711. READ,
  4712. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4713. IMM32,
  4714. READ),
  4715. // TEST r/m64, imm32
  4716. MachineCodeTableEntry(true,
  4717. 0xF7,
  4718. (char)1,
  4719. NO_PREFIX,
  4720. false,
  4721. false,
  4722. 0,
  4723. 0,
  4724. isGPRegisterOrMemoryAccess(
  4725. Framework::Assembly::MemoryBlockSize::QWORD),
  4726. MODRM_RM,
  4727. READ,
  4728. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4729. IMM32,
  4730. READ),
  4731. // TEST r/m8, r8
  4732. MachineCodeTableEntry(false,
  4733. 0x84,
  4734. (char)1,
  4735. NO_PREFIX,
  4736. false,
  4737. false,
  4738. 0,
  4739. 0,
  4740. isGPRegisterOrMemoryAccess(
  4741. Framework::Assembly::MemoryBlockSize::BYTE),
  4742. MODRM_RM,
  4743. READ,
  4744. isGPRegister(
  4745. Framework::Assembly::MemoryBlockSize::BYTE),
  4746. MODRM_REG,
  4747. READ),
  4748. // TEST r/m16, r16
  4749. MachineCodeTableEntry(false,
  4750. 0x85,
  4751. (char)1,
  4752. X66,
  4753. false,
  4754. false,
  4755. 0,
  4756. 0,
  4757. isGPRegisterOrMemoryAccess(
  4758. Framework::Assembly::MemoryBlockSize::WORD),
  4759. MODRM_RM,
  4760. READ,
  4761. isGPRegister(
  4762. Framework::Assembly::MemoryBlockSize::WORD),
  4763. MODRM_REG,
  4764. READ),
  4765. // TEST r/m32, r32
  4766. MachineCodeTableEntry(false,
  4767. 0x85,
  4768. (char)1,
  4769. NO_PREFIX,
  4770. false,
  4771. false,
  4772. 0,
  4773. 0,
  4774. isGPRegisterOrMemoryAccess(
  4775. Framework::Assembly::MemoryBlockSize::DWORD),
  4776. MODRM_RM,
  4777. READ,
  4778. isGPRegister(
  4779. Framework::Assembly::MemoryBlockSize::DWORD),
  4780. MODRM_REG,
  4781. READ),
  4782. // TEST r/m64, r64
  4783. MachineCodeTableEntry(true,
  4784. 0x85,
  4785. (char)1,
  4786. NO_PREFIX,
  4787. false,
  4788. false,
  4789. 0,
  4790. 0,
  4791. isGPRegisterOrMemoryAccess(
  4792. Framework::Assembly::MemoryBlockSize::QWORD),
  4793. MODRM_RM,
  4794. READ,
  4795. isGPRegister(
  4796. Framework::Assembly::MemoryBlockSize::QWORD),
  4797. MODRM_REG,
  4798. READ),
  4799. }));
  4800. OperationCodeTable::machineCodeTranslationTable.add(
  4801. new OperationCodeTable(Framework::Assembly::CMP,
  4802. {
  4803. // CMP AL, imm8
  4804. MachineCodeTableEntry(false,
  4805. 0x3C,
  4806. (char)1,
  4807. NO_PREFIX,
  4808. false,
  4809. false,
  4810. 0,
  4811. 0,
  4812. isSpecificGPRegister(Framework::Assembly::RAX,
  4813. Framework::Assembly::LOWER8),
  4814. UNDEFINED,
  4815. READ,
  4816. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4817. IMM8,
  4818. READ),
  4819. // CMP AX, imm16
  4820. MachineCodeTableEntry(false,
  4821. 0x3D,
  4822. (char)1,
  4823. X66,
  4824. false,
  4825. false,
  4826. 0,
  4827. 0,
  4828. isSpecificGPRegister(Framework::Assembly::RAX,
  4829. Framework::Assembly::LOWER16),
  4830. UNDEFINED,
  4831. READ,
  4832. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  4833. IMM16,
  4834. READ),
  4835. // CMP EAX, imm32
  4836. MachineCodeTableEntry(false,
  4837. 0x3D,
  4838. (char)1,
  4839. NO_PREFIX,
  4840. false,
  4841. false,
  4842. 0,
  4843. 0,
  4844. isSpecificGPRegister(Framework::Assembly::RAX,
  4845. Framework::Assembly::LOWER32),
  4846. UNDEFINED,
  4847. READ,
  4848. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4849. IMM32,
  4850. READ),
  4851. // CMP RAX, imm32
  4852. MachineCodeTableEntry(true,
  4853. 0x3D,
  4854. (char)1,
  4855. NO_PREFIX,
  4856. false,
  4857. false,
  4858. 0,
  4859. 0,
  4860. isSpecificGPRegister(Framework::Assembly::RAX,
  4861. Framework::Assembly::FULL64),
  4862. UNDEFINED,
  4863. READ,
  4864. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4865. IMM32,
  4866. READ),
  4867. // CMP r/m8, imm8
  4868. MachineCodeTableEntry(false,
  4869. 0x80,
  4870. (char)1,
  4871. NO_PREFIX,
  4872. false,
  4873. false,
  4874. 0,
  4875. 0b111,
  4876. isGPRegisterOrMemoryAccess(
  4877. Framework::Assembly::MemoryBlockSize::BYTE),
  4878. MODRM_RM,
  4879. READ,
  4880. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4881. IMM8,
  4882. READ),
  4883. // CMP r/m16, imm8
  4884. MachineCodeTableEntry(false,
  4885. 0x83,
  4886. (char)1,
  4887. X66,
  4888. false,
  4889. false,
  4890. 0,
  4891. 0b111,
  4892. isGPRegisterOrMemoryAccess(
  4893. Framework::Assembly::MemoryBlockSize::WORD),
  4894. MODRM_RM,
  4895. READ,
  4896. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4897. IMM8,
  4898. READ),
  4899. // CMP r/m32, imm8
  4900. MachineCodeTableEntry(false,
  4901. 0x83,
  4902. (char)1,
  4903. NO_PREFIX,
  4904. false,
  4905. false,
  4906. 0,
  4907. 0b111,
  4908. isGPRegisterOrMemoryAccess(
  4909. Framework::Assembly::MemoryBlockSize::DWORD),
  4910. MODRM_RM,
  4911. READ,
  4912. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4913. IMM8,
  4914. READ),
  4915. // CMP r/m64, imm8
  4916. MachineCodeTableEntry(true,
  4917. 0x83,
  4918. (char)1,
  4919. NO_PREFIX,
  4920. false,
  4921. false,
  4922. 0,
  4923. 0b111,
  4924. isGPRegisterOrMemoryAccess(
  4925. Framework::Assembly::MemoryBlockSize::QWORD),
  4926. MODRM_RM,
  4927. READ,
  4928. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  4929. IMM8,
  4930. READ),
  4931. // CMP r/m16, imm16
  4932. MachineCodeTableEntry(false,
  4933. 0x81,
  4934. (char)1,
  4935. X66,
  4936. false,
  4937. false,
  4938. 0,
  4939. 0b111,
  4940. isGPRegisterOrMemoryAccess(
  4941. Framework::Assembly::MemoryBlockSize::WORD),
  4942. MODRM_RM,
  4943. READ,
  4944. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  4945. IMM16,
  4946. READ),
  4947. // CMP r/m32, imm32
  4948. MachineCodeTableEntry(false,
  4949. 0x81,
  4950. (char)1,
  4951. NO_PREFIX,
  4952. false,
  4953. false,
  4954. 0,
  4955. 0b111,
  4956. isGPRegisterOrMemoryAccess(
  4957. Framework::Assembly::MemoryBlockSize::DWORD),
  4958. MODRM_RM,
  4959. READ,
  4960. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4961. IMM32,
  4962. READ),
  4963. // TEST r/m64, imm32
  4964. MachineCodeTableEntry(true,
  4965. 0x81,
  4966. (char)1,
  4967. NO_PREFIX,
  4968. false,
  4969. false,
  4970. 0,
  4971. 0b111,
  4972. isGPRegisterOrMemoryAccess(
  4973. Framework::Assembly::MemoryBlockSize::QWORD),
  4974. MODRM_RM,
  4975. READ,
  4976. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  4977. IMM32,
  4978. READ),
  4979. // CMP r/m8, r8
  4980. MachineCodeTableEntry(false,
  4981. 0x38,
  4982. (char)1,
  4983. NO_PREFIX,
  4984. false,
  4985. false,
  4986. 0,
  4987. 0b111,
  4988. isGPRegisterOrMemoryAccess(
  4989. Framework::Assembly::MemoryBlockSize::BYTE),
  4990. MODRM_RM,
  4991. READ,
  4992. isGPRegister(
  4993. Framework::Assembly::MemoryBlockSize::BYTE),
  4994. MODRM_REG,
  4995. READ),
  4996. // CMP r/m16, r16
  4997. MachineCodeTableEntry(false,
  4998. 0x39,
  4999. (char)1,
  5000. X66,
  5001. false,
  5002. false,
  5003. 0,
  5004. 0,
  5005. isGPRegisterOrMemoryAccess(
  5006. Framework::Assembly::MemoryBlockSize::WORD),
  5007. MODRM_RM,
  5008. READ,
  5009. isGPRegister(
  5010. Framework::Assembly::MemoryBlockSize::WORD),
  5011. MODRM_REG,
  5012. READ),
  5013. // CMP r/m32, r32
  5014. MachineCodeTableEntry(false,
  5015. 0x39,
  5016. (char)1,
  5017. NO_PREFIX,
  5018. false,
  5019. false,
  5020. 0,
  5021. 0,
  5022. isGPRegisterOrMemoryAccess(
  5023. Framework::Assembly::MemoryBlockSize::DWORD),
  5024. MODRM_RM,
  5025. READ,
  5026. isGPRegister(
  5027. Framework::Assembly::MemoryBlockSize::DWORD),
  5028. MODRM_REG,
  5029. READ),
  5030. // CMP r/m64, r64
  5031. MachineCodeTableEntry(true,
  5032. 0x39,
  5033. (char)1,
  5034. NO_PREFIX,
  5035. false,
  5036. false,
  5037. 0,
  5038. 0,
  5039. isGPRegisterOrMemoryAccess(
  5040. Framework::Assembly::MemoryBlockSize::QWORD),
  5041. MODRM_RM,
  5042. READ,
  5043. isGPRegister(
  5044. Framework::Assembly::MemoryBlockSize::QWORD),
  5045. MODRM_REG,
  5046. READ),
  5047. // CMP r8, r/m8
  5048. MachineCodeTableEntry(false,
  5049. 0x3A,
  5050. (char)1,
  5051. NO_PREFIX,
  5052. false,
  5053. false,
  5054. 0,
  5055. 0,
  5056. isGPRegister(
  5057. Framework::Assembly::MemoryBlockSize::BYTE),
  5058. MODRM_REG,
  5059. READ,
  5060. isGPRegisterOrMemoryAccess(
  5061. Framework::Assembly::MemoryBlockSize::BYTE),
  5062. MODRM_RM,
  5063. READ),
  5064. // CMP r16, r/m16
  5065. MachineCodeTableEntry(false,
  5066. 0x3B,
  5067. (char)1,
  5068. X66,
  5069. false,
  5070. false,
  5071. 0,
  5072. 0,
  5073. isGPRegister(
  5074. Framework::Assembly::MemoryBlockSize::WORD),
  5075. MODRM_REG,
  5076. READ,
  5077. isGPRegisterOrMemoryAccess(
  5078. Framework::Assembly::MemoryBlockSize::WORD),
  5079. MODRM_RM,
  5080. READ),
  5081. // CMP r32, r/m32
  5082. MachineCodeTableEntry(false,
  5083. 0x3B,
  5084. (char)1,
  5085. NO_PREFIX,
  5086. false,
  5087. false,
  5088. 0,
  5089. 0,
  5090. isGPRegister(
  5091. Framework::Assembly::MemoryBlockSize::DWORD),
  5092. MODRM_REG,
  5093. READ,
  5094. isGPRegisterOrMemoryAccess(
  5095. Framework::Assembly::MemoryBlockSize::DWORD),
  5096. MODRM_RM,
  5097. READ),
  5098. // CMP r64, r/m64
  5099. MachineCodeTableEntry(true,
  5100. 0x3B,
  5101. (char)1,
  5102. NO_PREFIX,
  5103. false,
  5104. false,
  5105. 0,
  5106. 0,
  5107. isGPRegister(
  5108. Framework::Assembly::MemoryBlockSize::QWORD),
  5109. MODRM_REG,
  5110. READ,
  5111. isGPRegisterOrMemoryAccess(
  5112. Framework::Assembly::MemoryBlockSize::QWORD),
  5113. MODRM_RM,
  5114. READ),
  5115. }));
  5116. OperationCodeTable::machineCodeTranslationTable.add(
  5117. new OperationCodeTable(Framework::Assembly::CMPPD,
  5118. {
  5119. // CMPPD xmm1, xmm2/m128, imm8
  5120. MachineCodeTableEntry(false,
  5121. 0xC20F,
  5122. (char)2,
  5123. X66,
  5124. false,
  5125. false,
  5126. 0,
  5127. 0,
  5128. isFPRegister(
  5129. Framework::Assembly::MemoryBlockSize::M128),
  5130. MODRM_REG,
  5131. READWRITE,
  5132. isFPRegisterOrMEmoryAccess(
  5133. Framework::Assembly::MemoryBlockSize::M128),
  5134. MODRM_RM,
  5135. READ,
  5136. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5137. IMM8,
  5138. READ),
  5139. // VCMPPD xmm1, xmm2, xmm3/m128, imm8
  5140. MachineCodeTableEntry(false,
  5141. 0xC20F,
  5142. (char)2,
  5143. NO_PREFIX,
  5144. true,
  5145. false,
  5146. 0b01,
  5147. 0,
  5148. isFPRegister(
  5149. Framework::Assembly::MemoryBlockSize::M128),
  5150. MODRM_REG,
  5151. WRITE,
  5152. isFPRegister(
  5153. Framework::Assembly::MemoryBlockSize::M128),
  5154. VEX_VVVV,
  5155. READ,
  5156. isFPRegisterOrMEmoryAccess(
  5157. Framework::Assembly::MemoryBlockSize::M128),
  5158. MODRM_RM,
  5159. READ,
  5160. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5161. IMM8,
  5162. READ),
  5163. // VCMPPD ymm1, ymm2, ymm3/m256, imm8
  5164. MachineCodeTableEntry(false,
  5165. 0xC20F,
  5166. (char)2,
  5167. NO_PREFIX,
  5168. true,
  5169. true,
  5170. 0b01,
  5171. 0,
  5172. isFPRegister(
  5173. Framework::Assembly::MemoryBlockSize::M256),
  5174. MODRM_REG,
  5175. WRITE,
  5176. isFPRegister(
  5177. Framework::Assembly::MemoryBlockSize::M256),
  5178. VEX_VVVV,
  5179. READ,
  5180. isFPRegisterOrMEmoryAccess(
  5181. Framework::Assembly::MemoryBlockSize::M256),
  5182. MODRM_RM,
  5183. READ,
  5184. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5185. IMM8,
  5186. READ),
  5187. }));
  5188. OperationCodeTable::machineCodeTranslationTable.add(
  5189. new OperationCodeTable(Framework::Assembly::CMPPS,
  5190. {
  5191. // CMPPS xmm1, xmm2/m128, imm8
  5192. MachineCodeTableEntry(false,
  5193. 0xC20F,
  5194. (char)2,
  5195. NO_PREFIX,
  5196. false,
  5197. false,
  5198. 0,
  5199. 0,
  5200. isFPRegister(
  5201. Framework::Assembly::MemoryBlockSize::M128),
  5202. MODRM_REG,
  5203. READWRITE,
  5204. isFPRegisterOrMEmoryAccess(
  5205. Framework::Assembly::MemoryBlockSize::M128),
  5206. MODRM_RM,
  5207. READ,
  5208. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5209. IMM8,
  5210. READ),
  5211. // VCMPPS xmm1, xmm2, xmm3/m128, imm8
  5212. MachineCodeTableEntry(false,
  5213. 0xC20F,
  5214. (char)2,
  5215. NO_PREFIX,
  5216. true,
  5217. false,
  5218. 0b00,
  5219. 0,
  5220. isFPRegister(
  5221. Framework::Assembly::MemoryBlockSize::M128),
  5222. MODRM_REG,
  5223. WRITE,
  5224. isFPRegister(
  5225. Framework::Assembly::MemoryBlockSize::M128),
  5226. VEX_VVVV,
  5227. READ,
  5228. isFPRegisterOrMEmoryAccess(
  5229. Framework::Assembly::MemoryBlockSize::M128),
  5230. MODRM_RM,
  5231. READ,
  5232. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5233. IMM8,
  5234. READ),
  5235. // VCMPPS ymm1, ymm2, ymm3/m256, imm8
  5236. MachineCodeTableEntry(false,
  5237. 0xC20F,
  5238. (char)2,
  5239. NO_PREFIX,
  5240. true,
  5241. true,
  5242. 0b00,
  5243. 0,
  5244. isFPRegister(
  5245. Framework::Assembly::MemoryBlockSize::M256),
  5246. MODRM_REG,
  5247. WRITE,
  5248. isFPRegister(
  5249. Framework::Assembly::MemoryBlockSize::M256),
  5250. VEX_VVVV,
  5251. READ,
  5252. isFPRegisterOrMEmoryAccess(
  5253. Framework::Assembly::MemoryBlockSize::M256),
  5254. MODRM_RM,
  5255. READ,
  5256. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5257. IMM8,
  5258. READ),
  5259. }));
  5260. OperationCodeTable::machineCodeTranslationTable.add(
  5261. new OperationCodeTable(Framework::Assembly::CMPSD,
  5262. {
  5263. // CMPSD xmm1, xmm2/m128, imm8
  5264. MachineCodeTableEntry(false,
  5265. 0xC20F,
  5266. (char)2,
  5267. XF2,
  5268. false,
  5269. false,
  5270. 0,
  5271. 0,
  5272. isFPRegister(
  5273. Framework::Assembly::MemoryBlockSize::M128),
  5274. MODRM_REG,
  5275. READWRITE,
  5276. isFPRegisterOrMEmoryAccess(
  5277. Framework::Assembly::MemoryBlockSize::M128),
  5278. MODRM_RM,
  5279. READ,
  5280. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5281. IMM8,
  5282. READ),
  5283. // VCMPSD xmm1, xmm2, xmm3/m128, imm8
  5284. MachineCodeTableEntry(false,
  5285. 0xC20F,
  5286. (char)2,
  5287. NO_PREFIX,
  5288. true,
  5289. false,
  5290. 0b11,
  5291. 0,
  5292. isFPRegister(
  5293. Framework::Assembly::MemoryBlockSize::M128),
  5294. MODRM_REG,
  5295. WRITE,
  5296. isFPRegister(
  5297. Framework::Assembly::MemoryBlockSize::M128),
  5298. VEX_VVVV,
  5299. READ,
  5300. isFPRegisterOrMEmoryAccess(
  5301. Framework::Assembly::MemoryBlockSize::M128),
  5302. MODRM_RM,
  5303. READ,
  5304. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5305. IMM8,
  5306. READ),
  5307. }));
  5308. OperationCodeTable::machineCodeTranslationTable.add(
  5309. new OperationCodeTable(Framework::Assembly::CMPSS,
  5310. {
  5311. // CMPSS xmm1, xmm2/m128, imm8
  5312. MachineCodeTableEntry(false,
  5313. 0xC20F,
  5314. (char)2,
  5315. XF3,
  5316. false,
  5317. false,
  5318. 0,
  5319. 0,
  5320. isFPRegister(
  5321. Framework::Assembly::MemoryBlockSize::M128),
  5322. MODRM_REG,
  5323. READWRITE,
  5324. isFPRegisterOrMEmoryAccess(
  5325. Framework::Assembly::MemoryBlockSize::M128),
  5326. MODRM_RM,
  5327. READ,
  5328. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5329. IMM8,
  5330. READ),
  5331. // VCMPSS xmm1, xmm2, xmm3/m128, imm8
  5332. MachineCodeTableEntry(false,
  5333. 0xC20F,
  5334. (char)2,
  5335. NO_PREFIX,
  5336. true,
  5337. false,
  5338. 0b10,
  5339. 0,
  5340. isFPRegister(
  5341. Framework::Assembly::MemoryBlockSize::M128),
  5342. MODRM_REG,
  5343. WRITE,
  5344. isFPRegister(
  5345. Framework::Assembly::MemoryBlockSize::M128),
  5346. VEX_VVVV,
  5347. READ,
  5348. isFPRegisterOrMEmoryAccess(
  5349. Framework::Assembly::MemoryBlockSize::M128),
  5350. MODRM_RM,
  5351. READ,
  5352. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5353. IMM8,
  5354. READ),
  5355. }));
  5356. OperationCodeTable::machineCodeTranslationTable.add(
  5357. new OperationCodeTable(Framework::Assembly::COMISD,
  5358. {// COMISD xmm1, xmm2/m64
  5359. MachineCodeTableEntry(false,
  5360. 0x2F0F,
  5361. (char)2,
  5362. X66,
  5363. false,
  5364. false,
  5365. 0,
  5366. 0,
  5367. isFPRegister(
  5368. Framework::Assembly::MemoryBlockSize::M128),
  5369. MODRM_REG,
  5370. READ,
  5371. isFPRegisterOrMEmoryAccess(
  5372. Framework::Assembly::MemoryBlockSize::M128,
  5373. Framework::Assembly::MemoryBlockSize::QWORD),
  5374. MODRM_RM,
  5375. READ)}));
  5376. OperationCodeTable::machineCodeTranslationTable.add(
  5377. new OperationCodeTable(Framework::Assembly::COMISS,
  5378. {// COMISS xmm1, xmm2/m32
  5379. MachineCodeTableEntry(false,
  5380. 0x2F0F,
  5381. (char)2,
  5382. NO_PREFIX,
  5383. false,
  5384. false,
  5385. 0,
  5386. 0,
  5387. isFPRegister(
  5388. Framework::Assembly::MemoryBlockSize::M128),
  5389. MODRM_REG,
  5390. READ,
  5391. isFPRegisterOrMEmoryAccess(
  5392. Framework::Assembly::MemoryBlockSize::M128,
  5393. Framework::Assembly::MemoryBlockSize::DWORD),
  5394. MODRM_RM,
  5395. READ)}));
  5396. OperationCodeTable::machineCodeTranslationTable.add(
  5397. new OperationCodeTable(Framework::Assembly::MOV,
  5398. {// MOV r/m8, r8
  5399. MachineCodeTableEntry(false,
  5400. 0x88,
  5401. (char)1,
  5402. NO_PREFIX,
  5403. false,
  5404. false,
  5405. 0,
  5406. 0,
  5407. isGPRegisterOrMemoryAccess(
  5408. Framework::Assembly::MemoryBlockSize::BYTE),
  5409. MODRM_RM,
  5410. WRITE,
  5411. isGPRegister(
  5412. Framework::Assembly::MemoryBlockSize::BYTE),
  5413. MODRM_REG,
  5414. READ),
  5415. // MOV r/m16, r16
  5416. MachineCodeTableEntry(false,
  5417. 0x89,
  5418. (char)1,
  5419. X66,
  5420. false,
  5421. false,
  5422. 0,
  5423. 0,
  5424. isGPRegisterOrMemoryAccess(
  5425. Framework::Assembly::MemoryBlockSize::WORD),
  5426. MODRM_RM,
  5427. WRITE,
  5428. isGPRegister(
  5429. Framework::Assembly::MemoryBlockSize::WORD),
  5430. MODRM_REG,
  5431. READ),
  5432. // MOV r/m32, r32
  5433. MachineCodeTableEntry(false,
  5434. 0x89,
  5435. (char)1,
  5436. NO_PREFIX,
  5437. false,
  5438. false,
  5439. 0,
  5440. 0,
  5441. isGPRegisterOrMemoryAccess(
  5442. Framework::Assembly::MemoryBlockSize::DWORD),
  5443. MODRM_RM,
  5444. WRITE,
  5445. isGPRegister(
  5446. Framework::Assembly::MemoryBlockSize::DWORD),
  5447. MODRM_REG,
  5448. READ),
  5449. // MOV r/m64, r64
  5450. MachineCodeTableEntry(true,
  5451. 0x89,
  5452. (char)1,
  5453. NO_PREFIX,
  5454. false,
  5455. false,
  5456. 0,
  5457. 0,
  5458. isGPRegisterOrMemoryAccess(
  5459. Framework::Assembly::MemoryBlockSize::QWORD),
  5460. MODRM_RM,
  5461. WRITE,
  5462. isGPRegister(
  5463. Framework::Assembly::MemoryBlockSize::QWORD),
  5464. MODRM_REG,
  5465. READ),
  5466. // MOV r8, r/m8
  5467. MachineCodeTableEntry(false,
  5468. 0x8A,
  5469. (char)1,
  5470. NO_PREFIX,
  5471. false,
  5472. false,
  5473. 0,
  5474. 0,
  5475. isGPRegister(
  5476. Framework::Assembly::MemoryBlockSize::BYTE),
  5477. MODRM_REG,
  5478. WRITE,
  5479. isGPRegisterOrMemoryAccess(
  5480. Framework::Assembly::MemoryBlockSize::BYTE),
  5481. MODRM_RM,
  5482. READ),
  5483. // MOV r/m16, r16
  5484. MachineCodeTableEntry(false,
  5485. 0x8B,
  5486. (char)1,
  5487. X66,
  5488. false,
  5489. false,
  5490. 0,
  5491. 0,
  5492. isGPRegister(
  5493. Framework::Assembly::MemoryBlockSize::WORD),
  5494. MODRM_REG,
  5495. WRITE,
  5496. isGPRegisterOrMemoryAccess(
  5497. Framework::Assembly::MemoryBlockSize::WORD),
  5498. MODRM_RM,
  5499. READ),
  5500. // MOV r/m32, r32
  5501. MachineCodeTableEntry(false,
  5502. 0x8B,
  5503. (char)1,
  5504. NO_PREFIX,
  5505. false,
  5506. false,
  5507. 0,
  5508. 0,
  5509. isGPRegister(
  5510. Framework::Assembly::MemoryBlockSize::DWORD),
  5511. MODRM_REG,
  5512. WRITE,
  5513. isGPRegisterOrMemoryAccess(
  5514. Framework::Assembly::MemoryBlockSize::DWORD),
  5515. MODRM_RM,
  5516. READ),
  5517. // MOV r/m64, r64
  5518. MachineCodeTableEntry(true,
  5519. 0x8B,
  5520. (char)1,
  5521. NO_PREFIX,
  5522. false,
  5523. false,
  5524. 0,
  5525. 0,
  5526. isGPRegister(
  5527. Framework::Assembly::MemoryBlockSize::QWORD),
  5528. MODRM_REG,
  5529. WRITE,
  5530. isGPRegisterOrMemoryAccess(
  5531. Framework::Assembly::MemoryBlockSize::QWORD),
  5532. MODRM_RM,
  5533. READ),
  5534. // Move imm8 to r8
  5535. MachineCodeTableEntry(false,
  5536. 0xB0,
  5537. (char)1,
  5538. NO_PREFIX,
  5539. false,
  5540. false,
  5541. 0,
  5542. 0,
  5543. isGPRegister(
  5544. Framework::Assembly::MemoryBlockSize::BYTE),
  5545. OPCODE_RD,
  5546. WRITE,
  5547. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5548. IMM8,
  5549. READ),
  5550. // MOV r16, imm16
  5551. MachineCodeTableEntry(false,
  5552. 0xB8,
  5553. (char)1,
  5554. X66,
  5555. false,
  5556. false,
  5557. 0,
  5558. 0,
  5559. isGPRegister(
  5560. Framework::Assembly::MemoryBlockSize::WORD),
  5561. OPCODE_RD,
  5562. WRITE,
  5563. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  5564. IMM16,
  5565. READ),
  5566. // MOV r32, imm32
  5567. MachineCodeTableEntry(false,
  5568. 0xB8,
  5569. (char)1,
  5570. NO_PREFIX,
  5571. false,
  5572. false,
  5573. 0,
  5574. 0,
  5575. isGPRegister(
  5576. Framework::Assembly::MemoryBlockSize::DWORD),
  5577. OPCODE_RD,
  5578. WRITE,
  5579. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  5580. IMM32,
  5581. READ),
  5582. // MOV r64, imm64
  5583. MachineCodeTableEntry(true,
  5584. 0xB8,
  5585. (char)1,
  5586. NO_PREFIX,
  5587. false,
  5588. false,
  5589. 0,
  5590. 0,
  5591. isGPRegister(
  5592. Framework::Assembly::MemoryBlockSize::QWORD),
  5593. OPCODE_RD,
  5594. WRITE,
  5595. isIMM(Framework::Assembly::MemoryBlockSize::QWORD),
  5596. IMM64,
  5597. READ),
  5598. // MOV r/m8, imm8
  5599. MachineCodeTableEntry(false,
  5600. 0xC6,
  5601. (char)1,
  5602. NO_PREFIX,
  5603. false,
  5604. false,
  5605. 0,
  5606. 0,
  5607. isGPRegisterOrMemoryAccess(
  5608. Framework::Assembly::MemoryBlockSize::BYTE),
  5609. MODRM_RM,
  5610. WRITE,
  5611. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  5612. IMM8,
  5613. READ),
  5614. // MOV r/m16, imm16
  5615. MachineCodeTableEntry(false,
  5616. 0xC7,
  5617. (char)1,
  5618. X66,
  5619. false,
  5620. false,
  5621. 0,
  5622. 0,
  5623. isGPRegisterOrMemoryAccess(
  5624. Framework::Assembly::MemoryBlockSize::WORD),
  5625. MODRM_RM,
  5626. WRITE,
  5627. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  5628. IMM16,
  5629. READ),
  5630. // MOV r/m32, imm32
  5631. MachineCodeTableEntry(false,
  5632. 0xC7,
  5633. (char)1,
  5634. NO_PREFIX,
  5635. false,
  5636. false,
  5637. 0,
  5638. 0,
  5639. isGPRegisterOrMemoryAccess(
  5640. Framework::Assembly::MemoryBlockSize::DWORD),
  5641. MODRM_RM,
  5642. WRITE,
  5643. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  5644. IMM32,
  5645. READ),
  5646. // MOV r/m64, imm64
  5647. MachineCodeTableEntry(true,
  5648. 0xC7,
  5649. (char)1,
  5650. NO_PREFIX,
  5651. false,
  5652. false,
  5653. 0,
  5654. 0,
  5655. isGPRegisterOrMemoryAccess(
  5656. Framework::Assembly::MemoryBlockSize::QWORD),
  5657. MODRM_RM,
  5658. WRITE,
  5659. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  5660. IMM32,
  5661. READ)}));
  5662. OperationCodeTable::machineCodeTranslationTable.add(
  5663. new OperationCodeTable(Framework::Assembly::MOVUPD,
  5664. {
  5665. // MOVUPD xmm1, xmm2/m128
  5666. MachineCodeTableEntry(false,
  5667. 0x100F,
  5668. (char)2,
  5669. X66,
  5670. false,
  5671. false,
  5672. 0,
  5673. 0,
  5674. isFPRegister(
  5675. Framework::Assembly::MemoryBlockSize::M128),
  5676. MODRM_REG,
  5677. WRITE,
  5678. isFPRegisterOrMEmoryAccess(
  5679. Framework::Assembly::MemoryBlockSize::M128),
  5680. MODRM_RM,
  5681. READ),
  5682. // MOVUPD xmm2/m128, xmm1
  5683. MachineCodeTableEntry(false,
  5684. 0x110F,
  5685. (char)2,
  5686. X66,
  5687. false,
  5688. false,
  5689. 0,
  5690. 0,
  5691. isFPRegisterOrMEmoryAccess(
  5692. Framework::Assembly::MemoryBlockSize::M128),
  5693. MODRM_RM,
  5694. WRITE,
  5695. isFPRegister(
  5696. Framework::Assembly::MemoryBlockSize::M128),
  5697. MODRM_REG,
  5698. READ),
  5699. // VMOVUPD ymm1, ymm2/m256
  5700. MachineCodeTableEntry(false,
  5701. 0x100F,
  5702. (char)2,
  5703. NO_PREFIX,
  5704. true,
  5705. true,
  5706. 0b01,
  5707. 0,
  5708. isFPRegister(
  5709. Framework::Assembly::MemoryBlockSize::M256),
  5710. MODRM_REG,
  5711. WRITE,
  5712. isFPRegisterOrMEmoryAccess(
  5713. Framework::Assembly::MemoryBlockSize::M256),
  5714. MODRM_RM,
  5715. READ),
  5716. // VMOVUPD ymm2/m256, ymm1
  5717. MachineCodeTableEntry(false,
  5718. 0x110F,
  5719. (char)2,
  5720. NO_PREFIX,
  5721. true,
  5722. true,
  5723. 0b01,
  5724. 0,
  5725. isFPRegisterOrMEmoryAccess(
  5726. Framework::Assembly::MemoryBlockSize::M256),
  5727. MODRM_RM,
  5728. WRITE,
  5729. isFPRegister(
  5730. Framework::Assembly::MemoryBlockSize::M256),
  5731. MODRM_REG,
  5732. READ),
  5733. }));
  5734. OperationCodeTable::machineCodeTranslationTable.add(
  5735. new OperationCodeTable(Framework::Assembly::MOVUPS,
  5736. {
  5737. // MOVUPS xmm1, xmm2/m128
  5738. MachineCodeTableEntry(false,
  5739. 0x100F,
  5740. (char)2,
  5741. NO_PREFIX,
  5742. false,
  5743. false,
  5744. 0,
  5745. 0,
  5746. isFPRegister(
  5747. Framework::Assembly::MemoryBlockSize::M128),
  5748. MODRM_REG,
  5749. WRITE,
  5750. isFPRegisterOrMEmoryAccess(
  5751. Framework::Assembly::MemoryBlockSize::M128),
  5752. MODRM_RM,
  5753. READ),
  5754. // MOVUPS xmm2/m128, xmm1
  5755. MachineCodeTableEntry(false,
  5756. 0x110F,
  5757. (char)2,
  5758. NO_PREFIX,
  5759. false,
  5760. false,
  5761. 0,
  5762. 0,
  5763. isFPRegisterOrMEmoryAccess(
  5764. Framework::Assembly::MemoryBlockSize::M128),
  5765. MODRM_RM,
  5766. WRITE,
  5767. isFPRegister(
  5768. Framework::Assembly::MemoryBlockSize::M128),
  5769. MODRM_REG,
  5770. READ),
  5771. // VMOVUPS ymm1, ymm2/m256
  5772. MachineCodeTableEntry(false,
  5773. 0x100F,
  5774. (char)2,
  5775. NO_PREFIX,
  5776. true,
  5777. true,
  5778. 0b00,
  5779. 0,
  5780. isFPRegister(
  5781. Framework::Assembly::MemoryBlockSize::M256),
  5782. MODRM_REG,
  5783. WRITE,
  5784. isFPRegisterOrMEmoryAccess(
  5785. Framework::Assembly::MemoryBlockSize::M256),
  5786. MODRM_RM,
  5787. READ),
  5788. // VMOVUPS ymm2/m256, ymm1
  5789. MachineCodeTableEntry(false,
  5790. 0x110F,
  5791. (char)2,
  5792. NO_PREFIX,
  5793. true,
  5794. true,
  5795. 0b00,
  5796. 0,
  5797. isFPRegisterOrMEmoryAccess(
  5798. Framework::Assembly::MemoryBlockSize::M256),
  5799. MODRM_RM,
  5800. WRITE,
  5801. isFPRegister(
  5802. Framework::Assembly::MemoryBlockSize::M256),
  5803. MODRM_REG,
  5804. READ),
  5805. }));
  5806. OperationCodeTable::machineCodeTranslationTable.add(
  5807. new OperationCodeTable(Framework::Assembly::MOVSD,
  5808. {
  5809. // MOVSD xmm1, xmm2/m64
  5810. MachineCodeTableEntry(false,
  5811. 0x100F,
  5812. (char)2,
  5813. XF2,
  5814. false,
  5815. false,
  5816. 0,
  5817. 0,
  5818. isFPRegister(
  5819. Framework::Assembly::MemoryBlockSize::M128),
  5820. MODRM_REG,
  5821. WRITE,
  5822. isFPRegisterOrMEmoryAccess(
  5823. Framework::Assembly::MemoryBlockSize::M128,
  5824. Framework::Assembly::MemoryBlockSize::QWORD),
  5825. MODRM_RM,
  5826. READ),
  5827. // MOVSD xmm2/m128, xmm1
  5828. MachineCodeTableEntry(false,
  5829. 0x110F,
  5830. (char)2,
  5831. XF2,
  5832. false,
  5833. false,
  5834. 0,
  5835. 0,
  5836. isFPRegisterOrMEmoryAccess(
  5837. Framework::Assembly::MemoryBlockSize::M128,
  5838. Framework::Assembly::MemoryBlockSize::QWORD),
  5839. MODRM_RM,
  5840. WRITE,
  5841. isFPRegister(
  5842. Framework::Assembly::MemoryBlockSize::M128),
  5843. MODRM_REG,
  5844. READ),
  5845. // VMOVSD VMOVSD xmm1, xmm2, xmm3
  5846. MachineCodeTableEntry(false,
  5847. 0x100F,
  5848. (char)2,
  5849. NO_PREFIX,
  5850. true,
  5851. false,
  5852. 0b11,
  5853. 0,
  5854. isFPRegister(
  5855. Framework::Assembly::MemoryBlockSize::M128),
  5856. MODRM_REG,
  5857. WRITE,
  5858. isFPRegister(
  5859. Framework::Assembly::MemoryBlockSize::M128),
  5860. VEX_VVVV,
  5861. READ,
  5862. isFPRegister(
  5863. Framework::Assembly::MemoryBlockSize::M128),
  5864. MODRM_RM,
  5865. READ),
  5866. }));
  5867. OperationCodeTable::machineCodeTranslationTable.add(
  5868. new OperationCodeTable(Framework::Assembly::MOVSS,
  5869. {
  5870. // MOVSS xmm1, xmm2/m32
  5871. MachineCodeTableEntry(false,
  5872. 0x100F,
  5873. (char)2,
  5874. XF3,
  5875. false,
  5876. false,
  5877. 0,
  5878. 0,
  5879. isFPRegister(
  5880. Framework::Assembly::MemoryBlockSize::M128),
  5881. MODRM_REG,
  5882. WRITE,
  5883. isFPRegisterOrMEmoryAccess(
  5884. Framework::Assembly::MemoryBlockSize::M128,
  5885. Framework::Assembly::MemoryBlockSize::DWORD),
  5886. MODRM_RM,
  5887. READ),
  5888. // MOVSS xmm2/m128, xmm1
  5889. MachineCodeTableEntry(false,
  5890. 0x110F,
  5891. (char)2,
  5892. XF3,
  5893. false,
  5894. false,
  5895. 0,
  5896. 0,
  5897. isFPRegisterOrMEmoryAccess(
  5898. Framework::Assembly::MemoryBlockSize::M128,
  5899. Framework::Assembly::MemoryBlockSize::QWORD),
  5900. MODRM_RM,
  5901. WRITE,
  5902. isFPRegister(
  5903. Framework::Assembly::MemoryBlockSize::M128),
  5904. MODRM_REG,
  5905. READ),
  5906. // VMOVSS VMOVSD xmm1, xmm2, xmm3
  5907. MachineCodeTableEntry(false,
  5908. 0x100F,
  5909. (char)2,
  5910. NO_PREFIX,
  5911. true,
  5912. false,
  5913. 0b10,
  5914. 0,
  5915. isFPRegister(
  5916. Framework::Assembly::MemoryBlockSize::M128),
  5917. MODRM_REG,
  5918. WRITE,
  5919. isFPRegister(
  5920. Framework::Assembly::MemoryBlockSize::M128),
  5921. VEX_VVVV,
  5922. READ,
  5923. isFPRegister(
  5924. Framework::Assembly::MemoryBlockSize::M128),
  5925. MODRM_RM,
  5926. READ),
  5927. }));
  5928. OperationCodeTable::machineCodeTranslationTable.add(
  5929. new OperationCodeTable(Framework::Assembly::LEA,
  5930. {
  5931. // LEA r16,m
  5932. MachineCodeTableEntry(
  5933. false,
  5934. 0x8D,
  5935. (char)1,
  5936. X66,
  5937. false,
  5938. false,
  5939. 0,
  5940. 0,
  5941. isGPRegister(
  5942. Framework::Assembly::MemoryBlockSize::WORD),
  5943. MODRM_REG,
  5944. WRITE,
  5945. [](const Framework::Assembly::OperationArgument& p) {
  5946. return p.asMemoryAccessArgument();
  5947. },
  5948. MODRM_RM,
  5949. READ),
  5950. // LEA r32,m
  5951. MachineCodeTableEntry(
  5952. false,
  5953. 0x8D,
  5954. (char)1,
  5955. NO_PREFIX,
  5956. false,
  5957. false,
  5958. 0,
  5959. 0,
  5960. isGPRegister(
  5961. Framework::Assembly::MemoryBlockSize::DWORD),
  5962. MODRM_REG,
  5963. WRITE,
  5964. [](const Framework::Assembly::OperationArgument& p) {
  5965. return p.asMemoryAccessArgument();
  5966. },
  5967. MODRM_RM,
  5968. READ),
  5969. // LEA r64,m
  5970. MachineCodeTableEntry(
  5971. true,
  5972. 0x8D,
  5973. (char)1,
  5974. NO_PREFIX,
  5975. false,
  5976. false,
  5977. 0,
  5978. 0,
  5979. isGPRegister(
  5980. Framework::Assembly::MemoryBlockSize::QWORD),
  5981. MODRM_REG,
  5982. WRITE,
  5983. [](const Framework::Assembly::OperationArgument& p) {
  5984. return p.asMemoryAccessArgument();
  5985. },
  5986. MODRM_RM,
  5987. READ),
  5988. }));
  5989. OperationCodeTable::machineCodeTranslationTable.add(
  5990. new OperationCodeTable(Framework::Assembly::CVTSI2SD,
  5991. {
  5992. // CVTSI2SD xmm1, r32/m32
  5993. MachineCodeTableEntry(false,
  5994. 0x2A0F,
  5995. (char)2,
  5996. XF3,
  5997. false,
  5998. false,
  5999. 0,
  6000. 0,
  6001. isFPRegister(
  6002. Framework::Assembly::MemoryBlockSize::M128),
  6003. MODRM_REG,
  6004. WRITE,
  6005. isGPRegisterOrMemoryAccess(
  6006. Framework::Assembly::MemoryBlockSize::DWORD),
  6007. MODRM_RM,
  6008. READ),
  6009. // CVTSI2SD xmm1, r64/m64
  6010. MachineCodeTableEntry(true,
  6011. 0x2A0F,
  6012. (char)2,
  6013. XF3,
  6014. false,
  6015. false,
  6016. 0,
  6017. 0,
  6018. isFPRegister(
  6019. Framework::Assembly::MemoryBlockSize::M128),
  6020. MODRM_REG,
  6021. WRITE,
  6022. isGPRegisterOrMemoryAccess(
  6023. Framework::Assembly::MemoryBlockSize::QWORD),
  6024. MODRM_RM,
  6025. READ),
  6026. }));
  6027. OperationCodeTable::machineCodeTranslationTable.add(
  6028. new OperationCodeTable(Framework::Assembly::CVTTSD2SI,
  6029. {
  6030. // CVTTSD2SI r32, xmm1/m64
  6031. MachineCodeTableEntry(false,
  6032. 0x2C0F,
  6033. (char)2,
  6034. XF2,
  6035. false,
  6036. false,
  6037. 0,
  6038. 0,
  6039. isGPRegister(
  6040. Framework::Assembly::MemoryBlockSize::DWORD),
  6041. MODRM_REG,
  6042. WRITE,
  6043. isFPRegisterOrMEmoryAccess(
  6044. Framework::Assembly::MemoryBlockSize::M128,
  6045. Framework::Assembly::MemoryBlockSize::QWORD),
  6046. MODRM_RM,
  6047. READ),
  6048. // CVTTSD2SI r64, xmm1/m64
  6049. MachineCodeTableEntry(true,
  6050. 0x2C0F,
  6051. (char)2,
  6052. XF2,
  6053. false,
  6054. false,
  6055. 0,
  6056. 0,
  6057. isGPRegister(
  6058. Framework::Assembly::MemoryBlockSize::QWORD),
  6059. MODRM_REG,
  6060. WRITE,
  6061. isFPRegisterOrMEmoryAccess(
  6062. Framework::Assembly::MemoryBlockSize::M128,
  6063. Framework::Assembly::MemoryBlockSize::QWORD),
  6064. MODRM_RM,
  6065. READ),
  6066. }));
  6067. OperationCodeTable::machineCodeTranslationTable.add(
  6068. new OperationCodeTable(Framework::Assembly::CVTTSS2SI,
  6069. {
  6070. // CVTTSS2SI r32, xmm1/m32
  6071. MachineCodeTableEntry(false,
  6072. 0x2C0F,
  6073. (char)2,
  6074. XF3,
  6075. false,
  6076. false,
  6077. 0,
  6078. 0,
  6079. isGPRegister(
  6080. Framework::Assembly::MemoryBlockSize::DWORD),
  6081. MODRM_REG,
  6082. WRITE,
  6083. isFPRegisterOrMEmoryAccess(
  6084. Framework::Assembly::MemoryBlockSize::M128,
  6085. Framework::Assembly::MemoryBlockSize::DWORD),
  6086. MODRM_RM,
  6087. READ),
  6088. // CVTTSS2SI r64, xmm1/m32
  6089. MachineCodeTableEntry(true,
  6090. 0x2C0F,
  6091. (char)2,
  6092. XF3,
  6093. false,
  6094. false,
  6095. 0,
  6096. 0,
  6097. isGPRegister(
  6098. Framework::Assembly::MemoryBlockSize::QWORD),
  6099. MODRM_REG,
  6100. WRITE,
  6101. isFPRegisterOrMEmoryAccess(
  6102. Framework::Assembly::MemoryBlockSize::M128,
  6103. Framework::Assembly::MemoryBlockSize::DWORD),
  6104. MODRM_RM,
  6105. READ),
  6106. }));
  6107. OperationCodeTable::machineCodeTranslationTable.add(
  6108. new OperationCodeTable(Framework::Assembly::CVTSD2SI,
  6109. {
  6110. // CVTSD2SI r32, xmm1/m64
  6111. MachineCodeTableEntry(false,
  6112. 0x2D0F,
  6113. (char)2,
  6114. XF2,
  6115. false,
  6116. false,
  6117. 0,
  6118. 0,
  6119. isGPRegister(
  6120. Framework::Assembly::MemoryBlockSize::DWORD),
  6121. MODRM_REG,
  6122. WRITE,
  6123. isFPRegisterOrMEmoryAccess(
  6124. Framework::Assembly::MemoryBlockSize::M128,
  6125. Framework::Assembly::MemoryBlockSize::QWORD),
  6126. MODRM_RM,
  6127. READ),
  6128. // CVTSD2SI r64, xmm1/m64
  6129. MachineCodeTableEntry(true,
  6130. 0x2D0F,
  6131. (char)2,
  6132. XF2,
  6133. false,
  6134. false,
  6135. 0,
  6136. 0,
  6137. isGPRegister(
  6138. Framework::Assembly::MemoryBlockSize::QWORD),
  6139. MODRM_REG,
  6140. WRITE,
  6141. isFPRegisterOrMEmoryAccess(
  6142. Framework::Assembly::MemoryBlockSize::M128,
  6143. Framework::Assembly::MemoryBlockSize::QWORD),
  6144. MODRM_RM,
  6145. READ),
  6146. }));
  6147. OperationCodeTable::machineCodeTranslationTable.add(
  6148. new OperationCodeTable(Framework::Assembly::CVTSS2SI,
  6149. {
  6150. // CVTSS2SI r32, xmm1/m32
  6151. MachineCodeTableEntry(false,
  6152. 0x2D0F,
  6153. (char)2,
  6154. XF3,
  6155. false,
  6156. false,
  6157. 0,
  6158. 0,
  6159. isGPRegister(
  6160. Framework::Assembly::MemoryBlockSize::DWORD),
  6161. MODRM_REG,
  6162. WRITE,
  6163. isFPRegisterOrMEmoryAccess(
  6164. Framework::Assembly::MemoryBlockSize::M128,
  6165. Framework::Assembly::MemoryBlockSize::DWORD),
  6166. MODRM_RM,
  6167. READ),
  6168. // CVTSS2SI r64, xmm1/m32
  6169. MachineCodeTableEntry(true,
  6170. 0x2D0F,
  6171. (char)2,
  6172. XF3,
  6173. false,
  6174. false,
  6175. 0,
  6176. 0,
  6177. isGPRegister(
  6178. Framework::Assembly::MemoryBlockSize::QWORD),
  6179. MODRM_REG,
  6180. WRITE,
  6181. isFPRegisterOrMEmoryAccess(
  6182. Framework::Assembly::MemoryBlockSize::M128,
  6183. Framework::Assembly::MemoryBlockSize::DWORD),
  6184. MODRM_RM,
  6185. READ),
  6186. }));
  6187. OperationCodeTable::machineCodeTranslationTable.add(
  6188. new OperationCodeTable(Framework::Assembly::CVTSI2SS,
  6189. {
  6190. // CVTSI2SS xmm1, r32/m32
  6191. MachineCodeTableEntry(false,
  6192. 0x2A0F,
  6193. (char)2,
  6194. XF2,
  6195. false,
  6196. false,
  6197. 0,
  6198. 0,
  6199. isFPRegister(
  6200. Framework::Assembly::MemoryBlockSize::M128),
  6201. MODRM_REG,
  6202. WRITE,
  6203. isGPRegisterOrMemoryAccess(
  6204. Framework::Assembly::MemoryBlockSize::DWORD),
  6205. MODRM_RM,
  6206. READ),
  6207. // CVTSI2SS xmm1, r64/m64
  6208. MachineCodeTableEntry(true,
  6209. 0x2A0F,
  6210. (char)2,
  6211. XF2,
  6212. false,
  6213. false,
  6214. 0,
  6215. 0,
  6216. isFPRegister(
  6217. Framework::Assembly::MemoryBlockSize::M128),
  6218. MODRM_REG,
  6219. WRITE,
  6220. isGPRegisterOrMemoryAccess(
  6221. Framework::Assembly::MemoryBlockSize::QWORD),
  6222. MODRM_RM,
  6223. READ),
  6224. }));
  6225. OperationCodeTable::machineCodeTranslationTable.add(
  6226. new JumpOperationCodeTable(Framework::Assembly::JMP,
  6227. 1,
  6228. {// JMP rel32
  6229. MachineCodeTableEntry(false,
  6230. 0xE9,
  6231. (char)1,
  6232. NO_PREFIX,
  6233. false,
  6234. false,
  6235. 0,
  6236. 0,
  6237. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6238. IMM32,
  6239. READ)}));
  6240. OperationCodeTable::machineCodeTranslationTable.add(
  6241. new JumpOperationCodeTable(Framework::Assembly::JZ,
  6242. 2,
  6243. {// JZ rel32
  6244. MachineCodeTableEntry(false,
  6245. 0x840F,
  6246. (char)2,
  6247. NO_PREFIX,
  6248. false,
  6249. false,
  6250. 0,
  6251. 0,
  6252. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6253. IMM32,
  6254. READ)}));
  6255. OperationCodeTable::machineCodeTranslationTable.add(
  6256. new JumpOperationCodeTable(Framework::Assembly::JNZ,
  6257. 2,
  6258. {// JNZ rel32
  6259. MachineCodeTableEntry(false,
  6260. 0x850F,
  6261. (char)2,
  6262. NO_PREFIX,
  6263. false,
  6264. false,
  6265. 0,
  6266. 0,
  6267. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6268. IMM32,
  6269. READ)}));
  6270. OperationCodeTable::machineCodeTranslationTable.add(
  6271. new JumpOperationCodeTable(Framework::Assembly::JG,
  6272. 2,
  6273. {// JG rel32
  6274. MachineCodeTableEntry(false,
  6275. 0x8F0F,
  6276. (char)2,
  6277. NO_PREFIX,
  6278. false,
  6279. false,
  6280. 0,
  6281. 0,
  6282. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6283. IMM32,
  6284. READ)}));
  6285. OperationCodeTable::machineCodeTranslationTable.add(
  6286. new JumpOperationCodeTable(Framework::Assembly::JGE,
  6287. 2,
  6288. {// JGE rel32
  6289. MachineCodeTableEntry(false,
  6290. 0x8D0F,
  6291. (char)2,
  6292. NO_PREFIX,
  6293. false,
  6294. false,
  6295. 0,
  6296. 0,
  6297. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6298. IMM32,
  6299. READ)}));
  6300. OperationCodeTable::machineCodeTranslationTable.add(
  6301. new JumpOperationCodeTable(Framework::Assembly::JL,
  6302. 2,
  6303. {// JL rel32
  6304. MachineCodeTableEntry(false,
  6305. 0x8C0F,
  6306. (char)2,
  6307. NO_PREFIX,
  6308. false,
  6309. false,
  6310. 0,
  6311. 0,
  6312. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6313. IMM32,
  6314. READ)}));
  6315. OperationCodeTable::machineCodeTranslationTable.add(
  6316. new JumpOperationCodeTable(Framework::Assembly::JLE,
  6317. 2,
  6318. {// JLE rel32
  6319. MachineCodeTableEntry(false,
  6320. 0x8E0F,
  6321. (char)2,
  6322. NO_PREFIX,
  6323. false,
  6324. false,
  6325. 0,
  6326. 0,
  6327. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6328. IMM32,
  6329. READ)}));
  6330. OperationCodeTable::machineCodeTranslationTable.add(
  6331. new JumpOperationCodeTable(Framework::Assembly::JA,
  6332. 2,
  6333. {// JA rel32
  6334. MachineCodeTableEntry(false,
  6335. 0x870F,
  6336. (char)2,
  6337. NO_PREFIX,
  6338. false,
  6339. false,
  6340. 0,
  6341. 0,
  6342. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6343. IMM32,
  6344. READ)}));
  6345. OperationCodeTable::machineCodeTranslationTable.add(
  6346. new JumpOperationCodeTable(Framework::Assembly::JC,
  6347. 2,
  6348. {// JC rel32
  6349. MachineCodeTableEntry(false,
  6350. 0x820F,
  6351. (char)2,
  6352. NO_PREFIX,
  6353. false,
  6354. false,
  6355. 0,
  6356. 0,
  6357. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6358. IMM32,
  6359. READ)}));
  6360. OperationCodeTable::machineCodeTranslationTable.add(
  6361. new JumpOperationCodeTable(Framework::Assembly::JNC,
  6362. 2,
  6363. {// JNC rel32
  6364. MachineCodeTableEntry(false,
  6365. 0x830F,
  6366. (char)2,
  6367. NO_PREFIX,
  6368. false,
  6369. false,
  6370. 0,
  6371. 0,
  6372. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6373. IMM32,
  6374. READ)}));
  6375. OperationCodeTable::machineCodeTranslationTable.add(
  6376. new JumpOperationCodeTable(Framework::Assembly::JBE,
  6377. 2,
  6378. {// JBE rel32
  6379. MachineCodeTableEntry(false,
  6380. 0x860F,
  6381. (char)2,
  6382. NO_PREFIX,
  6383. false,
  6384. false,
  6385. 0,
  6386. 0,
  6387. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6388. IMM32,
  6389. READ)}));
  6390. OperationCodeTable::machineCodeTranslationTable.add(
  6391. new JumpOperationCodeTable(Framework::Assembly::JO,
  6392. 2,
  6393. {// JO rel32
  6394. MachineCodeTableEntry(false,
  6395. 0x800F,
  6396. (char)2,
  6397. NO_PREFIX,
  6398. false,
  6399. false,
  6400. 0,
  6401. 0,
  6402. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6403. IMM32,
  6404. READ)}));
  6405. OperationCodeTable::machineCodeTranslationTable.add(
  6406. new JumpOperationCodeTable(Framework::Assembly::JNO,
  6407. 2,
  6408. {// JNO rel32
  6409. MachineCodeTableEntry(false,
  6410. 0x810F,
  6411. (char)2,
  6412. NO_PREFIX,
  6413. false,
  6414. false,
  6415. 0,
  6416. 0,
  6417. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6418. IMM32,
  6419. READ)}));
  6420. OperationCodeTable::machineCodeTranslationTable.add(
  6421. new JumpOperationCodeTable(Framework::Assembly::JP,
  6422. 2,
  6423. {// JP rel32
  6424. MachineCodeTableEntry(false,
  6425. 0x8A0F,
  6426. (char)2,
  6427. NO_PREFIX,
  6428. false,
  6429. false,
  6430. 0,
  6431. 0,
  6432. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6433. IMM32,
  6434. READ)}));
  6435. OperationCodeTable::machineCodeTranslationTable.add(
  6436. new JumpOperationCodeTable(Framework::Assembly::JNP,
  6437. 2,
  6438. {// JNP rel32
  6439. MachineCodeTableEntry(false,
  6440. 0x8B0F,
  6441. (char)2,
  6442. NO_PREFIX,
  6443. false,
  6444. false,
  6445. 0,
  6446. 0,
  6447. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6448. IMM32,
  6449. READ)}));
  6450. OperationCodeTable::machineCodeTranslationTable.add(
  6451. new JumpOperationCodeTable(Framework::Assembly::JS,
  6452. 2,
  6453. {// JS rel32
  6454. MachineCodeTableEntry(false,
  6455. 0x880F,
  6456. (char)2,
  6457. NO_PREFIX,
  6458. false,
  6459. false,
  6460. 0,
  6461. 0,
  6462. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6463. IMM32,
  6464. READ)}));
  6465. OperationCodeTable::machineCodeTranslationTable.add(
  6466. new JumpOperationCodeTable(Framework::Assembly::JNS,
  6467. 2,
  6468. {// JNS rel32
  6469. MachineCodeTableEntry(false,
  6470. 0x890F,
  6471. (char)2,
  6472. NO_PREFIX,
  6473. false,
  6474. false,
  6475. 0,
  6476. 0,
  6477. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6478. IMM32,
  6479. READ)}));
  6480. OperationCodeTable::machineCodeTranslationTable.add(
  6481. new OperationCodeTable(Framework::Assembly::CALL,
  6482. {// CALL rel32
  6483. MachineCodeTableEntry(false,
  6484. 0xE8,
  6485. (char)1,
  6486. NO_PREFIX,
  6487. false,
  6488. false,
  6489. 0,
  6490. 0,
  6491. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6492. IMM32,
  6493. READ),
  6494. // CALL r/m64
  6495. MachineCodeTableEntry(false,
  6496. 0xFF,
  6497. (char)1,
  6498. NO_PREFIX,
  6499. false,
  6500. false,
  6501. 0,
  6502. 0b010,
  6503. isGPRegisterOrMemoryAccess(
  6504. Framework::Assembly::MemoryBlockSize::QWORD),
  6505. MODRM_RM,
  6506. READ)}));
  6507. OperationCodeTable::machineCodeTranslationTable.add(
  6508. new OperationCodeTable(Framework::Assembly::RET,
  6509. {// RET
  6510. MachineCodeTableEntry(
  6511. false, 0xC3, (char)1, NO_PREFIX, false, false, 0, 0)}));
  6512. OperationCodeTable::machineCodeTranslationTable.add(
  6513. new OperationCodeTable(Framework::Assembly::PUSH,
  6514. {
  6515. // PUSH r/m16
  6516. MachineCodeTableEntry(false,
  6517. 0xFF,
  6518. (char)1,
  6519. X66,
  6520. false,
  6521. false,
  6522. 0,
  6523. 0b110,
  6524. isGPRegisterOrMemoryAccess(
  6525. Framework::Assembly::MemoryBlockSize::WORD),
  6526. MODRM_RM,
  6527. READ),
  6528. // PUSH r/m64
  6529. MachineCodeTableEntry(false,
  6530. 0xFF,
  6531. (char)1,
  6532. NO_PREFIX,
  6533. false,
  6534. false,
  6535. 0,
  6536. 0b110,
  6537. isGPRegisterOrMemoryAccess(
  6538. Framework::Assembly::MemoryBlockSize::QWORD),
  6539. MODRM_RM,
  6540. READ),
  6541. // PUSH imm8
  6542. MachineCodeTableEntry(false,
  6543. 0x6A,
  6544. (char)1,
  6545. NO_PREFIX,
  6546. false,
  6547. false,
  6548. 0,
  6549. 0,
  6550. isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
  6551. IMM8,
  6552. READ),
  6553. // PUSH imm16
  6554. MachineCodeTableEntry(false,
  6555. 0x68,
  6556. (char)1,
  6557. X66,
  6558. false,
  6559. false,
  6560. 0,
  6561. 0,
  6562. isIMM(Framework::Assembly::MemoryBlockSize::WORD),
  6563. IMM16,
  6564. READ),
  6565. // PUSH imm32
  6566. MachineCodeTableEntry(false,
  6567. 0x68,
  6568. (char)1,
  6569. NO_PREFIX,
  6570. false,
  6571. false,
  6572. 0,
  6573. 0,
  6574. isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
  6575. IMM32,
  6576. READ),
  6577. }));
  6578. OperationCodeTable::machineCodeTranslationTable.add(
  6579. new OperationCodeTable(Framework::Assembly::POP,
  6580. {
  6581. // POP r/m16
  6582. MachineCodeTableEntry(false,
  6583. 0x8F,
  6584. (char)1,
  6585. X66,
  6586. false,
  6587. false,
  6588. 0,
  6589. 0,
  6590. isGPRegisterOrMemoryAccess(
  6591. Framework::Assembly::MemoryBlockSize::WORD),
  6592. MODRM_RM,
  6593. READ),
  6594. // POP r/m64
  6595. MachineCodeTableEntry(false,
  6596. 0x8F,
  6597. (char)1,
  6598. NO_PREFIX,
  6599. false,
  6600. false,
  6601. 0,
  6602. 0,
  6603. isGPRegisterOrMemoryAccess(
  6604. Framework::Assembly::MemoryBlockSize::QWORD),
  6605. MODRM_RM,
  6606. READ),
  6607. }));
  6608. }
  6609. OperationCodeTable::machineCodeTranslationTableLock.unlock();
  6610. }
  6611. bool Framework::Assembly::OperationArgument::usesRegister(GPRegister reg) const
  6612. {
  6613. return false;
  6614. }
  6615. bool Framework::Assembly::OperationArgument::usesRegister(FPRegister reg) const
  6616. {
  6617. return false;
  6618. }
  6619. void Framework::Assembly::OperationArgument::replaceRegister(
  6620. GPRegister oldReg, GPRegister newReg)
  6621. {}
  6622. void Framework::Assembly::OperationArgument::replaceRegister(
  6623. FPRegister oldReg, FPRegister newReg)
  6624. {}
  6625. void Framework::Assembly::OperationArgument::addJumpLabelPrefix(
  6626. Text labelPrefix)
  6627. {}
  6628. const Framework::Assembly::GPRegisterArgument*
  6629. Framework::Assembly::OperationArgument::asGPRegisterArgument() const
  6630. {
  6631. return dynamic_cast<const GPRegisterArgument*>(this);
  6632. }
  6633. const Framework::Assembly::MemoryAccessArgument*
  6634. Framework::Assembly::OperationArgument::asMemoryAccessArgument() const
  6635. {
  6636. return dynamic_cast<const MemoryAccessArgument*>(this);
  6637. }
  6638. const Framework::Assembly::ConstantArgument*
  6639. Framework::Assembly::OperationArgument::asConstantArgument() const
  6640. {
  6641. return dynamic_cast<const ConstantArgument*>(this);
  6642. }
  6643. const Framework::Assembly::FPRegisterArgument*
  6644. Framework::Assembly::OperationArgument::asFPRegisterArgument() const
  6645. {
  6646. return dynamic_cast<const FPRegisterArgument*>(this);
  6647. }
  6648. const Framework::Assembly::JumpTargetArgument*
  6649. Framework::Assembly::OperationArgument::asJumpTargetArgument() const
  6650. {
  6651. return dynamic_cast<const JumpTargetArgument*>(this);
  6652. }
  6653. Framework::Assembly::GPRegisterArgument::GPRegisterArgument(
  6654. GPRegister reg, GPRegisterPart part)
  6655. : reg(reg),
  6656. part(part)
  6657. {}
  6658. bool Framework::Assembly::GPRegisterArgument::usesRegister(GPRegister reg) const
  6659. {
  6660. return this->reg == reg;
  6661. }
  6662. void Framework::Assembly::GPRegisterArgument::replaceRegister(
  6663. GPRegister oldReg, GPRegister newReg)
  6664. {
  6665. if (reg == oldReg)
  6666. {
  6667. reg = newReg;
  6668. }
  6669. }
  6670. Framework::Assembly::GPRegister
  6671. Framework::Assembly::GPRegisterArgument::getRegister() const
  6672. {
  6673. return reg;
  6674. }
  6675. Framework::Assembly::GPRegisterPart
  6676. Framework::Assembly::GPRegisterArgument::getPart() const
  6677. {
  6678. return part;
  6679. }
  6680. Framework::Assembly::FPRegisterArgument::FPRegisterArgument(
  6681. FPRegister reg, FPRegisterPart part)
  6682. : reg(reg),
  6683. part(part)
  6684. {}
  6685. bool Framework::Assembly::FPRegisterArgument::usesRegister(FPRegister reg) const
  6686. {
  6687. return this->reg == reg;
  6688. }
  6689. void Framework::Assembly::FPRegisterArgument::replaceRegister(
  6690. FPRegister oldReg, FPRegister newReg)
  6691. {
  6692. if (reg == oldReg)
  6693. {
  6694. reg = newReg;
  6695. }
  6696. }
  6697. Framework::Assembly::FPRegister
  6698. Framework::Assembly::FPRegisterArgument::getRegister() const
  6699. {
  6700. return reg;
  6701. }
  6702. Framework::Assembly::FPRegisterPart
  6703. Framework::Assembly::FPRegisterArgument::getPart() const
  6704. {
  6705. return part;
  6706. }
  6707. Framework::Assembly::MemoryAccessArgument::MemoryAccessArgument(
  6708. MemoryBlockSize blockSize,
  6709. GPRegister address,
  6710. bool useAddressReg,
  6711. int offset,
  6712. bool useOffsetReg,
  6713. GPRegister offsetReg)
  6714. : blockSize(blockSize),
  6715. useAddressReg(useAddressReg),
  6716. address(address),
  6717. offset(offset),
  6718. offsetReg(offsetReg),
  6719. useOffsetReg(useOffsetReg)
  6720. {}
  6721. bool Framework::Assembly::MemoryAccessArgument::usesRegister(
  6722. GPRegister reg) const
  6723. {
  6724. return (useAddressReg && this->address == reg)
  6725. || (useOffsetReg && offsetReg == reg);
  6726. }
  6727. void Framework::Assembly::MemoryAccessArgument::replaceRegister(
  6728. GPRegister oldReg, GPRegister newReg)
  6729. {
  6730. if (useAddressReg && address == oldReg)
  6731. {
  6732. address = newReg;
  6733. }
  6734. if (useOffsetReg && offsetReg == oldReg)
  6735. {
  6736. offsetReg = newReg;
  6737. }
  6738. }
  6739. bool Framework::Assembly::MemoryAccessArgument::isUsingAddressRegister() const
  6740. {
  6741. return useAddressReg;
  6742. }
  6743. Framework::Assembly::GPRegister
  6744. Framework::Assembly::MemoryAccessArgument::getAddressRegister() const
  6745. {
  6746. return address;
  6747. }
  6748. int Framework::Assembly::MemoryAccessArgument::getOffset() const
  6749. {
  6750. return offset;
  6751. }
  6752. bool Framework::Assembly::MemoryAccessArgument::isUsingOffsetRegister() const
  6753. {
  6754. return useOffsetReg;
  6755. }
  6756. Framework::Assembly::GPRegister
  6757. Framework::Assembly::MemoryAccessArgument::getOffsetRegister() const
  6758. {
  6759. return offsetReg;
  6760. }
  6761. Framework::Assembly::MemoryBlockSize
  6762. Framework::Assembly::MemoryAccessArgument::getBlockSize() const
  6763. {
  6764. return blockSize;
  6765. }
  6766. Framework::Assembly::ConstantArgument::ConstantArgument(
  6767. __int64 value, MemoryBlockSize size)
  6768. : value(value),
  6769. size(size)
  6770. {}
  6771. Framework::Assembly::ConstantArgument::ConstantArgument(
  6772. int value, MemoryBlockSize size)
  6773. : value((__int64)value),
  6774. size(size)
  6775. {}
  6776. Framework::Assembly::ConstantArgument::ConstantArgument(
  6777. short value, MemoryBlockSize size)
  6778. : value((__int64)value),
  6779. size(size)
  6780. {}
  6781. Framework::Assembly::ConstantArgument::ConstantArgument(
  6782. char value, MemoryBlockSize size)
  6783. : value((__int64)value),
  6784. size(size)
  6785. {}
  6786. __int64 Framework::Assembly::ConstantArgument::getValue() const
  6787. {
  6788. return value;
  6789. }
  6790. Framework::Assembly::MemoryBlockSize
  6791. Framework::Assembly::ConstantArgument::getSize() const
  6792. {
  6793. return size;
  6794. }
  6795. Framework::Assembly::JumpTargetArgument::JumpTargetArgument(Text name)
  6796. : name(name)
  6797. {}
  6798. void Framework::Assembly::JumpTargetArgument::addJumpLabelPrefix(
  6799. Text labelPrefix)
  6800. {
  6801. name = labelPrefix + name;
  6802. }
  6803. const Framework::Text& Framework::Assembly::JumpTargetArgument::getLabel() const
  6804. {
  6805. return name;
  6806. }
  6807. Framework::Assembly::Instruction::Instruction(
  6808. Operation op, std::initializer_list<OperationArgument*> args)
  6809. : Instruction(op, args, {}, {}, {}, {})
  6810. {}
  6811. Framework::Assembly::Instruction::Instruction(Operation op,
  6812. std::initializer_list<OperationArgument*> params,
  6813. std::initializer_list<GPRegister> implicitReadGPs,
  6814. std::initializer_list<FPRegister> implicitReadFPs,
  6815. std::initializer_list<GPRegister> implicitWriteGPs,
  6816. std::initializer_list<FPRegister> implicitWriteFPs)
  6817. : ReferenceCounter(),
  6818. op(op),
  6819. args(params),
  6820. implicitReadGPs(implicitReadGPs),
  6821. implicitReadFPs(implicitReadFPs),
  6822. implicitWriteGPs(implicitWriteGPs),
  6823. implicitWriteFPs(implicitWriteFPs)
  6824. {}
  6825. Framework::Assembly::Instruction::~Instruction()
  6826. {
  6827. for (auto arg : args)
  6828. {
  6829. delete arg;
  6830. }
  6831. }
  6832. bool Framework::Assembly::Instruction::writesToRegister(
  6833. GPRegister reg, const AssemblyBlock* block) const
  6834. {
  6835. for (GPRegister r : implicitWriteGPs)
  6836. {
  6837. if (r == reg)
  6838. {
  6839. return 0;
  6840. }
  6841. }
  6842. __intializeMachineCodeTranslationTable();
  6843. for (OperationCodeTable* tableEntry :
  6844. OperationCodeTable::machineCodeTranslationTable)
  6845. {
  6846. if (tableEntry->getOperation() == op)
  6847. {
  6848. Framework::Text err;
  6849. MachineCodeTableEntry* entry
  6850. = tableEntry->getEntry(args, block, this, err);
  6851. if (entry)
  6852. {
  6853. for (GPRegister r : entry->getImpliedWriteGPRegs())
  6854. {
  6855. if (r == reg)
  6856. {
  6857. return 1;
  6858. }
  6859. }
  6860. int index = 0;
  6861. for (const OperationArgument* arg : args)
  6862. {
  6863. OperandRW rw = entry->getOperandRW(index);
  6864. if (rw == WRITE || rw == READWRITE)
  6865. {
  6866. if (arg->asGPRegisterArgument()
  6867. && arg->asGPRegisterArgument()->getRegister()
  6868. == reg)
  6869. {
  6870. return 1;
  6871. }
  6872. }
  6873. index++;
  6874. }
  6875. }
  6876. }
  6877. }
  6878. return 0;
  6879. }
  6880. bool Framework::Assembly::Instruction::writesToRegister(
  6881. FPRegister reg, const AssemblyBlock* block) const
  6882. {
  6883. for (FPRegister r : implicitWriteFPs)
  6884. {
  6885. if (r == reg)
  6886. {
  6887. return 0;
  6888. }
  6889. }
  6890. __intializeMachineCodeTranslationTable();
  6891. for (OperationCodeTable* tableEntry :
  6892. OperationCodeTable::machineCodeTranslationTable)
  6893. {
  6894. if (tableEntry->getOperation() == op)
  6895. {
  6896. Framework::Text err;
  6897. MachineCodeTableEntry* entry
  6898. = tableEntry->getEntry(args, block, this, err);
  6899. if (entry)
  6900. {
  6901. for (FPRegister r : entry->getImpliedWriteFPRegs())
  6902. {
  6903. if (r == reg)
  6904. {
  6905. return 1;
  6906. }
  6907. }
  6908. int index = 0;
  6909. for (const OperationArgument* arg : args)
  6910. {
  6911. OperandRW rw = entry->getOperandRW(index);
  6912. if (rw == WRITE || rw == READWRITE)
  6913. {
  6914. if (arg->asFPRegisterArgument()
  6915. && arg->asFPRegisterArgument()->getRegister()
  6916. == reg)
  6917. {
  6918. return 1;
  6919. }
  6920. }
  6921. index++;
  6922. }
  6923. }
  6924. }
  6925. }
  6926. return 0;
  6927. }
  6928. bool Framework::Assembly::Instruction::readsFromRegister(
  6929. GPRegister reg, const AssemblyBlock* block) const
  6930. {
  6931. for (GPRegister r : implicitReadGPs)
  6932. {
  6933. if (r == reg)
  6934. {
  6935. return 0;
  6936. }
  6937. }
  6938. __intializeMachineCodeTranslationTable();
  6939. for (OperationCodeTable* tableEntry :
  6940. OperationCodeTable::machineCodeTranslationTable)
  6941. {
  6942. if (tableEntry->getOperation() == op)
  6943. {
  6944. Framework::Text err;
  6945. MachineCodeTableEntry* entry
  6946. = tableEntry->getEntry(args, block, this, err);
  6947. if (entry)
  6948. {
  6949. for (GPRegister r : entry->getImpliedReadGPRegs())
  6950. {
  6951. if (r == reg)
  6952. {
  6953. return 1;
  6954. }
  6955. }
  6956. int index = 0;
  6957. for (const OperationArgument* arg : args)
  6958. {
  6959. OperandRW rw = entry->getOperandRW(index);
  6960. if (rw == READ || rw == READWRITE)
  6961. {
  6962. if (arg->asGPRegisterArgument()
  6963. && arg->asGPRegisterArgument()->getRegister()
  6964. == reg)
  6965. {
  6966. return 1;
  6967. }
  6968. }
  6969. if (arg->asMemoryAccessArgument()
  6970. && arg->asMemoryAccessArgument()->usesRegister(reg))
  6971. {
  6972. return 1;
  6973. }
  6974. index++;
  6975. }
  6976. }
  6977. }
  6978. }
  6979. return 0;
  6980. }
  6981. bool Framework::Assembly::Instruction::readsFromRegister(
  6982. FPRegister reg, const AssemblyBlock* block) const
  6983. {
  6984. for (FPRegister r : implicitReadFPs)
  6985. {
  6986. if (r == reg)
  6987. {
  6988. return 0;
  6989. }
  6990. }
  6991. __intializeMachineCodeTranslationTable();
  6992. for (OperationCodeTable* tableEntry :
  6993. OperationCodeTable::machineCodeTranslationTable)
  6994. {
  6995. if (tableEntry->getOperation() == op)
  6996. {
  6997. Framework::Text err;
  6998. MachineCodeTableEntry* entry
  6999. = tableEntry->getEntry(args, block, this, err);
  7000. if (entry)
  7001. {
  7002. for (FPRegister r : entry->getImpliedReadFPRegs())
  7003. {
  7004. if (r == reg)
  7005. {
  7006. return 1;
  7007. }
  7008. }
  7009. int index = 0;
  7010. for (const OperationArgument* arg : args)
  7011. {
  7012. OperandRW rw = entry->getOperandRW(index);
  7013. if (rw == READ || rw == READWRITE)
  7014. {
  7015. if (arg->asFPRegisterArgument()
  7016. && arg->asFPRegisterArgument()->getRegister()
  7017. == reg)
  7018. {
  7019. return 1;
  7020. }
  7021. }
  7022. index++;
  7023. }
  7024. }
  7025. }
  7026. }
  7027. return 0;
  7028. }
  7029. bool Framework::Assembly::Instruction::isReplacementPossible(
  7030. GPRegister oldReg, GPRegister newReg, const AssemblyBlock* block) const
  7031. {
  7032. for (GPRegister r : implicitReadGPs)
  7033. {
  7034. if (r == oldReg)
  7035. {
  7036. return 0;
  7037. }
  7038. }
  7039. for (GPRegister r : implicitWriteGPs)
  7040. {
  7041. if (r == oldReg)
  7042. {
  7043. return 0;
  7044. }
  7045. }
  7046. __intializeMachineCodeTranslationTable();
  7047. for (OperationCodeTable* tableEntry :
  7048. OperationCodeTable::machineCodeTranslationTable)
  7049. {
  7050. if (tableEntry->getOperation() == op)
  7051. {
  7052. Framework::Text err;
  7053. MachineCodeTableEntry* entry
  7054. = tableEntry->getEntry(args, block, this, err);
  7055. if (entry)
  7056. {
  7057. for (GPRegister r : entry->getImpliedReadGPRegs())
  7058. {
  7059. if (r == oldReg)
  7060. {
  7061. return 0;
  7062. }
  7063. }
  7064. for (GPRegister r : entry->getImpliedWriteGPRegs())
  7065. {
  7066. if (r == oldReg)
  7067. {
  7068. return 0;
  7069. }
  7070. }
  7071. }
  7072. }
  7073. }
  7074. if (this->readsFromRegister(newReg, block)
  7075. || this->writesToRegister(newReg, block))
  7076. {
  7077. return 0;
  7078. }
  7079. if (newReg == RBP || newReg == RSI || newReg == RDI)
  7080. {
  7081. if (oldReg == RBP || oldReg == RSI || oldReg == RDI)
  7082. {
  7083. return 1;
  7084. }
  7085. else
  7086. {
  7087. return 0;
  7088. }
  7089. }
  7090. if (newReg >= R8)
  7091. {
  7092. return oldReg >= R8;
  7093. }
  7094. return oldReg < R8;
  7095. }
  7096. bool Framework::Assembly::Instruction::isReplacementPossible(
  7097. FPRegister oldReg, FPRegister newReg, const AssemblyBlock* block) const
  7098. {
  7099. for (FPRegister r : implicitReadFPs)
  7100. {
  7101. if (r == oldReg)
  7102. {
  7103. return 0;
  7104. }
  7105. }
  7106. for (FPRegister r : implicitWriteFPs)
  7107. {
  7108. if (r == oldReg)
  7109. {
  7110. return 0;
  7111. }
  7112. }
  7113. __intializeMachineCodeTranslationTable();
  7114. for (OperationCodeTable* tableEntry :
  7115. OperationCodeTable::machineCodeTranslationTable)
  7116. {
  7117. if (tableEntry->getOperation() == op)
  7118. {
  7119. Framework::Text err;
  7120. MachineCodeTableEntry* entry
  7121. = tableEntry->getEntry(args, block, this, err);
  7122. if (entry)
  7123. {
  7124. for (FPRegister r : entry->getImpliedReadFPRegs())
  7125. {
  7126. if (r == oldReg)
  7127. {
  7128. return 0;
  7129. }
  7130. }
  7131. for (FPRegister r : entry->getImpliedWriteFPRegs())
  7132. {
  7133. if (r == oldReg)
  7134. {
  7135. return 0;
  7136. }
  7137. }
  7138. }
  7139. }
  7140. }
  7141. if (this->readsFromRegister(newReg, block)
  7142. || this->writesToRegister(newReg, block))
  7143. {
  7144. return 0;
  7145. }
  7146. return 1;
  7147. }
  7148. void Framework::Assembly::Instruction::replaceRegister(
  7149. GPRegister oldReg, GPRegister newReg)
  7150. {
  7151. for (auto arg : args)
  7152. {
  7153. arg->replaceRegister(oldReg, newReg);
  7154. }
  7155. }
  7156. void Framework::Assembly::Instruction::replaceRegister(
  7157. FPRegister oldReg, FPRegister newReg)
  7158. {
  7159. for (auto arg : args)
  7160. {
  7161. arg->replaceRegister(oldReg, newReg);
  7162. }
  7163. }
  7164. void Framework::Assembly::Instruction::addJumpLabelPrefix(Text labelPrefix)
  7165. {
  7166. for (auto arg : args)
  7167. {
  7168. arg->addJumpLabelPrefix(labelPrefix);
  7169. }
  7170. }
  7171. void Framework::Assembly::Instruction::compile(
  7172. StreamWriter* byteCodeWriter, const AssemblyBlock* block) const
  7173. {
  7174. if (op == NOP)
  7175. {
  7176. return;
  7177. }
  7178. Framework::Text err;
  7179. __intializeMachineCodeTranslationTable();
  7180. for (OperationCodeTable* tableEntry :
  7181. OperationCodeTable::machineCodeTranslationTable)
  7182. {
  7183. if (tableEntry->getOperation() == op)
  7184. {
  7185. MachineCodeInstruction instr
  7186. = tableEntry->getInstruction(args, block, this, err);
  7187. if (err.getLength())
  7188. {
  7189. throw err;
  7190. }
  7191. instr.write(*byteCodeWriter);
  7192. return;
  7193. }
  7194. }
  7195. err.append() << "Failed to compile instruction: operation code " << (int)op
  7196. << " not found in translation table. args: \n";
  7197. for (auto arg : args)
  7198. {
  7199. err.append() << " " << typeid(*arg).name() << "\n";
  7200. }
  7201. throw err;
  7202. }
  7203. bool Framework::Assembly::Instruction::isValid(const AssemblyBlock* block) const
  7204. {
  7205. __intializeMachineCodeTranslationTable();
  7206. for (OperationCodeTable* tableEntry :
  7207. OperationCodeTable::machineCodeTranslationTable)
  7208. {
  7209. if (tableEntry->getOperation() == op)
  7210. {
  7211. Framework::Text err;
  7212. tableEntry->getInstruction(args, block, this, err);
  7213. return err.getLength() == 0;
  7214. }
  7215. }
  7216. return false;
  7217. }
  7218. int Framework::Assembly::Instruction::compiledSize(
  7219. const AssemblyBlock* block) const
  7220. {
  7221. __intializeMachineCodeTranslationTable();
  7222. for (OperationCodeTable* tableEntry :
  7223. OperationCodeTable::machineCodeTranslationTable)
  7224. {
  7225. if (tableEntry->getOperation() == op)
  7226. {
  7227. Framework::Text err;
  7228. MachineCodeInstruction instr
  7229. = tableEntry->getInstruction(args, block, this, err);
  7230. if (err.getLength())
  7231. {
  7232. throw err;
  7233. }
  7234. return instr.calculateSize();
  7235. }
  7236. }
  7237. return 0;
  7238. }
  7239. Framework::Assembly::Operation
  7240. Framework::Assembly::Instruction::getOperation() const
  7241. {
  7242. return op;
  7243. }
  7244. bool Framework::Assembly::Instruction::definesLabel(Text label) const
  7245. {
  7246. return op == NOP && args.size() == 1 && args.at(0)->asJumpTargetArgument()
  7247. && args.at(0)->asJumpTargetArgument()->getLabel().isEqual(label);
  7248. }
  7249. const std::vector<Framework::Assembly::OperationArgument*>&
  7250. Framework::Assembly::Instruction::getArguments() const
  7251. {
  7252. return args;
  7253. }
  7254. Framework::Assembly::AssemblyBlock::AssemblyBlock()
  7255. : inlineIndex(0),
  7256. compiledCode(0)
  7257. #ifndef WIN32
  7258. ,
  7259. compiledSize(0)
  7260. #endif
  7261. {}
  7262. Framework::Assembly::AssemblyBlock::~AssemblyBlock()
  7263. {
  7264. if (compiledCode != 0)
  7265. {
  7266. // Free the compiled code memory
  7267. #ifdef WIN32
  7268. VirtualFree(compiledCode, 0, MEM_RELEASE);
  7269. #else
  7270. munmap(compiledCode, compiledSize);
  7271. #endif
  7272. }
  7273. }
  7274. void Framework::Assembly::AssemblyBlock::addInstruction(Instruction* instr)
  7275. {
  7276. instructions.add(instr);
  7277. }
  7278. void Framework::Assembly::AssemblyBlock::defineJumpTarget(Text name)
  7279. {
  7280. instructions.add(new Instruction(NOP, {new JumpTargetArgument(name)}));
  7281. }
  7282. void Framework::Assembly::AssemblyBlock::addJump(
  7283. Operation jumpOp, Text targetName)
  7284. {
  7285. instructions.add(
  7286. new Instruction(jumpOp, {new JumpTargetArgument(targetName)}));
  7287. }
  7288. void Framework::Assembly::AssemblyBlock::addAddition(
  7289. GPRegister target, GPRegister source, GPRegisterPart part)
  7290. {
  7291. instructions.add(new Instruction(ADD,
  7292. {new GPRegisterArgument(target, part),
  7293. new GPRegisterArgument(source, part)}));
  7294. }
  7295. void Framework::Assembly::AssemblyBlock::addAddition(
  7296. GPRegister target, char value, GPRegisterPart part)
  7297. {
  7298. instructions.add(new Instruction(ADD,
  7299. {new GPRegisterArgument(target, part), new ConstantArgument(value)}));
  7300. }
  7301. void Framework::Assembly::AssemblyBlock::addAddition(
  7302. GPRegister target, int value, GPRegisterPart part)
  7303. {
  7304. instructions.add(new Instruction(ADD,
  7305. {new GPRegisterArgument(target, part), new ConstantArgument(value)}));
  7306. }
  7307. void Framework::Assembly::AssemblyBlock::addAddition(
  7308. FPRegister target, FPRegister source, FPDataType type, FPRegisterPart part)
  7309. {
  7310. Operation op = NOP;
  7311. switch (type)
  7312. {
  7313. case SINGLE_FLOAT:
  7314. op = ADDSS;
  7315. break;
  7316. case SINGLE_DOUBLE:
  7317. op = ADDSD;
  7318. break;
  7319. case PACKED_FLOAT:
  7320. op = ADDPS;
  7321. break;
  7322. case PACKED_DOUBLE:
  7323. op = ADDPD;
  7324. break;
  7325. }
  7326. instructions.add(new Instruction(op,
  7327. {new FPRegisterArgument(target, part),
  7328. new FPRegisterArgument(source, part)}));
  7329. }
  7330. void Framework::Assembly::AssemblyBlock::addSubtraction(
  7331. GPRegister target, GPRegister source, GPRegisterPart part)
  7332. {
  7333. instructions.add(new Instruction(SUB,
  7334. {new GPRegisterArgument(target, part),
  7335. new GPRegisterArgument(source, part)}));
  7336. }
  7337. void Framework::Assembly::AssemblyBlock::addSubtraction(
  7338. GPRegister target, char value, GPRegisterPart part)
  7339. {
  7340. instructions.add(new Instruction(SUB,
  7341. {new GPRegisterArgument(target, part), new ConstantArgument(value)}));
  7342. }
  7343. void Framework::Assembly::AssemblyBlock::addSubtraction(
  7344. GPRegister target, int value, GPRegisterPart part)
  7345. {
  7346. instructions.add(new Instruction(SUB,
  7347. {new GPRegisterArgument(target, part), new ConstantArgument(value)}));
  7348. }
  7349. void Framework::Assembly::AssemblyBlock::addSubtraction(
  7350. FPRegister target, FPRegister source, FPDataType type, FPRegisterPart part)
  7351. {
  7352. Operation op = NOP;
  7353. switch (type)
  7354. {
  7355. case SINGLE_FLOAT:
  7356. op = SUBSS;
  7357. break;
  7358. case SINGLE_DOUBLE:
  7359. op = SUBSD;
  7360. break;
  7361. case PACKED_FLOAT:
  7362. op = SUBPS;
  7363. break;
  7364. case PACKED_DOUBLE:
  7365. op = SUBPD;
  7366. break;
  7367. }
  7368. instructions.add(new Instruction(op,
  7369. {new FPRegisterArgument(target, part),
  7370. new FPRegisterArgument(source, part)}));
  7371. }
  7372. void Framework::Assembly::AssemblyBlock::addMultiplication(
  7373. GPRegister target, GPRegister source, GPRegisterPart part)
  7374. {
  7375. instructions.add(new Instruction(IMUL,
  7376. {new GPRegisterArgument(target, part),
  7377. new GPRegisterArgument(source, part)}));
  7378. }
  7379. void Framework::Assembly::AssemblyBlock::addMultiplication(
  7380. FPRegister target, FPRegister source, FPDataType type, FPRegisterPart part)
  7381. {
  7382. Operation op = NOP;
  7383. switch (type)
  7384. {
  7385. case SINGLE_FLOAT:
  7386. op = MULSS;
  7387. break;
  7388. case SINGLE_DOUBLE:
  7389. op = MULSD;
  7390. break;
  7391. case PACKED_FLOAT:
  7392. op = MULPS;
  7393. break;
  7394. case PACKED_DOUBLE:
  7395. op = MULPD;
  7396. break;
  7397. }
  7398. instructions.add(new Instruction(op,
  7399. {new FPRegisterArgument(target, part),
  7400. new FPRegisterArgument(source, part)}));
  7401. }
  7402. void Framework::Assembly::AssemblyBlock::addDivision(
  7403. GPRegister target, GPRegister source, GPRegisterPart part)
  7404. {
  7405. instructions.add(new Instruction(DIV,
  7406. {new GPRegisterArgument(target, part),
  7407. new GPRegisterArgument(source, part)}));
  7408. }
  7409. void Framework::Assembly::AssemblyBlock::addDivision(
  7410. FPRegister target, FPRegister source, FPDataType type, FPRegisterPart part)
  7411. {
  7412. Operation op = NOP;
  7413. switch (type)
  7414. {
  7415. case SINGLE_FLOAT:
  7416. op = DIVSS;
  7417. break;
  7418. case SINGLE_DOUBLE:
  7419. op = DIVSD;
  7420. break;
  7421. case PACKED_FLOAT:
  7422. op = DIVPS;
  7423. break;
  7424. case PACKED_DOUBLE:
  7425. op = DIVPD;
  7426. break;
  7427. }
  7428. instructions.add(new Instruction(op,
  7429. {new FPRegisterArgument(target, part),
  7430. new FPRegisterArgument(source, part)}));
  7431. }
  7432. void Framework::Assembly::AssemblyBlock::addTest(
  7433. GPRegister r1, GPRegister r2, GPRegisterPart part)
  7434. {
  7435. instructions.add(new Instruction(TEST,
  7436. {new GPRegisterArgument(r1, part), new GPRegisterArgument(r2, part)}));
  7437. }
  7438. void Framework::Assembly::AssemblyBlock::addCompare(
  7439. GPRegister r1, GPRegister r2, GPRegisterPart part)
  7440. {
  7441. instructions.add(new Instruction(CMP,
  7442. {new GPRegisterArgument(r1, part), new GPRegisterArgument(r2, part)}));
  7443. }
  7444. void Framework::Assembly::AssemblyBlock::addCompare(GPRegister r1, char value)
  7445. {
  7446. instructions.add(new Instruction(CMP,
  7447. {new GPRegisterArgument(r1, LOWER8), new ConstantArgument(value)}));
  7448. }
  7449. void Framework::Assembly::AssemblyBlock::addCompare(GPRegister r1, short value)
  7450. {
  7451. instructions.add(new Instruction(CMP,
  7452. {new GPRegisterArgument(r1, LOWER16), new ConstantArgument(value)}));
  7453. }
  7454. void Framework::Assembly::AssemblyBlock::addCompare(GPRegister r1, int value)
  7455. {
  7456. instructions.add(new Instruction(CMP,
  7457. {new GPRegisterArgument(r1, LOWER32), new ConstantArgument(value)}));
  7458. }
  7459. void Framework::Assembly::AssemblyBlock::addCompare(
  7460. FPRegister r1, FPRegister r2, FPDataType type)
  7461. {
  7462. Operation op = NOP;
  7463. switch (type)
  7464. {
  7465. case SINGLE_FLOAT:
  7466. op = COMISS;
  7467. break;
  7468. case SINGLE_DOUBLE:
  7469. op = COMISD;
  7470. break;
  7471. default:
  7472. break;
  7473. }
  7474. if (op != NOP)
  7475. {
  7476. instructions.add(new Instruction(op,
  7477. {new FPRegisterArgument(r1, FPRegisterPart::X),
  7478. new FPRegisterArgument(r2, FPRegisterPart::X)}));
  7479. }
  7480. }
  7481. void Framework::Assembly::AssemblyBlock::addAnd(
  7482. GPRegister target, GPRegister source, GPRegisterPart part)
  7483. {
  7484. instructions.add(new Instruction(AND,
  7485. {new GPRegisterArgument(target, part),
  7486. new GPRegisterArgument(source, part)}));
  7487. }
  7488. void Framework::Assembly::AssemblyBlock::addOr(
  7489. GPRegister target, GPRegister source, GPRegisterPart part)
  7490. {
  7491. instructions.add(new Instruction(OR,
  7492. {new GPRegisterArgument(target, part),
  7493. new GPRegisterArgument(source, part)}));
  7494. }
  7495. void Framework::Assembly::AssemblyBlock::addLoadValue(
  7496. char* valueAddress, GPRegister target)
  7497. {
  7498. instructions.add(new Instruction(MOV,
  7499. {new GPRegisterArgument(target),
  7500. new ConstantArgument(reinterpret_cast<__int64>(valueAddress))}));
  7501. instructions.add(new Instruction(MOV,
  7502. {new GPRegisterArgument(target, LOWER8),
  7503. new MemoryAccessArgument(MemoryBlockSize::BYTE, target)}));
  7504. }
  7505. void Framework::Assembly::AssemblyBlock::addLoadValue(
  7506. short* valueAddress, GPRegister target)
  7507. {
  7508. instructions.add(new Instruction(MOV,
  7509. {new GPRegisterArgument(target),
  7510. new ConstantArgument(reinterpret_cast<__int64>(valueAddress))}));
  7511. instructions.add(new Instruction(MOV,
  7512. {new GPRegisterArgument(target, LOWER16),
  7513. new MemoryAccessArgument(MemoryBlockSize::WORD, target)}));
  7514. }
  7515. void Framework::Assembly::AssemblyBlock::addLoadValue(
  7516. int* valueAddress, GPRegister target)
  7517. {
  7518. instructions.add(new Instruction(MOV,
  7519. {new GPRegisterArgument(target),
  7520. new ConstantArgument(reinterpret_cast<__int64>(valueAddress))}));
  7521. instructions.add(new Instruction(MOV,
  7522. {new GPRegisterArgument(target, LOWER32),
  7523. new MemoryAccessArgument(MemoryBlockSize::DWORD, target)}));
  7524. }
  7525. void Framework::Assembly::AssemblyBlock::addLoadValue(
  7526. __int64* valueAddress, GPRegister target)
  7527. {
  7528. instructions.add(new Instruction(MOV,
  7529. {new GPRegisterArgument(target),
  7530. new ConstantArgument(reinterpret_cast<__int64>(valueAddress))}));
  7531. instructions.add(new Instruction(MOV,
  7532. {new GPRegisterArgument(target),
  7533. new MemoryAccessArgument(MemoryBlockSize::QWORD, target)}));
  7534. }
  7535. void Framework::Assembly::AssemblyBlock::addLoadValue(
  7536. GPRegister addressRegister,
  7537. GPRegister target,
  7538. GPRegisterPart targetPart,
  7539. int offset)
  7540. {
  7541. instructions.add(new Instruction(MOV,
  7542. {new GPRegisterArgument(target, targetPart),
  7543. new MemoryAccessArgument(
  7544. (targetPart == LOWER8 || targetPart == HIGHER8)
  7545. ? MemoryBlockSize::BYTE
  7546. : (targetPart == LOWER16
  7547. ? MemoryBlockSize::WORD
  7548. : (targetPart == LOWER32
  7549. ? MemoryBlockSize::DWORD
  7550. : MemoryBlockSize::QWORD)),
  7551. addressRegister,
  7552. true,
  7553. offset)}));
  7554. }
  7555. void Framework::Assembly::AssemblyBlock::addLoadValue(
  7556. float* valueAddress, FPRegister target, GPRegister temp)
  7557. {
  7558. instructions.add(new Instruction(MOV,
  7559. {new GPRegisterArgument(temp),
  7560. new ConstantArgument(reinterpret_cast<__int64>(valueAddress))}));
  7561. instructions.add(new Instruction(MOVSS,
  7562. {new FPRegisterArgument(target),
  7563. new MemoryAccessArgument(MemoryBlockSize::DWORD, temp)}));
  7564. }
  7565. void Framework::Assembly::AssemblyBlock::addLoadValue(
  7566. double* valueAddress, FPRegister target, GPRegister temp)
  7567. {
  7568. instructions.add(new Instruction(MOV,
  7569. {new GPRegisterArgument(temp),
  7570. new ConstantArgument(reinterpret_cast<__int64>(valueAddress))}));
  7571. instructions.add(new Instruction(MOVSD,
  7572. {new FPRegisterArgument(target),
  7573. new MemoryAccessArgument(MemoryBlockSize::QWORD, temp)}));
  7574. }
  7575. void Framework::Assembly::AssemblyBlock::addMoveValue(
  7576. GPRegister target, char value)
  7577. {
  7578. instructions.add(new Instruction(MOV,
  7579. {new GPRegisterArgument(target, LOWER8), new ConstantArgument(value)}));
  7580. }
  7581. void Framework::Assembly::AssemblyBlock::addMoveValue(
  7582. GPRegister target, short value)
  7583. {
  7584. instructions.add(new Instruction(MOV,
  7585. {new GPRegisterArgument(target, LOWER16),
  7586. new ConstantArgument(value)}));
  7587. }
  7588. void Framework::Assembly::AssemblyBlock::addMoveValue(
  7589. GPRegister target, int value)
  7590. {
  7591. instructions.add(new Instruction(MOV,
  7592. {new GPRegisterArgument(target, LOWER32),
  7593. new ConstantArgument(value)}));
  7594. }
  7595. void Framework::Assembly::AssemblyBlock::addMoveValue(
  7596. GPRegister target, __int64 value)
  7597. {
  7598. instructions.add(new Instruction(
  7599. MOV, {new GPRegisterArgument(target), new ConstantArgument(value)}));
  7600. }
  7601. void Framework::Assembly::AssemblyBlock::addMoveValue(
  7602. FPRegister target, float value, GPRegister temp)
  7603. {
  7604. int data = *reinterpret_cast<int*>(&value);
  7605. addMoveValue(temp, data);
  7606. addPush(temp);
  7607. instructions.add(new Instruction(MOVSS,
  7608. {new FPRegisterArgument(target, X),
  7609. new MemoryAccessArgument(MemoryBlockSize::DWORD, RSP)}));
  7610. addPop(temp);
  7611. }
  7612. void Framework::Assembly::AssemblyBlock::addMoveValue(
  7613. FPRegister target, double value, GPRegister temp)
  7614. {
  7615. __int64 data = *reinterpret_cast<__int64*>(&value);
  7616. addMoveValue(temp, data);
  7617. addPush(temp);
  7618. instructions.add(new Instruction(MOVSD,
  7619. {new FPRegisterArgument(target, X),
  7620. new MemoryAccessArgument(MemoryBlockSize::QWORD, RSP)}));
  7621. addPop(temp);
  7622. }
  7623. void Framework::Assembly::AssemblyBlock::addMoveValue(
  7624. GPRegister target, GPRegister source, GPRegisterPart part)
  7625. {
  7626. instructions.add(new Instruction(MOV,
  7627. {new GPRegisterArgument(target, part),
  7628. new GPRegisterArgument(source, part)}));
  7629. }
  7630. void Framework::Assembly::AssemblyBlock::addMoveValue(
  7631. FPRegister target, FPRegister source, FPDataType type, FPRegisterPart part)
  7632. {
  7633. Operation op = NOP;
  7634. switch (type)
  7635. {
  7636. case SINGLE_FLOAT:
  7637. op = MOVSS;
  7638. break;
  7639. case SINGLE_DOUBLE:
  7640. op = MOVSD;
  7641. break;
  7642. case PACKED_FLOAT:
  7643. op = MOVUPS;
  7644. break;
  7645. case PACKED_DOUBLE:
  7646. op = MOVUPD;
  7647. break;
  7648. }
  7649. instructions.add(new Instruction(op,
  7650. {new FPRegisterArgument(target, part),
  7651. new FPRegisterArgument(source, part)}));
  7652. }
  7653. void Framework::Assembly::AssemblyBlock::addConversion(GPRegister target,
  7654. FPRegister source,
  7655. FPDataType type,
  7656. GPRegisterPart targetPart,
  7657. bool round)
  7658. {
  7659. Operation op = NOP;
  7660. if (type == SINGLE_DOUBLE)
  7661. {
  7662. op = round ? CVTSD2SI : CVTTSD2SI;
  7663. }
  7664. else if (type == SINGLE_FLOAT)
  7665. {
  7666. op = round ? CVTSS2SI : CVTTSS2SI;
  7667. }
  7668. instructions.add(new Instruction(op,
  7669. {new GPRegisterArgument(target, targetPart),
  7670. new FPRegisterArgument(source, X)}));
  7671. }
  7672. void Framework::Assembly::AssemblyBlock::addConversion(FPRegister target,
  7673. GPRegister source,
  7674. FPDataType targetType,
  7675. GPRegisterPart sourcePart)
  7676. {
  7677. Operation op = NOP;
  7678. if (targetType == SINGLE_DOUBLE)
  7679. {
  7680. op = CVTSI2SD;
  7681. }
  7682. else if (targetType == SINGLE_FLOAT)
  7683. {
  7684. op = CVTSI2SS;
  7685. }
  7686. instructions.add(new Instruction(op,
  7687. {new FPRegisterArgument(target, X),
  7688. new GPRegisterArgument(source, sourcePart)}));
  7689. }
  7690. void Framework::Assembly::AssemblyBlock::addCall(void* functionAddress,
  7691. FuncReturnType returnType,
  7692. std::initializer_list<GPRegister> gpParams,
  7693. std::initializer_list<FPRegister> fpParams,
  7694. GPRegister temp,
  7695. GPRegister bpTemp)
  7696. {
  7697. if (isVolatile(bpTemp) || bpTemp == RSP)
  7698. {
  7699. throw "Temporary register for base pointer must be a non-volatile "
  7700. "register (not RAX, RCX, RDX, R8, R9, R10, R11) and not RSP";
  7701. }
  7702. // enshure calling conventions
  7703. // save stack pointer value to bpTemp
  7704. addMoveValue(bpTemp, RSP);
  7705. // align stack pointer to 16 bytes
  7706. instructions.add(new Instruction(
  7707. AND, {new GPRegisterArgument(RSP), new ConstantArgument(-16)}));
  7708. // allocate shadow space
  7709. instructions.add(new Instruction(
  7710. SUB, {new GPRegisterArgument(RSP), new ConstantArgument(32)}));
  7711. // load function address into temp register
  7712. instructions.add(new Instruction(MOV,
  7713. {new GPRegisterArgument(temp),
  7714. new ConstantArgument(reinterpret_cast<__int64>(functionAddress))}));
  7715. // call the function
  7716. if (returnType == INT_VALUE)
  7717. {
  7718. instructions.add(new Instruction(CALL,
  7719. {new GPRegisterArgument(temp)},
  7720. gpParams,
  7721. fpParams,
  7722. {RAX},
  7723. {}));
  7724. }
  7725. else if (returnType == FLOAT_VALUE)
  7726. {
  7727. instructions.add(new Instruction(CALL,
  7728. {new GPRegisterArgument(temp)},
  7729. gpParams,
  7730. fpParams,
  7731. {},
  7732. {MM0}));
  7733. }
  7734. else
  7735. {
  7736. instructions.add(new Instruction(
  7737. CALL, {new GPRegisterArgument(temp)}, gpParams, fpParams, {}, {}));
  7738. }
  7739. // restore stack pointer
  7740. addMoveValue(RSP, bpTemp);
  7741. }
  7742. void Framework::Assembly::AssemblyBlock::addReturn()
  7743. {
  7744. instructions.add(new Instruction(RET, {}));
  7745. }
  7746. void Framework::Assembly::AssemblyBlock::addPush(
  7747. GPRegister reg, GPRegisterPart part)
  7748. {
  7749. GPRegisterPart pushPart = part;
  7750. if (part == LOWER8 || part == HIGHER8)
  7751. {
  7752. pushPart = LOWER16;
  7753. }
  7754. if (part == LOWER32)
  7755. {
  7756. pushPart = FULL64;
  7757. }
  7758. instructions.add(
  7759. new Instruction(PUSH, {new GPRegisterArgument(reg, pushPart)}));
  7760. }
  7761. void Framework::Assembly::AssemblyBlock::addPop(
  7762. GPRegister reg, GPRegisterPart part)
  7763. {
  7764. GPRegisterPart popPart = part;
  7765. if (part == LOWER8 || part == HIGHER8)
  7766. {
  7767. popPart = LOWER16;
  7768. }
  7769. if (part == LOWER32)
  7770. {
  7771. popPart = FULL64;
  7772. }
  7773. instructions.add(
  7774. new Instruction(POP, {new GPRegisterArgument(reg, popPart)}));
  7775. }
  7776. void Framework::Assembly::AssemblyBlock::addPush(
  7777. FPRegister reg, FPDataType type, FPRegisterPart part)
  7778. {
  7779. MemoryBlockSize size = MemoryBlockSize::BYTE;
  7780. int bytes = 0;
  7781. Operation moveOp = NOP;
  7782. switch (type)
  7783. {
  7784. case SINGLE_DOUBLE:
  7785. moveOp = MOVSD;
  7786. bytes = 8;
  7787. size = MemoryBlockSize::QWORD;
  7788. part = X;
  7789. break;
  7790. case SINGLE_FLOAT:
  7791. moveOp = MOVSS;
  7792. bytes = 4;
  7793. size = MemoryBlockSize::DWORD;
  7794. part = X;
  7795. break;
  7796. case PACKED_DOUBLE:
  7797. moveOp = MOVUPD;
  7798. bytes = part == X ? 16 : 32;
  7799. size = part == X ? MemoryBlockSize::M128 : MemoryBlockSize::M256;
  7800. case PACKED_FLOAT:
  7801. moveOp = MOVUPS;
  7802. bytes = part == X ? 16 : 32;
  7803. size = part == X ? MemoryBlockSize::M128 : MemoryBlockSize::M256;
  7804. }
  7805. instructions.add(new Instruction(
  7806. SUB, {new GPRegisterArgument(RSP), new ConstantArgument(bytes)}));
  7807. instructions.add(new Instruction(moveOp,
  7808. {new MemoryAccessArgument(size, RSP),
  7809. new FPRegisterArgument(reg, part)}));
  7810. }
  7811. void Framework::Assembly::AssemblyBlock::addPop(
  7812. FPRegister reg, FPDataType type, FPRegisterPart part)
  7813. {
  7814. addPop(instructions, reg, type, part);
  7815. }
  7816. void Framework::Assembly::AssemblyBlock::addPop(
  7817. RCArray<Instruction>& instructionList,
  7818. FPRegister reg,
  7819. FPDataType type,
  7820. FPRegisterPart part)
  7821. {
  7822. MemoryBlockSize size = MemoryBlockSize::BYTE;
  7823. int bytes = 0;
  7824. Operation moveOp = NOP;
  7825. switch (type)
  7826. {
  7827. case SINGLE_DOUBLE:
  7828. moveOp = MOVSD;
  7829. bytes = 8;
  7830. size = MemoryBlockSize::QWORD;
  7831. part = X;
  7832. break;
  7833. case SINGLE_FLOAT:
  7834. moveOp = MOVSS;
  7835. bytes = 4;
  7836. size = MemoryBlockSize::DWORD;
  7837. part = X;
  7838. break;
  7839. case PACKED_DOUBLE:
  7840. moveOp = MOVUPD;
  7841. bytes = part == X ? 16 : 32;
  7842. size = part == X ? MemoryBlockSize::M128 : MemoryBlockSize::M256;
  7843. case PACKED_FLOAT:
  7844. moveOp = MOVUPS;
  7845. bytes = part == X ? 16 : 32;
  7846. size = part == X ? MemoryBlockSize::M128 : MemoryBlockSize::M256;
  7847. }
  7848. instructionList.add(new Instruction(moveOp,
  7849. {new FPRegisterArgument(reg, part),
  7850. new MemoryAccessArgument(size, RSP)}));
  7851. instructionList.add(new Instruction(
  7852. ADD, {new GPRegisterArgument(RSP), new ConstantArgument(bytes)}));
  7853. }
  7854. void Framework::Assembly::AssemblyBlock::addBlock(AssemblyBlock* block,
  7855. std::initializer_list<GPRegister> preservedGPRegisters,
  7856. std::initializer_list<FPRegister> preservedFPRegisters,
  7857. std::initializer_list<FPDataType> preservedFPDataTypes,
  7858. GPRegister* blockResultGpReg,
  7859. FPRegister* blockResultFpReg)
  7860. {
  7861. std::vector<FPDataType> fpTypes(preservedFPDataTypes);
  7862. bool containsCall = false;
  7863. for (const auto& instr : block->instructions)
  7864. {
  7865. if (instr->getOperation() == CALL)
  7866. {
  7867. containsCall = true; // volatile registers that should be preserved
  7868. // needs to be pushed to the stack
  7869. break;
  7870. }
  7871. }
  7872. RCArray<Instruction> tempInstructions;
  7873. for (GPRegister preservedReg : preservedGPRegisters)
  7874. {
  7875. if (block->writesToRegister(preservedReg))
  7876. {
  7877. bool replaced = false;
  7878. for (int i = 0; i < 16; i++)
  7879. {
  7880. if (i == 4 || i == 5 || preservedReg == RSP
  7881. || preservedReg == RBP)
  7882. {
  7883. continue; // Skip RSP and RBP (stack counter register)
  7884. }
  7885. if (!containsCall
  7886. || (isVolatile(preservedReg)
  7887. == isVolatile((Framework::Assembly::GPRegister)i)))
  7888. { // call inside the block -> only replace volatile with
  7889. // volatile and non volatile with non volatile registers
  7890. bool found = false;
  7891. for (GPRegister r : preservedGPRegisters)
  7892. {
  7893. if (r == (GPRegister)i)
  7894. {
  7895. found = true;
  7896. break;
  7897. }
  7898. }
  7899. if (found)
  7900. {
  7901. continue;
  7902. }
  7903. GPRegister newReg = (GPRegister)i;
  7904. if (block->isReplacementPossible(preservedReg, newReg))
  7905. {
  7906. if (blockResultGpReg)
  7907. {
  7908. if (preservedReg == *blockResultGpReg)
  7909. {
  7910. *blockResultGpReg = newReg;
  7911. }
  7912. }
  7913. replaced = true;
  7914. block->replaceRegister(preservedReg, newReg);
  7915. break;
  7916. }
  7917. }
  7918. }
  7919. if (!replaced)
  7920. {
  7921. addPush(preservedReg);
  7922. tempInstructions.add(
  7923. new Instruction(
  7924. POP, {new GPRegisterArgument(preservedReg)}),
  7925. 0);
  7926. }
  7927. }
  7928. }
  7929. int index = 0;
  7930. for (FPRegister preservedReg : preservedFPRegisters)
  7931. {
  7932. if (block->writesToRegister(preservedReg))
  7933. {
  7934. bool replaced = false;
  7935. for (int i = 0; i < __FP_REGISTER_COUNT; i++)
  7936. {
  7937. if (!containsCall
  7938. || (isVolatile(preservedReg) == isVolatile((FPRegister)i)))
  7939. { // call inside the block -> only replace volatile with
  7940. // volatile and non volatile with non volatile registers
  7941. bool found = false;
  7942. for (FPRegister r : preservedFPRegisters)
  7943. {
  7944. if (r == (FPRegister)i)
  7945. {
  7946. found = true;
  7947. break;
  7948. }
  7949. }
  7950. if (found)
  7951. {
  7952. continue;
  7953. }
  7954. FPRegister newReg = (FPRegister)i;
  7955. if (block->isReplacementPossible(preservedReg, newReg))
  7956. {
  7957. if (blockResultFpReg)
  7958. {
  7959. if (preservedReg == *blockResultFpReg)
  7960. {
  7961. *blockResultFpReg = newReg;
  7962. }
  7963. }
  7964. replaced = true;
  7965. block->replaceRegister(preservedReg, newReg);
  7966. break;
  7967. }
  7968. }
  7969. }
  7970. if (!replaced)
  7971. {
  7972. // TODO: search for last instruction that wrote to preservedReg
  7973. // to find its data type
  7974. addPush(preservedReg, fpTypes[index], Y);
  7975. addPop(tempInstructions, preservedReg, fpTypes[index], Y);
  7976. }
  7977. }
  7978. index++;
  7979. }
  7980. index = 0;
  7981. Text prefix = "inlined_";
  7982. prefix.append() << inlineIndex++ << "_";
  7983. block->addJumpLabelPrefix(prefix);
  7984. bool returnFound = false;
  7985. for (const auto& instr : block->instructions)
  7986. {
  7987. if (instr->getOperation() == RET)
  7988. {
  7989. if (index != block->instructions.getEntryCount() - 1)
  7990. {
  7991. returnFound = true;
  7992. instructions.add(new Instruction(
  7993. JMP, {new JumpTargetArgument(Text("after_") + prefix)}));
  7994. }
  7995. }
  7996. else
  7997. {
  7998. instructions.add(dynamic_cast<Instruction*>(instr->getThis()));
  7999. }
  8000. index++;
  8001. }
  8002. if (returnFound)
  8003. {
  8004. defineJumpTarget(Text("after_") + prefix);
  8005. }
  8006. for (const auto& instr : tempInstructions)
  8007. {
  8008. instructions.add(dynamic_cast<Instruction*>(instr->getThis()));
  8009. }
  8010. }
  8011. bool Framework::Assembly::AssemblyBlock::writesToRegister(GPRegister reg) const
  8012. {
  8013. for (const auto& instr : instructions)
  8014. {
  8015. if (instr->writesToRegister(reg, this))
  8016. {
  8017. return true;
  8018. }
  8019. }
  8020. return false;
  8021. }
  8022. bool Framework::Assembly::AssemblyBlock::writesToRegister(FPRegister reg) const
  8023. {
  8024. for (const auto& instr : instructions)
  8025. {
  8026. if (instr->writesToRegister(reg, this))
  8027. {
  8028. return true;
  8029. }
  8030. }
  8031. return false;
  8032. }
  8033. bool Framework::Assembly::AssemblyBlock::readsFromRegister(GPRegister reg) const
  8034. {
  8035. for (const auto& instr : instructions)
  8036. {
  8037. if (instr->readsFromRegister(reg, this))
  8038. {
  8039. return true;
  8040. }
  8041. }
  8042. return false;
  8043. }
  8044. bool Framework::Assembly::AssemblyBlock::readsFromRegister(FPRegister reg) const
  8045. {
  8046. for (const auto& instr : instructions)
  8047. {
  8048. if (instr->readsFromRegister(reg, this))
  8049. {
  8050. return true;
  8051. }
  8052. }
  8053. return false;
  8054. }
  8055. bool Framework::Assembly::AssemblyBlock::isReplacementPossible(
  8056. GPRegister oldReg, GPRegister newReg) const
  8057. {
  8058. for (const auto& instr : instructions)
  8059. {
  8060. if (!instr->isReplacementPossible(oldReg, newReg, this))
  8061. {
  8062. return false;
  8063. }
  8064. }
  8065. return true;
  8066. }
  8067. bool Framework::Assembly::AssemblyBlock::isReplacementPossible(
  8068. FPRegister oldReg, FPRegister newReg) const
  8069. {
  8070. for (const auto& instr : instructions)
  8071. {
  8072. if (!instr->isReplacementPossible(oldReg, newReg, this))
  8073. {
  8074. return false;
  8075. }
  8076. }
  8077. return true;
  8078. }
  8079. void Framework::Assembly::AssemblyBlock::replaceRegister(
  8080. GPRegister oldReg, GPRegister newReg)
  8081. {
  8082. for (const auto& instr : instructions)
  8083. {
  8084. instr->replaceRegister(oldReg, newReg);
  8085. }
  8086. }
  8087. void Framework::Assembly::AssemblyBlock::replaceRegister(
  8088. FPRegister oldReg, FPRegister newReg)
  8089. {
  8090. for (const auto& instr : instructions)
  8091. {
  8092. instr->replaceRegister(oldReg, newReg);
  8093. }
  8094. }
  8095. void Framework::Assembly::AssemblyBlock::addJumpLabelPrefix(Text labelPrefix)
  8096. {
  8097. for (const auto& instr : instructions)
  8098. {
  8099. instr->addJumpLabelPrefix(labelPrefix);
  8100. }
  8101. }
  8102. const Framework::RCArray<Framework::Assembly::Instruction>&
  8103. Framework::Assembly::AssemblyBlock::getInstructions() const
  8104. {
  8105. return instructions;
  8106. }
  8107. void Framework::Assembly::AssemblyBlock::optimize()
  8108. {
  8109. RCArray<Instruction> optimizedInstructions;
  8110. for (int index = 0; index < instructions.getEntryCount(); index++)
  8111. {
  8112. Instruction* curr = instructions.z(index);
  8113. if (index < instructions.getEntryCount() - 1
  8114. && curr->getOperation() == MOV && curr->getArguments().size() == 2
  8115. && curr->getArguments().at(0)->asGPRegisterArgument()
  8116. && curr->getArguments().at(1)->asMemoryAccessArgument())
  8117. {
  8118. GPRegister target = curr->getArguments()
  8119. .at(0)
  8120. ->asGPRegisterArgument()
  8121. ->getRegister();
  8122. GPRegisterPart part
  8123. = curr->getArguments().at(0)->asGPRegisterArgument()->getPart();
  8124. Instruction* next = instructions.z(index + 1);
  8125. if (!next->writesToRegister(target, this)
  8126. && next->getArguments().size() == 2
  8127. && next->getArguments().at(1)->asGPRegisterArgument()
  8128. && next->getArguments()
  8129. .at(1)
  8130. ->asGPRegisterArgument()
  8131. ->getRegister()
  8132. == target
  8133. && next->getArguments().at(1)->asGPRegisterArgument()->getPart()
  8134. == part)
  8135. {
  8136. Instruction* replacement = new Instruction(next->getOperation(),
  8137. {next->getArguments().at(0), curr->getArguments().at(1)});
  8138. if (replacement->isValid(this))
  8139. {
  8140. optimizedInstructions.add(replacement);
  8141. index++;
  8142. continue;
  8143. }
  8144. replacement->release();
  8145. }
  8146. }
  8147. optimizedInstructions.add(dynamic_cast<Instruction*>(curr->getThis()));
  8148. }
  8149. instructions.clear();
  8150. for (Instruction* instr : optimizedInstructions)
  8151. {
  8152. instructions.add(dynamic_cast<Instruction*>(instr->getThis()));
  8153. }
  8154. }
  8155. void* Framework::Assembly::AssemblyBlock::compile()
  8156. {
  8157. if (compiledCode != 0)
  8158. {
  8159. return compiledCode;
  8160. }
  8161. InMemoryBuffer buffer;
  8162. // check non-volatile registers
  8163. RCArray<Instruction> restoreInstructions;
  8164. for (GPRegister nvReg : {RBX, RBP, RSI, RDI, R12, R13, R14, R15})
  8165. {
  8166. if (writesToRegister(nvReg))
  8167. {
  8168. Instruction pushInstr(
  8169. PUSH, {new GPRegisterArgument(nvReg, FULL64)});
  8170. pushInstr.compile(&buffer, this);
  8171. restoreInstructions.add(
  8172. new Instruction(POP, {new GPRegisterArgument(nvReg, FULL64)}),
  8173. 0);
  8174. }
  8175. }
  8176. for (FPRegister nvReg :
  8177. {MM6, MM7, MM8, MM9, MM10, MM11, MM12, MM13, MM14, MM15})
  8178. {
  8179. if (writesToRegister(nvReg))
  8180. {
  8181. Instruction subInst(
  8182. SUB, {new GPRegisterArgument(RSP), new ConstantArgument(32)});
  8183. subInst.compile(&buffer, this);
  8184. Instruction pushInstr(MOVUPD,
  8185. {new MemoryAccessArgument(MemoryBlockSize::M256, RSP),
  8186. new FPRegisterArgument(nvReg, Y)});
  8187. pushInstr.compile(&buffer, this);
  8188. restoreInstructions.add(new Instruction(MOVUPD,
  8189. {new FPRegisterArgument(nvReg, Y),
  8190. new MemoryAccessArgument(MemoryBlockSize::M256, RSP)}));
  8191. restoreInstructions.add(new Instruction(
  8192. ADD, {new GPRegisterArgument(RSP), new ConstantArgument(32)}));
  8193. }
  8194. }
  8195. // replace return instructions with jumps to the end
  8196. if (restoreInstructions.getEntryCount() > 0)
  8197. {
  8198. bool needed = false;
  8199. for (int index = 0; index < instructions.getEntryCount(); index++)
  8200. {
  8201. if (instructions.z(index)->getOperation() == RET)
  8202. {
  8203. if (index < instructions.getEntryCount() - 1)
  8204. {
  8205. needed = true;
  8206. instructions.set(
  8207. new Instruction(JMP,
  8208. {new JumpTargetArgument(
  8209. Text("_restore_non_volatile_registers"))}),
  8210. index);
  8211. }
  8212. else
  8213. {
  8214. // remove last RET instruction, will be added after non
  8215. // volatile registers were restored from the stack
  8216. instructions.remove(index);
  8217. }
  8218. }
  8219. }
  8220. if (needed)
  8221. {
  8222. defineJumpTarget(Text("_restore_non_volatile_registers"));
  8223. }
  8224. }
  8225. // compile instructions
  8226. for (const auto& instr : instructions)
  8227. {
  8228. instr->compile(&buffer, this);
  8229. }
  8230. // restore non-volatile registers
  8231. for (const auto& instr : restoreInstructions)
  8232. {
  8233. instr->compile(&buffer, this);
  8234. }
  8235. // add final RET instruction
  8236. Instruction retInstr(RET, {});
  8237. retInstr.compile(&buffer, this);
  8238. int totalSize = (int)buffer.getSize();
  8239. // Allocate executable memory
  8240. #ifdef WIN32
  8241. compiledCode = VirtualAlloc(nullptr, totalSize, MEM_COMMIT, PAGE_READWRITE);
  8242. #else
  8243. compiledSize = totalSize;
  8244. compiledCode = mmap(nullptr,
  8245. compiledSize,
  8246. PROT_READ | PROT_WRITE,
  8247. MAP_PRIVATE | MAP_ANONYMOUS,
  8248. -1,
  8249. 0);
  8250. #endif
  8251. if (compiledCode == nullptr)
  8252. {
  8253. throw std::runtime_error("Failed to allocate executable memory.");
  8254. }
  8255. // Write the compiled code into the allocated memory
  8256. buffer.read((char*)compiledCode, totalSize);
  8257. #ifdef WIN32
  8258. unsigned long dummy;
  8259. VirtualProtect(compiledCode, totalSize, PAGE_EXECUTE_READ, &dummy);
  8260. #else
  8261. mprotect(compiledCode, compiledSize, PROT_READ | PROT_EXEC);
  8262. #endif
  8263. return compiledCode;
  8264. }