| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft Corporation and contributors. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "Backend.h"
- #ifdef ASMJS_PLAT
- #include "ByteCode/OpCodeUtilAsmJs.h"
- void
- IRBuilderAsmJs::Build()
- {
- m_funcAlloc = m_func->m_alloc;
- NoRecoverMemoryJitArenaAllocator localAlloc(_u("BE-IRBuilder"), m_funcAlloc->GetPageAllocator(), Js::Throw::OutOfMemory);
- m_tempAlloc = &localAlloc;
- uint32 offset;
- uint32 statementIndex = m_statementReader.GetStatementIndex();
- m_argStack = JitAnew(m_tempAlloc, SList<IR::Instr *>, m_tempAlloc);
- m_tempList = JitAnew(m_tempAlloc, SList<IR::Instr *>, m_tempAlloc);
- m_argOffsetStack = JitAnew(m_tempAlloc, SList<int32>, m_tempAlloc);
- m_branchRelocList = JitAnew(m_tempAlloc, SList<BranchReloc *>, m_tempAlloc);
- m_switchBuilder.Init(m_func, m_tempAlloc, true);
- m_firstVarConst = 0;
- m_tempCount = 0;
- m_firstsType[0] = m_firstVarConst + AsmJsRegSlots::RegCount;
- for (int i = 0, j = 1; i < WAsmJs::LIMIT; ++i, ++j)
- {
- WAsmJs::Types type = (WAsmJs::Types)i;
- const auto typedInfo = m_asmFuncInfo->GetTypedSlotInfo(type);
- m_firstsType[j] = typedInfo.constCount;
- m_firstsType[j + WAsmJs::LIMIT] = typedInfo.varCount;
- m_firstsType[j + 2 * WAsmJs::LIMIT] = typedInfo.tmpCount;
- m_tempCount += typedInfo.tmpCount;
- }
- // Fixup the firsts by looking at the previous value
- for (int i = 1; i < m_firstsTypeCount; ++i)
- {
- m_firstsType[i] += m_firstsType[i - 1];
- }
- m_firstIRTemp = m_firstsType[m_firstsTypeCount - 1];
- m_simdOpcodesMap = JitAnewArrayZ(m_tempAlloc, Js::OpCode, Js::Simd128AsmJsOpcodeCount());
- {
- #define MACRO_SIMD(opcode, asmjsLayout, opCodeAttrAsmJs, OpCodeAttr, ...) m_simdOpcodesMap[(uint32)(Js::OpCodeAsmJs::opcode - Js::OpCodeAsmJs::Simd128_Start)] = Js::OpCode::opcode;
- #define MACRO_SIMD_WMS(opcode, asmjsLayout, opCodeAttrAsmJs, OpCodeAttr, ...) MACRO_SIMD(opcode, asmjsLayout, opCodeAttrAsmJs, OpCodeAttr)
- // append extended opcodes
- #define MACRO_SIMD_EXTEND(opcode, asmjsLayout, opCodeAttrAsmJs, OpCodeAttr, ...) \
- m_simdOpcodesMap[(uint32)(Js::OpCodeAsmJs::opcode - Js::OpCodeAsmJs::Simd128_Start_Extend) + (Js::OpCodeAsmJs::Simd128_End - Js::OpCodeAsmJs::Simd128_Start + 1)] = Js::OpCode::opcode;
- #define MACRO_SIMD_EXTEND_WMS(opcode, asmjsLayout, opCodeAttrAsmJs, OpCodeAttr, ...) MACRO_SIMD_EXTEND(opcode, asmjsLayout, opCodeAttrAsmJs, OpCodeAttr)
- #include "ByteCode/OpCodesSimd.h"
- }
- // we will be using lower space for type specialized syms, so bump up where new temp syms can be created
- m_func->m_symTable->IncreaseStartingID(m_firstIRTemp - m_func->m_symTable->GetMaxSymID());
- if (m_tempCount > 0)
- {
- m_tempMap = AnewArrayZ(m_tempAlloc, SymID, m_tempCount);
- m_fbvTempUsed = BVFixed::New<JitArenaAllocator>(m_tempCount, m_tempAlloc);
- }
- else
- {
- m_tempMap = nullptr;
- m_fbvTempUsed = nullptr;
- }
- m_func->m_headInstr = IR::EntryInstr::New(Js::OpCode::FunctionEntry, m_func);
- m_func->m_exitInstr = IR::ExitInstr::New(Js::OpCode::FunctionExit, m_func);
- m_func->m_tailInstr = m_func->m_exitInstr;
- m_func->m_headInstr->InsertAfter(m_func->m_tailInstr);
- m_func->m_isLeaf = true; // until proven otherwise
- m_functionStartOffset = m_jnReader.GetCurrentOffset();
- m_lastInstr = m_func->m_headInstr;
- AssertMsg(sizeof(SymID) >= sizeof(Js::RegSlot), "sizeof(SymID) != sizeof(Js::RegSlot)!!");
- offset = m_functionStartOffset;
- // Skip the last EndOfBlock opcode
- // EndOfBlock opcode has same value in Asm
- Assert(!OpCodeAttr::HasMultiSizeLayout(Js::OpCode::EndOfBlock));
- uint32 lastOffset = m_func->GetJITFunctionBody()->GetByteCodeLength() - Js::OpCodeUtil::EncodedSize(Js::OpCode::EndOfBlock, Js::SmallLayout);
- uint32 offsetToInstructionCount = lastOffset;
- if (this->IsLoopBody())
- {
- // LdSlot needs to cover all the register, including the temps, because we might treat
- // those as if they are local for the value of the with statement
- this->m_ldSlots = BVFixed::New<JitArenaAllocator>(GetLastTmp(WAsmJs::LastType), m_tempAlloc);
- this->m_stSlots = BVFixed::New<JitArenaAllocator>(GetFirstTmp(WAsmJs::FirstType), m_tempAlloc);
- this->m_loopBodyRetIPSym = StackSym::New(TyInt32, this->m_func);
- #if DBG
- uint32 tmpCount = GetLastTmp(WAsmJs::LastType) - GetFirstTmp(WAsmJs::FirstType);
- if (tmpCount != 0)
- {
- this->m_usedAsTemp = BVFixed::New<JitArenaAllocator>(tmpCount, m_tempAlloc);
- }
- #endif
- lastOffset = m_func->GetWorkItem()->GetLoopHeader()->endOffset;
- // Ret is created at lastOffset + 1, so we need lastOffset + 2 entries
- offsetToInstructionCount = lastOffset + 2;
- }
- #if DBG
- m_offsetToInstructionCount = offsetToInstructionCount;
- #endif
- m_offsetToInstruction = JitAnewArrayZ(m_tempAlloc, IR::Instr *, offsetToInstructionCount);
- LoadNativeCodeData();
- BuildConstantLoads();
- if (!this->IsLoopBody() && m_func->GetJITFunctionBody()->HasImplicitArgIns())
- {
- BuildImplicitArgIns();
- }
- if (m_statementReader.AtStatementBoundary(&m_jnReader))
- {
- statementIndex = AddStatementBoundary(statementIndex, offset);
- }
- Js::LayoutSize layoutSize;
- for (Js::OpCodeAsmJs newOpcode = m_jnReader.ReadAsmJsOp(layoutSize); (uint)m_jnReader.GetCurrentOffset() <= lastOffset; newOpcode = m_jnReader.ReadAsmJsOp(layoutSize))
- {
- Assert(newOpcode != Js::OpCodeAsmJs::EndOfBlock);
- AssertOrFailFastMsg(Js::OpCodeUtilAsmJs::IsValidByteCodeOpcode(newOpcode), "Error getting opcode from m_jnReader.Op()");
- uint layoutAndSize = layoutSize * Js::OpLayoutTypeAsmJs::Count + Js::OpCodeUtilAsmJs::GetOpCodeLayout(newOpcode);
- switch (layoutAndSize)
- {
- #define LAYOUT_TYPE(layout) \
- case Js::OpLayoutTypeAsmJs::layout: \
- Assert(layoutSize == Js::SmallLayout); \
- Build##layout(newOpcode, offset); \
- break;
- #define LAYOUT_TYPE_WMS(layout) \
- case Js::SmallLayout * Js::OpLayoutTypeAsmJs::Count + Js::OpLayoutTypeAsmJs::layout: \
- Build##layout<Js::SmallLayoutSizePolicy>(newOpcode, offset); \
- break; \
- case Js::MediumLayout * Js::OpLayoutTypeAsmJs::Count + Js::OpLayoutTypeAsmJs::layout: \
- Build##layout<Js::MediumLayoutSizePolicy>(newOpcode, offset); \
- break; \
- case Js::LargeLayout * Js::OpLayoutTypeAsmJs::Count + Js::OpLayoutTypeAsmJs::layout: \
- Build##layout<Js::LargeLayoutSizePolicy>(newOpcode, offset); \
- break;
- #define EXCLUDE_FRONTEND_LAYOUT
- #include "ByteCode/LayoutTypesAsmJs.h"
- default:
- AssertMsg(UNREACHED, "Unimplemented layout");
- Js::Throw::InternalError();
- break;
- }
- offset = m_jnReader.GetCurrentOffset();
- if (m_statementReader.AtStatementBoundary(&m_jnReader))
- {
- statementIndex = AddStatementBoundary(statementIndex, offset);
- }
- }
- if (Js::Constants::NoStatementIndex != statementIndex)
- {
- statementIndex = AddStatementBoundary(statementIndex, Js::Constants::NoByteCodeOffset);
- }
- if (IsLoopBody())
- {
- // Insert the LdSlot/StSlot and Ret
- IR::Opnd * retOpnd = this->InsertLoopBodyReturnIPInstr(offset, offset);
- // Restore and Ret are at the last offset + 1
- GenerateLoopBodySlotAccesses(lastOffset + 1);
- IR::Instr * retInstr = IR::Instr::New(Js::OpCode::Ret, m_func);
- retInstr->SetSrc1(retOpnd);
- this->AddInstr(retInstr, lastOffset + 1);
- }
- // Now fix up the targets for all the branches we've introduced.
- InsertLabels();
- // Now that we know whether the func is a leaf or not, decide whether we'll emit fast paths.
- // Do this once and for all, per-func, since the source size on the ThreadContext will be
- // changing while we JIT.
- if (m_func->IsTopFunc())
- {
- m_func->SetDoFastPaths();
- }
- }
- void
- IRBuilderAsmJs::LoadNativeCodeData()
- {
- Assert(m_func->IsTopFunc());
- if (m_func->IsOOPJIT())
- {
- IR::RegOpnd * nativeDataOpnd = IR::RegOpnd::New(TyVar, m_func);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::LdNativeCodeData, nativeDataOpnd, m_func);
- this->AddInstr(instr, Js::Constants::NoByteCodeOffset);
- m_func->SetNativeCodeDataSym(nativeDataOpnd->GetStackSym());
- }
- }
- void
- IRBuilderAsmJs::AddInstr(IR::Instr * instr, uint32 offset)
- {
- m_lastInstr->InsertAfter(instr);
- if (offset != Js::Constants::NoByteCodeOffset)
- {
- Assert(offset < m_offsetToInstructionCount);
- if (m_offsetToInstruction[offset] == nullptr)
- {
- m_offsetToInstruction[offset] = instr;
- }
- else
- {
- Assert(m_lastInstr->GetByteCodeOffset() == offset);
- }
- instr->SetByteCodeOffset(offset);
- }
- else
- {
- instr->SetByteCodeOffset(m_lastInstr->GetByteCodeOffset());
- }
- m_lastInstr = instr;
- Func *topFunc = m_func->GetTopFunc();
- if (!topFunc->GetHasTempObjectProducingInstr())
- {
- if (OpCodeAttr::TempObjectProducing(instr->m_opcode))
- {
- topFunc->SetHasTempObjectProducingInstr(true);
- }
- }
- #if DBG_DUMP
- if (Js::Configuration::Global.flags.Trace.IsEnabled(Js::IRBuilderPhase, m_func->GetTopFunc()->GetSourceContextId(), m_func->GetTopFunc()->GetLocalFunctionId()))
- {
- instr->Dump();
- }
- #endif
- }
- IR::RegOpnd *
- IRBuilderAsmJs::BuildDstOpnd(Js::RegSlot dstRegSlot, IRType type)
- {
- SymID symID;
- if (RegIsTemp(dstRegSlot))
- {
- #if DBG
- if (this->IsLoopBody())
- {
- // If we are doing loop body, and a temp reg slot is loaded via LdSlot
- // That means that we have detected that the slot is live coming in to the loop.
- // This would only happen for the value of a "with" statement, so there shouldn't
- // be any def for those
- Assert(!this->m_ldSlots->Test(dstRegSlot));
- this->m_usedAsTemp->Set(dstRegSlot - GetFirstTmp(WAsmJs::FirstType));
- }
- #endif
- // This is a def of a temp. Create a new sym ID for it if it's been used since its last def.
- // !!!NOTE: always process an instruction's temp uses before its temp defs!!!
- if (GetTempUsed(dstRegSlot))
- {
- symID = m_func->m_symTable->NewID();
- SetTempUsed(dstRegSlot, FALSE);
- SetMappedTemp(dstRegSlot, symID);
- }
- else
- {
- symID = GetMappedTemp(dstRegSlot);
- // The temp hasn't been used since its last def. There are 2 possibilities:
- if (symID == 0)
- {
- // First time we've seen the temp. Just use the number that the front end gave it.
- symID = static_cast<SymID>(dstRegSlot);
- SetMappedTemp(dstRegSlot, symID);
- }
- else if (IRType_IsSimd128(type))
- {
- //In Asm.js, SIMD register space is untyped, so we could have SIMD temp registers.
- //Make sure that the StackSym types matches before reusing simd temps.
- StackSym * stackSym = m_func->m_symTable->FindStackSym(symID);
- if (!stackSym || stackSym->GetType() != type)
- {
- symID = m_func->m_symTable->NewID();
- SetMappedTemp(dstRegSlot, symID);
- }
- }
- }
- }
- else
- {
- symID = static_cast<SymID>(dstRegSlot);
- if (RegIsConstant(dstRegSlot))
- {
- // Don't need to track constant registers for bailout. Don't set the byte code register for constant.
- dstRegSlot = Js::Constants::NoRegister;
- }
- else if (IsLoopBody() && RegIsVar(dstRegSlot))
- {
- // Loop body and not constants
- this->m_stSlots->Set(symID);
- // We need to make sure that the symbols is loaded as well
- // so that the sym will be defined on all path.
- this->EnsureLoopBodyAsmJsLoadSlot(symID, type);
- }
- else
- {
- Assert(!IsLoopBody() || dstRegSlot == 0); // if loop body then one of the above two conditions should hold true
- }
- }
- //Simd return values of different IR types share the same reg slot.
- //To avoid symbol type mismatch, use the stack symbol with a dummy simd type.
- if (RegIsSimd128ReturnVar(symID))
- {
- type = TySimd128F4;
- }
- StackSym * symDst = StackSym::FindOrCreate(symID, dstRegSlot, m_func, type);
- // Always reset isSafeThis to false. We'll set it to true for singleDef cases,
- // but want to reset it to false if it is multi-def.
- // NOTE: We could handle the multiDef if they are all safe, but it probably isn't very common.
- symDst->m_isSafeThis = false;
- IR::RegOpnd *regOpnd = IR::RegOpnd::New(symDst, type, m_func);
- return regOpnd;
- }
- IR::RegOpnd *
- IRBuilderAsmJs::BuildSrcOpnd(Js::RegSlot srcRegSlot, IRType type)
- {
- StackSym * symSrc = m_func->m_symTable->FindStackSym(BuildSrcStackSymID(srcRegSlot, type));
- AssertMsg(symSrc, "Tried to use an undefined stack slot?");
- IR::RegOpnd * regOpnd = IR::RegOpnd::New(symSrc, type, m_func);
- return regOpnd;
- }
- IR::RegOpnd *
- IRBuilderAsmJs::BuildIntConstOpnd(Js::RegSlot regSlot)
- {
- Js::Var * constTable = (Js::Var*)m_func->GetJITFunctionBody()->GetConstTable();
- const WAsmJs::TypedSlotInfo& info = m_func->GetJITFunctionBody()->GetAsmJsInfo()->GetTypedSlotInfo(WAsmJs::INT32);
- Assert(info.constSrcByteOffset != Js::Constants::InvalidOffset);
- AssertOrFailFast(info.constSrcByteOffset < UInt32Math::Mul<sizeof(Js::Var)>(m_func->GetJITFunctionBody()->GetConstCount()));
- int* intConstTable = reinterpret_cast<int*>(((byte*)constTable) + info.constSrcByteOffset);
- Js::RegSlot srcReg = GetTypedRegFromRegSlot(regSlot, WAsmJs::INT32);
- AssertOrFailFast(srcReg >= Js::FunctionBody::FirstRegSlot && srcReg < info.constCount);
- const int32 value = intConstTable[srcReg];
- IR::IntConstOpnd *opnd = IR::IntConstOpnd::New(value, TyInt32, m_func);
- return (IR::RegOpnd*)opnd;
- }
- SymID
- IRBuilderAsmJs::BuildSrcStackSymID(Js::RegSlot regSlot, IRType type /*= IRType::TyVar*/)
- {
- SymID symID;
- if (this->RegIsTemp(regSlot))
- {
- // This is a use of a temp. Map the reg slot to its sym ID.
- // !!!NOTE: always process an instruction's temp uses before its temp defs!!!
- symID = this->GetMappedTemp(regSlot);
- if (symID == 0)
- {
- // We might have temps that are live through the loop body via "with" statement
- // We need to treat those as if they are locals and don't remap them
- Assert(this->IsLoopBody());
- Assert(!this->m_usedAsTemp->Test(regSlot - GetFirstTmp(WAsmJs::FirstType)));
- symID = static_cast<SymID>(regSlot);
- this->SetMappedTemp(regSlot, symID);
- this->EnsureLoopBodyAsmJsLoadSlot(symID, type);
- }
- this->SetTempUsed(regSlot, TRUE);
- }
- else
- {
- symID = static_cast<SymID>(regSlot);
- if (IsLoopBody() && RegIsVar(regSlot))
- {
- this->EnsureLoopBodyAsmJsLoadSlot(symID, type);
- }
- else
- {
- Assert(!IsLoopBody() || this->RegIsConstant(regSlot) || regSlot == 0);
- }
- }
- return symID;
- }
- IR::SymOpnd *
- IRBuilderAsmJs::BuildFieldOpnd(Js::RegSlot reg, Js::PropertyId propertyId, PropertyKind propertyKind, IRType type, bool scale)
- {
- Js::PropertyId scaledPropertyId = propertyId;
- if (scale)
- {
- scaledPropertyId *= TySize[type];
- }
- PropertySym * propertySym = BuildFieldSym(reg, scaledPropertyId, propertyKind);
- IR::SymOpnd * symOpnd = IR::SymOpnd::New(propertySym, type, m_func);
- return symOpnd;
- }
- PropertySym *
- IRBuilderAsmJs::BuildFieldSym(Js::RegSlot reg, Js::PropertyId propertyId, PropertyKind propertyKind)
- {
- SymID symId = BuildSrcStackSymID(reg);
- AssertMsg(m_func->m_symTable->FindStackSym(symId), "Tried to use an undefined stacksym?");
- PropertySym * propertySym = PropertySym::FindOrCreate(symId, propertyId, (Js::PropertyIdIndexType)-1, (uint)-1, propertyKind, m_func);
- return propertySym;
- }
- uint
- IRBuilderAsmJs::AddStatementBoundary(uint statementIndex, uint offset)
- {
- if (m_func->GetJITFunctionBody()->IsWasmFunction())
- {
- return 0;
- }
- IR::PragmaInstr* pragmaInstr = IR::PragmaInstr::New(Js::OpCode::StatementBoundary, statementIndex, m_func);
- this->AddInstr(pragmaInstr, offset);
- return m_statementReader.MoveNextStatementBoundary();
- }
- Js::RegSlot IRBuilderAsmJs::GetTypedRegFromRegSlot(Js::RegSlot reg, WAsmJs::Types type)
- {
- const auto typedInfo = m_asmFuncInfo->GetTypedSlotInfo(type);
- Js::RegSlot srcReg = reg;
- if (RegIsTypedVar(reg, type))
- {
- srcReg = reg - GetFirstVar(type);
- Assert(srcReg < typedInfo.varCount);
- srcReg += typedInfo.constCount;
- }
- else if (RegIsTemp(reg))
- {
- srcReg = reg - GetFirstTmp(type);
- Assert(srcReg < typedInfo.tmpCount);
- srcReg += typedInfo.varCount + typedInfo.constCount;
- }
- else if (RegIsConstant(reg))
- {
- srcReg = reg - GetFirstConst(type);
- Assert(srcReg < typedInfo.constCount);
- }
- return srcReg;
- }
- Js::RegSlot
- IRBuilderAsmJs::GetRegSlotFromTypedReg(Js::RegSlot srcReg, WAsmJs::Types type)
- {
- const auto typedInfo = m_asmFuncInfo->GetTypedSlotInfo(type);
- Js::RegSlot reg;
- if (srcReg < typedInfo.constCount)
- {
- reg = srcReg + GetFirstConst(type);
- Assert(reg >= GetFirstConst(type) && reg < GetLastConst(type));
- return reg;
- }
- srcReg -= typedInfo.constCount;
- if (srcReg < typedInfo.varCount)
- {
- reg = srcReg + GetFirstVar(type);
- Assert(reg >= GetFirstVar(type) && reg < GetLastVar(type));
- return reg;
- }
- srcReg -= typedInfo.varCount;
- Assert(srcReg < typedInfo.tmpCount);
- reg = srcReg + GetFirstTmp(type);
- Assert(reg >= GetFirstTmp(type) && reg < GetLastTmp(type));
- return reg;
- }
- IR::Instr *
- IRBuilderAsmJs::AddExtendedArg(IR::RegOpnd *src1, IR::RegOpnd *src2, uint32 offset)
- {
- Assert(src1);
- IR::RegOpnd * dst = IR::RegOpnd::New(src1->GetType(), m_func);
- dst->SetValueType(src1->GetValueType());
- IR::Instr * instr = IR::Instr::New(Js::OpCode::ExtendArg_A, dst, src1, m_func);
- if (src2)
- {
- instr->SetSrc2(src2);
- }
- AddInstr(instr, offset);
- return instr;
- }
- Js::RegSlot
- IRBuilderAsmJs::GetRegSlotFromVarReg(Js::RegSlot srcVarReg)
- {
- Js::RegSlot reg;
- if (srcVarReg < (Js::RegSlot)(AsmJsRegSlots::RegCount - 1))
- {
- reg = srcVarReg + m_firstVarConst;
- Assert(reg >= m_firstVarConst && reg < GetFirstConst(WAsmJs::FirstType));
- }
- else
- {
- reg = srcVarReg - AsmJsRegSlots::RegCount + GetFirstTmp(WAsmJs::FirstType) - 1;
- }
- return reg;
- }
- SymID
- IRBuilderAsmJs::GetMappedTemp(Js::RegSlot reg)
- {
- AssertMsg(RegIsTemp(reg), "Processing non-temp reg as a temp?");
- AssertMsg(m_tempMap, "Processing non-temp reg without a temp map?");
- Js::RegSlot tempIndex = reg - GetFirstTmp(WAsmJs::FirstType);
- AssertOrFailFast(tempIndex < m_tempCount);
- return m_tempMap[tempIndex];
- }
- void
- IRBuilderAsmJs::SetMappedTemp(Js::RegSlot reg, SymID tempId)
- {
- AssertMsg(RegIsTemp(reg), "Processing non-temp reg as a temp?");
- AssertMsg(m_tempMap, "Processing non-temp reg without a temp map?");
- Js::RegSlot tempIndex = reg - GetFirstTmp(WAsmJs::FirstType);
- AssertOrFailFast(tempIndex < m_tempCount);
- m_tempMap[tempIndex] = tempId;
- }
- BOOL
- IRBuilderAsmJs::GetTempUsed(Js::RegSlot reg)
- {
- AssertMsg(RegIsTemp(reg), "Processing non-temp reg as a temp?");
- AssertMsg(m_fbvTempUsed, "Processing non-temp reg without a used BV?");
- Js::RegSlot tempIndex = reg - GetFirstTmp(WAsmJs::FirstType);
- AssertOrFailFast(tempIndex < m_tempCount);
- return m_fbvTempUsed->Test(tempIndex);
- }
- void
- IRBuilderAsmJs::SetTempUsed(Js::RegSlot reg, BOOL used)
- {
- AssertMsg(RegIsTemp(reg), "Processing non-temp reg as a temp?");
- AssertMsg(m_fbvTempUsed, "Processing non-temp reg without a used BV?");
- Js::RegSlot tempIndex = reg - GetFirstTmp(WAsmJs::FirstType);
- AssertOrFailFast(tempIndex < m_tempCount);
- if (used)
- {
- m_fbvTempUsed->Set(tempIndex);
- }
- else
- {
- m_fbvTempUsed->Clear(tempIndex);
- }
- }
- BOOL
- IRBuilderAsmJs::RegIsTemp(Js::RegSlot reg)
- {
- return reg >= GetFirstTmp(WAsmJs::FirstType);
- }
- BOOL
- IRBuilderAsmJs::RegIsVar(Js::RegSlot reg)
- {
- for (int i = 0; i < WAsmJs::LIMIT; ++i)
- {
- if (RegIsTypedVar(reg, (WAsmJs::Types)i))
- {
- return true;
- }
- }
- return false;
- }
- BOOL
- IRBuilderAsmJs::RegIsTypedVar(Js::RegSlot reg, WAsmJs::Types type)
- {
- return reg >= GetFirstVar(type) && reg < GetLastVar(type);
- }
- bool
- IRBuilderAsmJs::RegIsSimd128ReturnVar(Js::RegSlot reg)
- {
- return (reg == GetFirstConst(WAsmJs::SIMD) &&
- Js::AsmJsRetType(m_asmFuncInfo->GetRetType()).toVarType().isSIMD());
- }
- BOOL
- IRBuilderAsmJs::RegIsConstant(Js::RegSlot reg)
- {
- return (reg > 0 && reg < GetLastConst(WAsmJs::LastType));
- }
- BranchReloc *
- IRBuilderAsmJs::AddBranchInstr(IR::BranchInstr * branchInstr, uint32 offset, uint32 targetOffset)
- {
- //
- // Loop jitting would be done only till the LoopEnd
- // Any branches beyond that offset are for the return statement
- //
- if (IsLoopBodyOuterOffset(targetOffset))
- {
- // if we have loaded the loop IP sym from the ProfiledLoopEnd then don't add it here
- if (!IsLoopBodyReturnIPInstr(m_lastInstr))
- {
- this->InsertLoopBodyReturnIPInstr(targetOffset, offset);
- }
- // Jump the restore StSlot and Ret instruction
- targetOffset = GetLoopBodyExitInstrOffset();
- }
- BranchReloc * reloc = nullptr;
- reloc = CreateRelocRecord(branchInstr, offset, targetOffset);
- AddInstr(branchInstr, offset);
- return reloc;
- }
- BranchReloc *
- IRBuilderAsmJs::CreateRelocRecord(IR::BranchInstr * branchInstr, uint32 offset, uint32 targetOffset)
- {
- BranchReloc * reloc = JitAnew(m_tempAlloc, BranchReloc, branchInstr, offset, targetOffset);
- m_branchRelocList->Prepend(reloc);
- return reloc;
- }
- void
- IRBuilderAsmJs::BuildHeapBufferReload(uint32 offset)
- {
- #ifdef ENABLE_WASM
- if(m_func->GetJITFunctionBody()->IsWasmFunction())
- {
- // WebAssembly.Memory
- IR::RegOpnd * dstOpnd = BuildDstOpnd(AsmJsRegSlots::WasmMemoryReg, TyVar);
- IR::Opnd * srcOpnd = IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::ModuleMemReg, TyVar), (int32)Js::WebAssemblyModule::GetMemoryOffset(), TyVar, m_func);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- // ArrayBuffer
- dstOpnd = BuildDstOpnd(AsmJsRegSlots::ArrayReg, TyVar);
- srcOpnd = IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::WasmMemoryReg, TyVar), Js::WebAssemblyMemory::GetOffsetOfArrayBuffer(), TyVar, m_func);
- instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- else
- #endif
- {
- // ArrayBuffer
- IR::RegOpnd * dstOpnd = BuildDstOpnd(AsmJsRegSlots::ArrayReg, TyVar);
- IR::Opnd * srcOpnd = IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::ModuleMemReg, TyVar), (int32)Js::AsmJsModuleMemory::MemoryTableBeginOffset, TyVar, m_func);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- // ArrayBuffer buffer
- IR::RegOpnd * dstOpnd = BuildDstOpnd(AsmJsRegSlots::BufferReg, TyVar);
- IR::Opnd * srcOpnd = IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::ArrayReg, TyVar), Js::ArrayBuffer::GetBufferOffset(), TyVar, m_func);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- // ArrayBuffer length
- dstOpnd = BuildDstOpnd(AsmJsRegSlots::LengthReg, TyUint32);
- srcOpnd = IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::ArrayReg, TyVar), Js::ArrayBuffer::GetByteLengthOffset(), TyUint32, m_func);
- instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- template<typename T, typename ConstOpnd, typename F>
- void IRBuilderAsmJs::CreateLoadConstInstrForType(
- byte* table,
- Js::RegSlot& regAllocated,
- uint32 constCount,
- uint32 byteOffset,
- IRType irType,
- ValueType valueType,
- Js::OpCode opcode,
- F extraProcess
- )
- {
- T* typedTable = (T*)(table + byteOffset);
- AssertOrFailFast(byteOffset < UInt32Math::Mul<sizeof(Js::Var)>(m_func->GetJITFunctionBody()->GetConstCount()));
- AssertOrFailFast(AllocSizeMath::Add((size_t)typedTable, UInt32Math::Mul<sizeof(T)>(constCount)) <= (size_t)((Js::Var*)m_func->GetJITFunctionBody()->GetConstTable() + m_func->GetJITFunctionBody()->GetConstCount()));
- // 1 for return register
- ++regAllocated;
- ++typedTable;
- for (uint32 i = 1; i < constCount; ++i)
- {
- uint32 reg = regAllocated++;
- T constVal = *typedTable++;
- IR::RegOpnd * dstOpnd = BuildDstOpnd(reg, irType);
- Assert(RegIsConstant(reg));
- dstOpnd->m_sym->SetIsFromByteCodeConstantTable();
- dstOpnd->SetValueType(valueType);
- IR::Instr *instr = IR::Instr::New(opcode, dstOpnd, ConstOpnd::New(constVal, irType, m_func), m_func);
- extraProcess(instr, constVal);
- AddInstr(instr, Js::Constants::NoByteCodeOffset);
- }
- }
- void
- IRBuilderAsmJs::BuildConstantLoads()
- {
- Js::Var * constTable = (Js::Var *)m_func->GetJITFunctionBody()->GetConstTable();
- // Load FrameDisplay
- IR::RegOpnd * asmJsEnvDstOpnd = BuildDstOpnd(AsmJsRegSlots::ModuleMemReg, TyVar);
- IR::Instr * ldAsmJsEnvInstr = IR::Instr::New(Js::OpCode::LdAsmJsEnv, asmJsEnvDstOpnd, m_func);
- AddInstr(ldAsmJsEnvInstr, Js::Constants::NoByteCodeOffset);
- // Load heap buffer
- if (m_asmFuncInfo->UsesHeapBuffer())
- {
- BuildHeapBufferReload(Js::Constants::NoByteCodeOffset);
- }
- if (!constTable)
- {
- return;
- }
- uint32 regAllocated = AsmJsRegSlots::RegCount;
- byte* table = (byte*)constTable;
- const bool isOOPJIT = m_func->IsOOPJIT();
- for (int i = 0; i < WAsmJs::LIMIT; ++i)
- {
- WAsmJs::Types type = (WAsmJs::Types)i;
- WAsmJs::TypedSlotInfo info = m_asmFuncInfo->GetTypedSlotInfo(type);
- if (info.constCount == 0)
- {
- continue;
- }
- switch(type)
- {
- case WAsmJs::INT32:
- CreateLoadConstInstrForType<int32, IR::IntConstOpnd>(
- table,
- regAllocated,
- info.constCount,
- info.constSrcByteOffset,
- TyInt32,
- ValueType::GetInt(false),
- Js::OpCode::Ld_I4,
- [isOOPJIT](IR::Instr* instr, int32 val)
- {
- IR::RegOpnd* dstOpnd = instr->GetDst()->AsRegOpnd();
- if (!isOOPJIT && dstOpnd->m_sym->IsSingleDef())
- {
- dstOpnd->m_sym->SetIsIntConst(val);
- }
- }
- );
- break;
- case WAsmJs::FLOAT32:
- CreateLoadConstInstrForType<float, IR::FloatConstOpnd>(
- table,
- regAllocated,
- info.constCount,
- info.constSrcByteOffset,
- TyFloat32,
- ValueType::Float,
- Js::OpCode::LdC_F8_R8,
- [isOOPJIT](IR::Instr* instr, float val)
- {
- #if _M_IX86
- IR::RegOpnd* dstOpnd = instr->GetDst()->AsRegOpnd();
- if (!isOOPJIT && dstOpnd->m_sym->IsSingleDef())
- {
- dstOpnd->m_sym->SetIsFloatConst();
- }
- #endif
- }
- );
- break;
- case WAsmJs::FLOAT64:
- CreateLoadConstInstrForType<double, IR::FloatConstOpnd>(
- table,
- regAllocated,
- info.constCount,
- info.constSrcByteOffset,
- TyFloat64,
- ValueType::Float,
- Js::OpCode::LdC_F8_R8,
- [isOOPJIT](IR::Instr* instr, double val)
- {
- #if _M_IX86
- IR::RegOpnd* dstOpnd = instr->GetDst()->AsRegOpnd();
- if (!isOOPJIT && dstOpnd->m_sym->IsSingleDef())
- {
- dstOpnd->m_sym->SetIsFloatConst();
- }
- #endif
- }
- );
- break;
- case WAsmJs::SIMD:
- CreateLoadConstInstrForType<AsmJsSIMDValue, IR::Simd128ConstOpnd>(
- table,
- regAllocated,
- info.constCount,
- info.constSrcByteOffset,
- TySimd128F4,
- ValueType::UninitializedObject,
- Js::OpCode::Simd128_LdC,
- [isOOPJIT](IR::Instr* instr, AsmJsSIMDValue val)
- {
- #if _M_IX86
- IR::RegOpnd* dstOpnd = instr->GetDst()->AsRegOpnd();
- if (!isOOPJIT && dstOpnd->m_sym->IsSingleDef())
- {
- dstOpnd->m_sym->SetIsSimd128Const();
- }
- #endif
- }
- );
- break;
- default:
- Assert(false);
- break;
- }
- }
- }
- void
- IRBuilderAsmJs::BuildImplicitArgIns()
- {
- int32 intArgInCount = 0;
- int32 int64ArgInCount = 0;
- int32 floatArgInCount = 0;
- int32 doubleArgInCount = 0;
- int32 simd128ArgInCount = 0;
- // formal params are offset from EBP by the EBP chain, return address, and function object
- int32 offset = 3 * MachPtr;
- for (Js::ArgSlot i = 1; i < m_func->GetJITFunctionBody()->GetInParamsCount(); ++i)
- {
- StackSym * symSrc = nullptr;
- IR::Opnd * srcOpnd = nullptr;
- IR::RegOpnd * dstOpnd = nullptr;
- IR::Instr * instr = nullptr;
- // TODO: double args are not aligned on stack
- Js::AsmJsVarType varType = m_func->GetJITFunctionBody()->GetAsmJsInfo()->GetArgType(i - 1);
- switch (varType.which())
- {
- case Js::AsmJsVarType::Which::Int:
- symSrc = StackSym::NewParamSlotSym(i, m_func, TyInt32);
- m_func->SetArgOffset(symSrc, offset);
- srcOpnd = IR::SymOpnd::New(symSrc, TyInt32, m_func);
- dstOpnd = BuildDstOpnd(GetFirstVar(WAsmJs::INT32) + intArgInCount, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- instr = IR::Instr::New(Js::OpCode::ArgIn_A, dstOpnd, srcOpnd, m_func);
- offset += MachPtr;
- ++intArgInCount;
- break;
- case Js::AsmJsVarType::Which::Float:
- symSrc = StackSym::NewParamSlotSym(i, m_func, TyFloat32);
- m_func->SetArgOffset(symSrc, offset);
- srcOpnd = IR::SymOpnd::New(symSrc, TyFloat32, m_func);
- dstOpnd = BuildDstOpnd(GetFirstVar(WAsmJs::FLOAT32) + floatArgInCount, TyFloat32);
- dstOpnd->SetValueType(ValueType::Float);
- instr = IR::Instr::New(Js::OpCode::ArgIn_A, dstOpnd, srcOpnd, m_func);
- offset += MachPtr;
- ++floatArgInCount;
- break;
- case Js::AsmJsVarType::Which::Double:
- symSrc = StackSym::NewParamSlotSym(i, m_func, TyFloat64);
- m_func->SetArgOffset(symSrc, offset);
- srcOpnd = IR::SymOpnd::New(symSrc, TyFloat64, m_func);
- dstOpnd = BuildDstOpnd(GetFirstVar(WAsmJs::FLOAT64) + doubleArgInCount, TyFloat64);
- dstOpnd->SetValueType(ValueType::Float);
- instr = IR::Instr::New(Js::OpCode::ArgIn_A, dstOpnd, srcOpnd, m_func);
- offset += MachDouble;
- ++doubleArgInCount;
- break;
- case Js::AsmJsVarType::Which::Int64:
- symSrc = StackSym::NewParamSlotSym(i, m_func, TyInt64);
- m_func->SetArgOffset(symSrc, offset);
- srcOpnd = IR::SymOpnd::New(symSrc, TyInt64, m_func);
- dstOpnd = BuildDstOpnd(GetFirstVar(WAsmJs::INT64) + int64ArgInCount, TyInt64);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- instr = IR::Instr::New(Js::OpCode::ArgIn_A, dstOpnd, srcOpnd, m_func);
- offset += 8;
- ++int64ArgInCount;
- break;
- default:
- {
- // SIMD_JS
- IRType argType;
- GetSimdTypesFromAsmType((Js::AsmJsType::Which)varType.which(), &argType);
- symSrc = StackSym::NewParamSlotSym(i, m_func, argType);
- m_func->SetArgOffset(symSrc, offset);
- srcOpnd = IR::SymOpnd::New(symSrc, argType, m_func);
- dstOpnd = BuildDstOpnd(GetFirstVar(WAsmJs::SIMD) + simd128ArgInCount, argType);
- dstOpnd->SetValueType(ValueType::UninitializedObject);
- instr = IR::Instr::New(Js::OpCode::ArgIn_A, dstOpnd, srcOpnd, m_func);
- offset += sizeof(AsmJsSIMDValue);
- ++simd128ArgInCount;
- break;
- }
- }
- AddInstr(instr, Js::Constants::NoByteCodeOffset);
- }
- }
- void
- IRBuilderAsmJs::InsertLabels()
- {
- AssertMsg(m_branchRelocList, "Malformed branch reloc list");
- SList<BranchReloc *>::Iterator iter(m_branchRelocList);
- while (iter.Next())
- {
- IR::LabelInstr * labelInstr = nullptr;
- BranchReloc * reloc = iter.Data();
- IR::BranchInstr * branchInstr = reloc->GetBranchInstr();
- uint offset = reloc->GetOffset();
- uint const branchOffset = reloc->GetBranchOffset();
- Assert(!IsLoopBody() || offset <= GetLoopBodyExitInstrOffset());
- if (branchInstr->m_opcode == Js::OpCode::MultiBr)
- {
- IR::MultiBranchInstr * multiBranchInstr = branchInstr->AsBranchInstr()->AsMultiBrInstr();
- multiBranchInstr->UpdateMultiBrTargetOffsets([&](uint32 offset) -> IR::LabelInstr *
- {
- labelInstr = this->CreateLabel(branchInstr, offset);
- multiBranchInstr->ChangeLabelRef(nullptr, labelInstr);
- return labelInstr;
- });
- }
- else
- {
- labelInstr = CreateLabel(branchInstr, offset);
- branchInstr->SetTarget(labelInstr);
- }
- if (!reloc->IsNotBackEdge() && branchOffset >= offset)
- {
- labelInstr->m_isLoopTop = true;
- }
- }
- }
- IR::LabelInstr *
- IRBuilderAsmJs::CreateLabel(IR::BranchInstr * branchInstr, uint & offset)
- {
- IR::Instr * targetInstr = nullptr;
- while (targetInstr == nullptr)
- {
- targetInstr = m_offsetToInstruction[offset];
- Assert(offset < m_offsetToInstructionCount);
- ++offset;
- }
- IR::Instr *instrPrev = targetInstr->m_prev;
- if (instrPrev)
- {
- instrPrev = targetInstr->GetPrevRealInstrOrLabel();
- }
- IR::LabelInstr * labelInstr;
- if (instrPrev && instrPrev->IsLabelInstr())
- {
- // Found an existing label at the right offset. Just reuse it.
- labelInstr = instrPrev->AsLabelInstr();
- }
- else
- {
- // No label at the desired offset. Create one.
- labelInstr = IR::LabelInstr::New(Js::OpCode::Label, m_func);
- labelInstr->SetByteCodeOffset(offset);
- if (instrPrev)
- {
- instrPrev->InsertAfter(labelInstr);
- }
- else
- {
- targetInstr->InsertBefore(labelInstr);
- }
- }
- return labelInstr;
- }
- void
- IRBuilderAsmJs::BuildEmpty(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- m_jnReader.Empty();
- IR::Instr * instr = nullptr;
- IR::RegOpnd * regOpnd = nullptr;
- Js::RegSlot retSlot;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::CheckHeap:
- instr = IR::Instr::New(Js::OpCode::ArrayDetachedCheck, m_func);
- instr->SetSrc1(IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::ArrayReg, TyVar), Js::ArrayBuffer::GetIsDetachedOffset(), TyInt8, m_func));
- AddInstr(instr, offset);
- break;
- case Js::OpCodeAsmJs::Unreachable_Void:
- instr = IR::Instr::New(Js::OpCode::ThrowRuntimeError, m_func);
- instr->SetSrc1(IR::IntConstOpnd::New(SCODE_CODE(WASMERR_Unreachable), TyInt32, instr->m_func));
- AddInstr(instr, offset);
- break;
- case Js::OpCodeAsmJs::Ret:
- instr = IR::Instr::New(Js::OpCode::Ret, m_func);
- switch (m_asmFuncInfo->GetRetType())
- {
- case Js::AsmJsRetType::Which::Signed:
- retSlot = GetRegSlotFromIntReg(0);
- regOpnd = BuildDstOpnd(retSlot, TyInt32);
- regOpnd->SetValueType(ValueType::GetInt(false));
- break;
- case Js::AsmJsRetType::Which::Float:
- retSlot = GetRegSlotFromFloatReg(0);
- regOpnd = BuildDstOpnd(retSlot, TyFloat32);
- regOpnd->SetValueType(ValueType::Float);
- break;
- case Js::AsmJsRetType::Which::Double:
- retSlot = GetRegSlotFromDoubleReg(0);
- regOpnd = BuildDstOpnd(retSlot, TyFloat64);
- regOpnd->SetValueType(ValueType::Float);
- break;
- case Js::AsmJsVarType::Which::Int64:
- retSlot = GetRegSlotFromInt64Reg(0);
- regOpnd = BuildDstOpnd(retSlot, TyInt64);
- regOpnd->SetValueType(ValueType::GetInt(false));
- break;
- case Js::AsmJsRetType::Which::Void:
- retSlot = GetRegSlotFromVarReg(0);
- regOpnd = BuildDstOpnd(retSlot, TyVar);
- break;
- default:
- {
- IRType irType;
- ValueType vType;
- GetSimdTypesFromAsmType(Js::AsmJsRetType(m_asmFuncInfo->GetRetType()).toType().GetWhich(), &irType, &vType);
- retSlot = GetRegSlotFromSimd128Reg(0);
- regOpnd = BuildDstOpnd(retSlot, irType);
- regOpnd->SetValueType(vType);
- }
- }
- instr->SetSrc1(regOpnd);
- AddInstr(instr, offset);
- break;
- case Js::OpCodeAsmJs::Label:
- // NOP
- break;
- default:
- Assume(UNREACHED);
- }
- }
- template <typename SizePolicy>
- void
- IRBuilderAsmJs::BuildElementSlot(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- auto layout = m_jnReader.GetLayout<Js::OpLayoutT_ElementSlot<SizePolicy>>();
- //TraceIrBuilder(newOpcode, ElementSlot, layout);
- BuildElementSlot(newOpcode, offset, layout->SlotIndex, layout->Value, layout->Instance);
- }
- template <typename SizePolicy>
- void
- IRBuilderAsmJs::BuildAsmUnsigned1(Js::OpCodeAsmJs newOpcode, uint value)
- {
- // we do not support counter in loop body ,just read the layout here
- m_jnReader.GetLayout<Js::OpLayoutT_AsmUnsigned1<SizePolicy>>();
- }
- void
- IRBuilderAsmJs::BuildElementSlot(Js::OpCodeAsmJs newOpcode, uint32 offset, int32 slotIndex, Js::RegSlot value, Js::RegSlot instance)
- {
- Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- Assert(instance == 1 || newOpcode == Js::OpCodeAsmJs::LdArr_Func || newOpcode == Js::OpCodeAsmJs::LdArr_WasmFunc);
- Js::RegSlot valueRegSlot;
- IR::Opnd * slotOpnd;
- IR::RegOpnd * regOpnd;
- IR::Instr * instr = nullptr;
- WAsmJs::Types type;
- IRType irType;
- ValueType valueType;
- bool isStore = false;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::LdSlot:
- valueRegSlot = GetRegSlotFromVarReg(value);
- slotOpnd = BuildFieldOpnd(AsmJsRegSlots::ModuleMemReg, slotIndex, PropertyKindSlotArray, TyVar);
- regOpnd = BuildDstOpnd(valueRegSlot, TyVar);
- instr = IR::Instr::New(Js::OpCode::LdSlot, regOpnd, slotOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::LdSlotArr:
- valueRegSlot = GetRegSlotFromVarReg(value);
- slotOpnd = BuildFieldOpnd(AsmJsRegSlots::ModuleMemReg, slotIndex, PropertyKindSlots, TyVar);
- regOpnd = BuildDstOpnd(valueRegSlot, TyVar);
- instr = IR::Instr::New(Js::OpCode::LdSlot, regOpnd, slotOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::LdArr_Func:
- {
- IR::RegOpnd * baseOpnd = BuildSrcOpnd(GetRegSlotFromVarReg(instance), TyVar);
- IR::RegOpnd * indexOpnd = BuildSrcOpnd(GetRegSlotFromIntReg(slotIndex), TyUint32);
- IR::IndirOpnd * indirOpnd = IR::IndirOpnd::New(baseOpnd, indexOpnd, TyVar, m_func);
- regOpnd = BuildDstOpnd(GetRegSlotFromVarReg(value), TyVar);
- instr = IR::Instr::New(Js::OpCode::LdAsmJsFunc, regOpnd, indirOpnd, m_func);
- break;
- }
- case Js::OpCodeAsmJs::LdArr_WasmFunc:
- {
- IR::RegOpnd * baseOpnd = BuildSrcOpnd(GetRegSlotFromVarReg(instance), TyVar);
- IR::RegOpnd * indexOpnd = BuildSrcOpnd(GetRegSlotFromIntReg(slotIndex), TyUint32);
- regOpnd = BuildDstOpnd(GetRegSlotFromVarReg(value), TyVar);
- instr = IR::Instr::New(Js::OpCode::LdWasmFunc, regOpnd, baseOpnd, indexOpnd, m_func);
- break;
- }
- case Js::OpCodeAsmJs::StSlot_Int:
- case Js::OpCodeAsmJs::LdSlot_Int:
- type = WAsmJs::INT32;
- irType = TyInt32;
- valueType = ValueType::GetInt(false);
- isStore = newOpcode == Js::OpCodeAsmJs::StSlot_Int;
- goto ProcessGenericSlot;
- case Js::OpCodeAsmJs::StSlot_Long:
- case Js::OpCodeAsmJs::LdSlot_Long:
- type = WAsmJs::INT64;
- irType = TyInt64;
- valueType = ValueType::GetInt(false);
- isStore = newOpcode == Js::OpCodeAsmJs::StSlot_Long;
- goto ProcessGenericSlot;
- case Js::OpCodeAsmJs::StSlot_Flt:
- case Js::OpCodeAsmJs::LdSlot_Flt:
- type = WAsmJs::FLOAT32;
- irType = TyFloat32;
- valueType = ValueType::Float;
- isStore = newOpcode == Js::OpCodeAsmJs::StSlot_Flt;
- goto ProcessGenericSlot;
- case Js::OpCodeAsmJs::StSlot_Db:
- case Js::OpCodeAsmJs::LdSlot_Db:
- type = WAsmJs::FLOAT64;
- irType = TyFloat64;
- valueType = ValueType::Float;
- isStore = newOpcode == Js::OpCodeAsmJs::StSlot_Db;
- goto ProcessGenericSlot;
- case Js::OpCodeAsmJs::Simd128_StSlot_I4:
- case Js::OpCodeAsmJs::Simd128_LdSlot_I4:
- irType = TySimd128I4;
- isStore = newOpcode == Js::OpCodeAsmJs::Simd128_StSlot_I4;
- goto ProcessSimdSlot;
- case Js::OpCodeAsmJs::Simd128_StSlot_B4:
- case Js::OpCodeAsmJs::Simd128_LdSlot_B4:
- irType = TySimd128B4;
- isStore = newOpcode == Js::OpCodeAsmJs::Simd128_StSlot_B4;
- goto ProcessSimdSlot;
- case Js::OpCodeAsmJs::Simd128_StSlot_B8:
- case Js::OpCodeAsmJs::Simd128_LdSlot_B8:
- irType = TySimd128B8;
- isStore = newOpcode == Js::OpCodeAsmJs::Simd128_StSlot_B8;
- goto ProcessSimdSlot;
- case Js::OpCodeAsmJs::Simd128_StSlot_B16:
- case Js::OpCodeAsmJs::Simd128_LdSlot_B16:
- irType = TySimd128B16;
- isStore = newOpcode == Js::OpCodeAsmJs::Simd128_StSlot_B16;
- goto ProcessSimdSlot;
- case Js::OpCodeAsmJs::Simd128_StSlot_F4:
- case Js::OpCodeAsmJs::Simd128_LdSlot_F4:
- irType = TySimd128F4;
- isStore = newOpcode == Js::OpCodeAsmJs::Simd128_StSlot_F4;
- goto ProcessSimdSlot;
- #if 0
- case Js::OpCodeAsmJs::Simd128_StSlot_D2:
- case Js::OpCodeAsmJs::Simd128_LdSlot_D2:
- irType = TySimd128D2;
- isStore = newOpcode == Js::OpCodeAsmJs::Simd128_StSlot_D2;
- goto ProcessSimdSlot;
- #endif // 0
- case Js::OpCodeAsmJs::Simd128_StSlot_I8:
- case Js::OpCodeAsmJs::Simd128_LdSlot_I8:
- irType = TySimd128I8;
- isStore = newOpcode == Js::OpCodeAsmJs::Simd128_StSlot_I8;
- goto ProcessSimdSlot;
- case Js::OpCodeAsmJs::Simd128_StSlot_I16:
- case Js::OpCodeAsmJs::Simd128_LdSlot_I16:
- irType = TySimd128I16;
- isStore = newOpcode == Js::OpCodeAsmJs::Simd128_StSlot_I16;
- goto ProcessSimdSlot;
- case Js::OpCodeAsmJs::Simd128_StSlot_U4:
- case Js::OpCodeAsmJs::Simd128_LdSlot_U4:
- irType = TySimd128U4;
- isStore = newOpcode == Js::OpCodeAsmJs::Simd128_StSlot_U4;
- goto ProcessSimdSlot;
- case Js::OpCodeAsmJs::Simd128_StSlot_U8:
- case Js::OpCodeAsmJs::Simd128_LdSlot_U8:
- irType = TySimd128U8;
- isStore = newOpcode == Js::OpCodeAsmJs::Simd128_StSlot_U8;
- goto ProcessSimdSlot;
- case Js::OpCodeAsmJs::Simd128_StSlot_U16:
- case Js::OpCodeAsmJs::Simd128_LdSlot_U16:
- irType = TySimd128U16;
- isStore = newOpcode == Js::OpCodeAsmJs::Simd128_StSlot_U16;
- goto ProcessSimdSlot;
- default:
- Assume(UNREACHED);
- break;
- ProcessSimdSlot:
- type = WAsmJs::SIMD;
- valueType = GetSimdValueTypeFromIRType(irType);
- ProcessGenericSlot:
- valueRegSlot = GetRegSlotFromTypedReg(value, type);
- slotOpnd = BuildFieldOpnd(AsmJsRegSlots::ModuleMemReg, slotIndex, PropertyKindSlots, irType);
- if (isStore)
- {
- regOpnd = BuildSrcOpnd(valueRegSlot, irType);
- regOpnd->SetValueType(valueType);
- instr = IR::Instr::New(Js::OpCode::StSlot, slotOpnd, regOpnd, m_func);
- }
- else
- {
- regOpnd = BuildDstOpnd(valueRegSlot, irType);
- regOpnd->SetValueType(valueType);
- instr = IR::Instr::New(Js::OpCode::LdSlot, regOpnd, slotOpnd, m_func);
- }
- break;
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildStartCall(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- Assert(!OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- const unaligned Js::OpLayoutStartCall * layout = m_jnReader.StartCall();
- IR::RegOpnd * dstOpnd = IR::RegOpnd::New(TyVar, m_func);
- IR::IntConstOpnd * srcOpnd = IR::IntConstOpnd::New(layout->ArgCount, TyInt32, m_func);
- IR::Instr * instr = nullptr;
- StackSym * symDst = nullptr;
- IR::SymOpnd * argDst = nullptr;
- IR::AddrOpnd * addrOpnd = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::I_StartCall:
- instr = IR::Instr::New(Js::OpCode::StartCall, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- // save this so we can calculate arg offsets later on
- m_argOffsetStack->Push(layout->ArgCount);
- m_argStack->Push(instr);
- break;
- case Js::OpCodeAsmJs::StartCall:
- instr = IR::Instr::New(Js::OpCode::StartCall, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- // also need to add undefined as arg0
- addrOpnd = IR::AddrOpnd::New(m_func->GetScriptContextInfo()->GetUndefinedAddr(), IR::AddrOpndKindDynamicVar, m_func, true);
- addrOpnd->SetValueType(ValueType::Undefined);
- symDst = m_func->m_symTable->GetArgSlotSym(1);
- argDst = IR::SymOpnd::New(symDst, TyVar, m_func);
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, argDst, addrOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- break;
- default:
- Assume(UNREACHED);
- }
- }
- void
- IRBuilderAsmJs::InitializeMemAccessTypeInfo(Js::ArrayBufferView::ViewType viewType, _Out_ MemAccessTypeInfo * typeInfo)
- {
- typeInfo->type = TyInt32;
- typeInfo->valueRegType = WAsmJs::INT32;
- switch (viewType)
- {
- case Js::ArrayBufferView::TYPE_INT8_TO_INT64:
- typeInfo->valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_INT8:
- typeInfo->arrayType = ValueType::GetObject(ObjectType::Int8Array);
- typeInfo->type = TyInt8;
- break;
- case Js::ArrayBufferView::TYPE_UINT8_TO_INT64:
- typeInfo->valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_UINT8:
- typeInfo->arrayType = ValueType::GetObject(ObjectType::Uint8Array);
- typeInfo->type = TyUint8;
- break;
- case Js::ArrayBufferView::TYPE_INT16_TO_INT64:
- typeInfo->valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_INT16:
- typeInfo->arrayType = ValueType::GetObject(ObjectType::Int16Array);
- typeInfo->type = TyInt16;
- break;
- case Js::ArrayBufferView::TYPE_UINT16_TO_INT64:
- typeInfo->valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_UINT16:
- typeInfo->arrayType = ValueType::GetObject(ObjectType::Uint16Array);
- typeInfo->type = TyUint16;
- break;
- case Js::ArrayBufferView::TYPE_INT32_TO_INT64:
- typeInfo->valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_INT32:
- typeInfo->arrayType = ValueType::GetObject(ObjectType::Int32Array);
- typeInfo->type = TyInt32;
- break;
- case Js::ArrayBufferView::TYPE_UINT32_TO_INT64:
- typeInfo->valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_UINT32:
- typeInfo->arrayType = ValueType::GetObject(ObjectType::Uint32Array);
- typeInfo->type = TyUint32;
- break;
- case Js::ArrayBufferView::TYPE_FLOAT32:
- typeInfo->valueRegType = WAsmJs::FLOAT32;
- typeInfo->arrayType = ValueType::GetObject(ObjectType::Float32Array);
- typeInfo->type = TyFloat32;
- break;
- case Js::ArrayBufferView::TYPE_FLOAT64:
- typeInfo->valueRegType = WAsmJs::FLOAT64;
- typeInfo->arrayType = ValueType::GetObject(ObjectType::Float64Array);
- typeInfo->type = TyFloat64;
- break;
- case Js::ArrayBufferView::TYPE_INT64:
- typeInfo->valueRegType = WAsmJs::INT64;
- typeInfo->arrayType = ValueType::GetObject(ObjectType::Int64Array);
- typeInfo->type = TyInt64;
- break;
- default:
- Assume(UNREACHED);
- }
- }
- template <typename SizePolicy>
- void
- IRBuilderAsmJs::BuildWasmMemAccess(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- auto layout = m_jnReader.GetLayout<Js::OpLayoutT_WasmMemAccess<SizePolicy>>();
- BuildWasmMemAccess(newOpcode, offset, layout->SlotIndex, layout->Value, layout->Offset, layout->ViewType);
- }
- void
- IRBuilderAsmJs::BuildWasmMemAccess(Js::OpCodeAsmJs newOpcode, uint32 offset, uint32 slotIndex, Js::RegSlot value, uint32 constOffset, Js::ArrayBufferView::ViewType viewType)
- {
- bool isLd = newOpcode == Js::OpCodeAsmJs::LdArrWasm;
- Js::OpCode op = isLd ? Js::OpCode::LdArrViewElemWasm : Js::OpCode::StArrViewElem;
- MemAccessTypeInfo typeInfo;
- InitializeMemAccessTypeInfo(viewType, &typeInfo);
- Js::RegSlot valueRegSlot = GetRegSlotFromTypedReg(value, typeInfo.valueRegType);
- IR::Instr * instr = nullptr;
- IR::RegOpnd * regOpnd = nullptr;
- IR::IndirOpnd * indirOpnd = nullptr;
- Js::RegSlot indexRegSlot = GetRegSlotFromIntReg(slotIndex);
- IR::RegOpnd * indexOpnd = BuildSrcOpnd(indexRegSlot, TyUint32);
- indirOpnd = IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::BufferReg, TyVar), constOffset, typeInfo.type, m_func);
- indirOpnd->SetIndexOpnd(indexOpnd);
- indirOpnd->GetBaseOpnd()->SetValueType(typeInfo.arrayType);
- // Setup the value/destination
- if (typeInfo.valueRegType == WAsmJs::FLOAT32 || typeInfo.valueRegType == WAsmJs::FLOAT64)
- {
- Assert(IRType_IsFloat(typeInfo.type));
- regOpnd = !isLd ? BuildSrcOpnd(valueRegSlot, typeInfo.type) : BuildDstOpnd(valueRegSlot, typeInfo.type);
- regOpnd->SetValueType(ValueType::Float);
- }
- else if (typeInfo.valueRegType == WAsmJs::INT64)
- {
- Assert(IRType_IsNativeInt(typeInfo.type));
- regOpnd = !isLd ? BuildSrcOpnd(valueRegSlot, TyInt64) : BuildDstOpnd(valueRegSlot, TyInt64);
- regOpnd->SetValueType(ValueType::GetInt(false));
- }
- else
- {
- Assert(IRType_IsNativeInt(typeInfo.type));
- Assert(typeInfo.valueRegType == WAsmJs::INT32);
- regOpnd = !isLd ? BuildSrcOpnd(valueRegSlot, TyInt32) : BuildDstOpnd(valueRegSlot, TyInt32);
- regOpnd->SetValueType(ValueType::GetInt(false));
- }
- // Create the instruction
- if (isLd)
- {
- instr = IR::Instr::New(op, regOpnd, indirOpnd, m_func);
- }
- else
- {
- instr = IR::Instr::New(op, indirOpnd, regOpnd, m_func);
- }
- #if ENABLE_FAST_ARRAYBUFFER
- if (!CONFIG_FLAG(WasmFastArray))
- #endif
- {
- instr->SetSrc2(BuildSrcOpnd(AsmJsRegSlots::LengthReg, TyUint32));
- }
- AddInstr(instr, offset);
- #if DBG
- if (newOpcode == Js::OpCodeAsmJs::StArrWasm && PHASE_TRACE(Js::WasmMemWritesPhase, m_func))
- {
- IR::Opnd* prevArg = nullptr;
- auto PushArg = [&](ValueType valueType, IR::Opnd* srcOpnd) {
- IR::RegOpnd* dstOpnd = IR::RegOpnd::New(srcOpnd->GetType(), m_func);
- dstOpnd->SetValueType(valueType);
- IR::Instr* instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- if (prevArg)
- {
- instr->SetSrc2(prevArg);
- }
- prevArg = dstOpnd;
- AddInstr(instr, offset);
- };
- // static void TraceMemWrite(WebAssemblyMemory* mem, uint32 index, uint32 offset, Js::ArrayBufferView::ViewType viewType, uint bytecodeOffset, ScriptContext* context);
- // ScriptContext is added automatically by CallHelper lower
- PushArg(ValueType::GetInt(false), IR::IntConstOpnd::New(offset, TyUint32, m_func, true));
- PushArg(ValueType::GetInt(false), IR::IntConstOpnd::New(viewType, TyUint8, m_func, true));
- PushArg(ValueType::GetInt(false), IR::IntConstOpnd::New(constOffset, TyUint32, m_func));
- PushArg(ValueType::GetInt(false), indexOpnd);
- PushArg(ValueType::GetObject(ObjectType::Object), BuildSrcOpnd(AsmJsRegSlots::WasmMemoryReg, TyVar));
- IR::Instr* callInstr = IR::Instr::New(Js::OpCode::CallHelper, m_func);
- callInstr->SetSrc1(IR::HelperCallOpnd::New(IR::HelperOp_WasmMemoryTraceWrite, m_func));
- callInstr->SetSrc2(prevArg);
- AddInstr(callInstr, offset);
- }
- #endif
- }
- template <typename SizePolicy>
- void
- IRBuilderAsmJs::BuildAsmTypedArr(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- auto layout = m_jnReader.GetLayout<Js::OpLayoutT_AsmTypedArr<SizePolicy>>();
- BuildAsmTypedArr(newOpcode, offset, layout->SlotIndex, layout->Value, layout->ViewType);
- }
- void
- IRBuilderAsmJs::BuildAsmTypedArr(Js::OpCodeAsmJs newOpcode, uint32 offset, uint32 slotIndex, Js::RegSlot value, Js::ArrayBufferView::ViewType viewType)
- {
- bool isLd = newOpcode == Js::OpCodeAsmJs::LdArr || newOpcode == Js::OpCodeAsmJs::LdArrConst;
- Js::OpCode op = isLd ? Js::OpCode::LdArrViewElem : Js::OpCode::StArrViewElem;
- MemAccessTypeInfo typeInfo;
- InitializeMemAccessTypeInfo(viewType, &typeInfo);
- Js::RegSlot valueRegSlot = GetRegSlotFromTypedReg(value, typeInfo.valueRegType);
- IR::Instr * instr = nullptr;
- IR::Instr * maskInstr = nullptr;
- IR::RegOpnd * regOpnd = nullptr;
- IR::IndirOpnd * indirOpnd = nullptr;
- // Get the index
- if (newOpcode == Js::OpCodeAsmJs::LdArr || newOpcode == Js::OpCodeAsmJs::StArr)
- {
- uint32 mask = Js::ArrayBufferView::ViewMask[viewType];
- Js::RegSlot indexRegSlot = GetRegSlotFromIntReg(slotIndex);
- IR::RegOpnd * maskedOpnd = nullptr;
- if (mask != ~0)
- {
- maskedOpnd = IR::RegOpnd::New(TyUint32, m_func);
- maskInstr = IR::Instr::New(Js::OpCode::And_I4, maskedOpnd, BuildSrcOpnd(indexRegSlot, TyInt32), IR::IntConstOpnd::New(mask, TyUint32, m_func), m_func);
- AddInstr(maskInstr, offset);
- }
- else
- {
- maskedOpnd = BuildSrcOpnd(indexRegSlot, TyInt32);
- }
- indirOpnd = IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::BufferReg, TyVar), maskedOpnd, typeInfo.type, m_func);
- indirOpnd->GetBaseOpnd()->SetValueType(typeInfo.arrayType);
- }
- else
- {
- Assert(newOpcode == Js::OpCodeAsmJs::LdArrConst || newOpcode == Js::OpCodeAsmJs::StArrConst);
- indirOpnd = IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::BufferReg, TyVar), slotIndex, typeInfo.type, m_func);
- indirOpnd->GetBaseOpnd()->SetValueType(typeInfo.arrayType);
- }
- // Setup the value/destination
- if (typeInfo.valueRegType == WAsmJs::FLOAT32 || typeInfo.valueRegType == WAsmJs::FLOAT64)
- {
- Assert(IRType_IsFloat(typeInfo.type));
- regOpnd = !isLd ? BuildSrcOpnd(valueRegSlot, typeInfo.type) : BuildDstOpnd(valueRegSlot, typeInfo.type);
- regOpnd->SetValueType(ValueType::Float);
- }
- else
- {
- Assert(IRType_IsNativeInt(typeInfo.type));
- Assert(typeInfo.valueRegType == WAsmJs::INT32);
- regOpnd = !isLd ? BuildSrcOpnd(valueRegSlot, TyInt32) : BuildDstOpnd(valueRegSlot, TyInt32);
- regOpnd->SetValueType(ValueType::GetInt(false));
- }
- // Create the instruction
- if (isLd)
- {
- instr = IR::Instr::New(op, regOpnd, indirOpnd, m_func);
- }
- else
- {
- instr = IR::Instr::New(op, indirOpnd, regOpnd, m_func);
- }
- #if !ENABLE_FAST_ARRAYBUFFER
- instr->SetSrc2(BuildSrcOpnd(AsmJsRegSlots::LengthReg, TyUint32));
- #endif
- AddInstr(instr, offset);
- }
- template <typename SizePolicy>
- void
- IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- auto layout = m_jnReader.GetLayout<Js::OpLayoutT_AsmCall<SizePolicy>>();
- BuildAsmCall(newOpcode, offset, layout->ArgCount, layout->Return, layout->Function, layout->ReturnType);
- }
- void
- IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSlot argCount, Js::RegSlot ret, Js::RegSlot function, int8 returnType)
- {
- #if DBG
- int count = 0;
- #endif
- IR::Instr * instr = nullptr;
- IR::RegOpnd * dstOpnd = nullptr;
- IR::Opnd * srcOpnd = nullptr;
- Js::RegSlot dstRegSlot;
- Js::RegSlot srcRegSlot;
- int32 argOffset = 0;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::I_Call:
- srcRegSlot = GetRegSlotFromVarReg(function);
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyVar);
- switch ((Js::AsmJsRetType::Which)returnType)
- {
- case Js::AsmJsRetType::Which::Signed:
- dstRegSlot = GetRegSlotFromIntReg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- break;
- case Js::AsmJsRetType::Which::Float:
- dstRegSlot = GetRegSlotFromFloatReg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat32);
- dstOpnd->SetValueType(ValueType::Float);
- break;
- case Js::AsmJsRetType::Which::Double:
- dstRegSlot = GetRegSlotFromDoubleReg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat64);
- dstOpnd->SetValueType(ValueType::Float);
- break;
- case Js::AsmJsRetType::Which::Int64:
- dstRegSlot = GetRegSlotFromInt64Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TyInt64);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- break;
- case Js::AsmJsRetType::Which::Void:
- break;
- case Js::AsmJsRetType::Which::Float32x4:
- dstRegSlot = GetRegSlotFromSimd128Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128F4);
- break;
- case Js::AsmJsRetType::Which::Int32x4:
- dstRegSlot = GetRegSlotFromSimd128Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I4);
- break;
- case Js::AsmJsRetType::Which::Bool32x4:
- dstRegSlot = GetRegSlotFromSimd128Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128B4);
- break;
- case Js::AsmJsRetType::Which::Bool16x8:
- dstRegSlot = GetRegSlotFromSimd128Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128B8);
- break;
- case Js::AsmJsRetType::Which::Bool8x16:
- dstRegSlot = GetRegSlotFromSimd128Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128B16);
- break;
- case Js::AsmJsRetType::Which::Float64x2:
- dstRegSlot = GetRegSlotFromSimd128Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- break;
- case Js::AsmJsRetType::Which::Int16x8:
- dstRegSlot = GetRegSlotFromSimd128Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I8);
- break;
- case Js::AsmJsRetType::Which::Int8x16:
- dstRegSlot = GetRegSlotFromSimd128Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I16);
- break;
- case Js::AsmJsRetType::Which::Uint32x4:
- dstRegSlot = GetRegSlotFromSimd128Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U4);
- break;
- case Js::AsmJsRetType::Which::Uint16x8:
- dstRegSlot = GetRegSlotFromSimd128Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U8);
- break;
- case Js::AsmJsRetType::Which::Uint8x16:
- dstRegSlot = GetRegSlotFromSimd128Reg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U16);
- break;
- default:
- Assume(UNREACHED);
- }
- instr = IR::Instr::New(Js::OpCode::AsmJsCallI, m_func);
- instr->SetSrc1(srcOpnd);
- if (dstOpnd)
- {
- instr->SetDst(dstOpnd);
- }
- argOffset = m_argOffsetStack->Pop();
- argOffset -= MachPtr;
- break;
- case Js::OpCodeAsmJs::Call:
- srcRegSlot = GetRegSlotFromVarReg(function);
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyVar);
- dstRegSlot = GetRegSlotFromVarReg(ret);
- dstOpnd = BuildDstOpnd(dstRegSlot, TyVar);
- instr = IR::Instr::New(Js::OpCode::AsmJsCallE, dstOpnd, srcOpnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- IR::Instr * argInstr = nullptr;
- IR::Instr * prevInstr = instr;
- for (argInstr = m_argStack->Pop(); argInstr && argInstr->m_opcode != Js::OpCode::StartCall; argInstr = m_argStack->Pop())
- {
- if (newOpcode == Js::OpCodeAsmJs::I_Call)
- {
- #if _M_IX86
- argOffset -= argInstr->GetDst()->GetSize();
- #elif _M_X64
- argOffset -= (argInstr->GetDst()->GetSize() <= MachPtr ? MachPtr : argInstr->GetDst()->GetSize());
- #else
- Assert(UNREACHED);
- #endif
- argInstr->GetDst()->GetStackSym()->m_offset = argOffset;
- }
- // associate the ArgOuts with this call via src2
- prevInstr->SetSrc2(argInstr->GetDst());
- prevInstr = argInstr;
- #ifdef ENABLE_SIMDJS
- #if defined(_M_X64)
- if (m_func->IsSIMDEnabled())
- {
- m_tempList->Push(argInstr);
- }
- #endif
- #endif
- #if DBG
- count++;
- #endif
- }
- Assert(argOffset == 0);
- AnalysisAssert(argInstr);
- prevInstr->SetSrc2(argInstr->GetDst());
- #ifdef ENABLE_SIMDJS
- #if defined(_M_X64)
- // Without SIMD vars, all args are Var in size. So offset in Var = arg position in args list.
- // With SIMD, args have variable size, so we need to track argument position in the args list to be able to assign arg register for first four args on x64.
- if (m_func->IsSIMDEnabled())
- {
- for (uint i = 1; !m_tempList->Empty(); i++)
- {
- IR::Instr * instrArg = m_tempList->Pop();
- // record argument position and make room for implicit args
- instrArg->GetDst()->GetStackSym()->m_argPosition = i;
- if (newOpcode == Js::OpCodeAsmJs::I_Call)
- {
- // implicit func obj arg
- instrArg->GetDst()->GetStackSym()->m_argPosition += 1;
- }
- else
- {
- // implicit func obj + callInfo args
- Assert(newOpcode == Js::OpCodeAsmJs::Call);
- instrArg->GetDst()->GetStackSym()->m_argPosition += 2;
- }
- }
- }
- #endif
- #endif
- if (m_func->m_argSlotsForFunctionsCalled < argCount)
- {
- m_func->m_argSlotsForFunctionsCalled = argCount;
- }
- #ifdef ENABLE_WASM
- // heap buffer can change for wasm
- if (m_asmFuncInfo->UsesHeapBuffer() && m_func->GetJITFunctionBody()->IsWasmFunction())
- {
- BuildHeapBufferReload(offset);
- }
- #endif
- }
- void
- IRBuilderAsmJs::BuildAsmBr(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- Assert(!OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- const unaligned Js::OpLayoutAsmBr * branchInsn = m_jnReader.AsmBr();
- uint targetOffset = m_jnReader.GetCurrentOffset() + branchInsn->RelativeJumpOffset;
- if (newOpcode == Js::OpCodeAsmJs::EndSwitch_Int)
- {
- m_switchBuilder.EndSwitch(offset, targetOffset);
- return;
- }
- IR::BranchInstr * branchInstr = IR::BranchInstr::New(Js::OpCode::Br, NULL, m_func);
- AddBranchInstr(branchInstr, offset, targetOffset);
- }
- template <typename SizePolicy>
- void
- IRBuilderAsmJs::BuildAsmReg1(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- auto layout = m_jnReader.GetLayout<Js::OpLayoutT_AsmReg1<SizePolicy>>();
- BuildAsmReg1(newOpcode, offset, layout->R0);
- }
- void
- IRBuilderAsmJs::BuildAsmReg1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstReg)
- {
- if (newOpcode == Js::OpCodeAsmJs::LdUndef)
- {
- Js::RegSlot dstRegSlot = GetRegSlotFromVarReg(dstReg);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyVar);
- if (dstOpnd->m_sym->m_isSingleDef)
- {
- dstOpnd->m_sym->m_isConst = true;
- dstOpnd->m_sym->m_isNotInt = true;
- }
- IR::AddrOpnd * addrOpnd = IR::AddrOpnd::New(m_func->GetScriptContextInfo()->GetUndefinedAddr(), IR::AddrOpndKindDynamicVar, m_func, true);
- addrOpnd->SetValueType(ValueType::Undefined);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, addrOpnd, m_func);
- AddInstr(instr, offset);
- }
- else
- {
- Assert(newOpcode == Js::OpCodeAsmJs::CurrentMemory_Int);
- Js::RegSlot dstRegSlot = GetRegSlotFromIntReg(dstReg);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- IR::IntConstOpnd* constZero = IR::IntConstOpnd::New(0, TyInt32, m_func);
- IR::IntConstOpnd* constSixteen = IR::IntConstOpnd::New(16, TyUint8, m_func);
- IR::Instr * instr = m_asmFuncInfo->UsesHeapBuffer() ?
- IR::Instr::New(Js::OpCode::ShrU_I4, dstOpnd, BuildSrcOpnd(AsmJsRegSlots::LengthReg, TyUint32), constSixteen, m_func) :
- IR::Instr::New(Js::OpCode::Ld_I4, dstOpnd, constZero, m_func);
- AddInstr(instr, offset);
- }
- }
- #define BUILD_LAYOUT_IMPL(layout, ...) \
- template <typename SizePolicy> void IRBuilderAsmJs::Build##layout (Js::OpCodeAsmJs newOpcode, uint32 offset) \
- { \
- Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));\
- auto _layout = m_jnReader.GetLayout<Js::OpLayoutT_##layout <SizePolicy>>();\
- Build##layout(newOpcode, offset, __VA_ARGS__);\
- }
- #define RegProc(v) v
- #define IntProc(v) GetRegSlotFromIntReg(v)
- #define LongProc(v) GetRegSlotFromInt64Reg(v)
- #define FloatProc(v) GetRegSlotFromFloatReg(v)
- #define DoubleProc(v) GetRegSlotFromDoubleReg(v)
- #define IntConstProc(v) v
- #define LongConstProc(v) v
- #define FloatConstProc(v) v
- #define DoubleConstProc(v) v
- #define Float32x4Proc(v) GetRegSlotFromSimd128Reg(v)
- #define Bool32x4Proc(v) GetRegSlotFromSimd128Reg(v)
- #define Int32x4Proc(v) GetRegSlotFromSimd128Reg(v)
- #define Float64x2Proc(v) GetRegSlotFromSimd128Reg(v)
- #define Int16x8Proc(v) GetRegSlotFromSimd128Reg(v)
- #define Bool16x8Proc(v) GetRegSlotFromSimd128Reg(v)
- #define Int8x16Proc(v) GetRegSlotFromSimd128Reg(v)
- #define Bool8x16Proc(v) GetRegSlotFromSimd128Reg(v)
- #define Uint32x4Proc(v) GetRegSlotFromSimd128Reg(v)
- #define Uint16x8Proc(v) GetRegSlotFromSimd128Reg(v)
- #define Uint8x16Proc(v) GetRegSlotFromSimd128Reg(v)
- #define _PREFIX_HELPER(prefix, index) prefix##index
- #define _PREFIX_NAME(prefix, index) _PREFIX_HELPER(prefix, index)
- #define _M(ti, i) ti##Proc(_layout-> _PREFIX_NAME(LAYOUT_PREFIX_##ti(), i))
- #define LAYOUT_TYPE_WMS_REG2(layout, t0, t1) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1))
- #define LAYOUT_TYPE_WMS_REG3(layout, t0, t1, t2) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1), _M(t2, 2))
- #define LAYOUT_TYPE_WMS_REG4(layout, t0, t1, t2, t3) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1), _M(t2, 2), _M(t3, 3))
- #define LAYOUT_TYPE_WMS_REG5(layout, t0, t1, t2, t3, t4) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1), _M(t2, 2), _M(t3, 3), _M(t4, 4))
- #define LAYOUT_TYPE_WMS_REG6(layout, t0, t1, t2, t3, t4, t5) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1), _M(t2, 2), _M(t3, 3), _M(t4, 4), _M(t5, 5))
- #define LAYOUT_TYPE_WMS_REG7(layout, t0, t1, t2, t3, t4, t5, t6) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1), _M(t2, 2), _M(t3, 3), _M(t4, 4), _M(t5, 5), _M(t6, 6))
- #define LAYOUT_TYPE_WMS_REG9(layout, t0, t1, t2, t3, t4, t5, t6, t7, t8) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1), _M(t2, 2), _M(t3, 3), _M(t4, 4), _M(t5, 5), _M(t6, 6), _M(t7, 7), _M(t8, 8))
- #define LAYOUT_TYPE_WMS_REG10(layout, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1), _M(t2, 2), _M(t3, 3), _M(t4, 4), _M(t5, 5), _M(t6, 6), _M(t7, 7), _M(t8, 8), _M(t9, 9))
- #define LAYOUT_TYPE_WMS_REG11(layout, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1), _M(t2, 2), _M(t3, 3), _M(t4, 4), _M(t5, 5), _M(t6, 6), _M(t7, 7), _M(t8, 8), _M(t9, 9), _M(t10, 10))
- #define LAYOUT_TYPE_WMS_REG17(layout, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1), _M(t2, 2), _M(t3, 3), _M(t4, 4), _M(t5, 5), _M(t6, 6), _M(t7, 7), _M(t8, 8), _M(t9, 9), _M(t10, 10), _M(t11, 11), _M(t12, 12), _M(t13, 13), _M(t14, 14), _M(t15, 15), _M(t16, 16))
- #define LAYOUT_TYPE_WMS_REG18(layout, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1), _M(t2, 2), _M(t3, 3), _M(t4, 4), _M(t5, 5), _M(t6, 6), _M(t7, 7), _M(t8, 8), _M(t9, 9), _M(t10, 10), _M(t11, 11), _M(t12, 12), _M(t13, 13), _M(t14, 14), _M(t15, 15), _M(t16, 16), _M(t17, 17))
- #define LAYOUT_TYPE_WMS_REG19(layout, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18) BUILD_LAYOUT_IMPL(layout, _M(t0, 0), _M(t1, 1), _M(t2, 2), _M(t3, 3), _M(t4, 4), _M(t5, 5), _M(t6, 6), _M(t7, 7), _M(t8, 8), _M(t9, 9), _M(t10, 10), _M(t11, 11), _M(t12, 12), _M(t13, 13), _M(t14, 14), _M(t15, 15), _M(t16, 16), _M(t17, 17), _M(t18, 18))
- #define EXCLUDE_FRONTEND_LAYOUT
- #include "LayoutTypesAsmJs.h"
- #undef BUILD_LAYOUT_IMPL
- #undef _PREFIX_NAME
- #undef _PREFIX_HELPER
- #undef _M
- #undef RegProc
- #undef IntProc
- #undef LongProc
- #undef FloatProc
- #undef DoubleProc
- #undef IntConstProc
- #undef LongConstProc
- #undef FloatConstProc
- #undef DoubleConstProc
- #undef Float32x4Proc
- #undef Bool32x4Proc
- #undef Int32x4Proc
- #undef Float64x2Proc
- #undef Int16x8Proc
- #undef Bool16x8Proc
- #undef Int8x16Proc
- #undef Bool8x16Proc
- #undef Uint32x4Proc
- #undef Uint16x8Proc
- #undef Uint8x16Proc
- void IRBuilderAsmJs::BuildArgOut(IR::Opnd* srcOpnd, uint32 dstRegSlot, uint32 offset, IRType type, ValueType valueType)
- {
- Js::ArgSlot dstArgSlot = (Js::ArgSlot)dstRegSlot;
- if ((uint32)dstArgSlot != dstRegSlot)
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- StackSym * symDst = nullptr;
- if (type == TyVar)
- {
- symDst = m_func->m_symTable->GetArgSlotSym(ArgSlotMath::Add(dstArgSlot, 1));
- IR::Opnd * tmpDst = IR::RegOpnd::New(StackSym::New(m_func), TyVar, m_func);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::ToVar, tmpDst, srcOpnd, m_func);
- AddInstr(instr, offset);
- srcOpnd = tmpDst;
- }
- else
- {
- symDst = StackSym::NewArgSlotSym(dstArgSlot, m_func, type);
- symDst->m_allocated = true;
- }
- IR::Opnd * dstOpnd = IR::SymOpnd::New(symDst, type, m_func);
- if (!valueType.IsUninitialized())
- {
- dstOpnd->SetValueType(valueType);
- }
- IR::Instr * instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- void IRBuilderAsmJs::BuildFromVar(uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot, IRType irType, ValueType valueType)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(GetRegSlotFromVarReg(srcRegSlot), TyVar);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, irType);
- dstOpnd->SetValueType(valueType);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::FromVar, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildInt1Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyFloat64);
- srcOpnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Conv_DTI:
- dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- break;
- case Js::OpCodeAsmJs::Conv_DTU:
- dstOpnd = BuildDstOpnd(dstRegSlot, TyUint32);
- break;
- case Js::OpCodeAsmJs::Conv_Check_DTI:
- case Js::OpCodeAsmJs::Conv_Check_DTU:
- {
- IR::RegOpnd* tmpDst = IR::RegOpnd::New(TyFloat64, m_func);
- tmpDst->SetValueType(ValueType::Float);
- AddInstr(IR::Instr::New(Js::OpCode::TrapIfTruncOverflow, tmpDst, srcOpnd, m_func), offset);
- dstOpnd = BuildDstOpnd(dstRegSlot, newOpcode == Js::OpCodeAsmJs::Conv_Check_DTI ? TyInt32 : TyUint32);
- dstOpnd->m_dontDeadStore = true;
- srcOpnd = tmpDst;
- break;
- }
- default:
- Assume(UNREACHED);
- }
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Conv_Prim, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildInt1Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyFloat32);
- srcOpnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = nullptr;
- Js::OpCode op = Js::OpCode::Nop;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Conv_FTI:
- dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- op = Js::OpCode::Conv_Prim;
- break;
- case Js::OpCodeAsmJs::Conv_FTU:
- dstOpnd = BuildDstOpnd(dstRegSlot, TyUint32);
- op = Js::OpCode::Conv_Prim;
- break;
- case Js::OpCodeAsmJs::Reinterpret_FTI:
- dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- op = Js::OpCode::Reinterpret_Prim;
- break;
- case Js::OpCodeAsmJs::Conv_Check_FTI:
- case Js::OpCodeAsmJs::Conv_Check_FTU:
- {
- IR::RegOpnd* tmpDst = IR::RegOpnd::New(TyFloat32, m_func);
- tmpDst->SetValueType(ValueType::Float);
- AddInstr(IR::Instr::New(Js::OpCode::TrapIfTruncOverflow, tmpDst, srcOpnd, m_func), offset);
- dstOpnd = BuildDstOpnd(dstRegSlot, newOpcode == Js::OpCodeAsmJs::Conv_Check_FTI ? TyInt32 : TyUint32);
- dstOpnd->m_dontDeadStore = true;
- srcOpnd = tmpDst;
- op = Js::OpCode::Conv_Prim;
- break;
- }
- default:
- Assume(UNREACHED);
- }
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = IR::Instr::New(op, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildDouble1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Conv_ITD:
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyInt32);
- break;
- case Js::OpCodeAsmJs::Conv_UTD:
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyUint32);
- break;
- default:
- Assume(UNREACHED);
- }
- srcOpnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat64);
- dstOpnd->SetValueType(ValueType::Float);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Conv_Prim, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildDouble1Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Conv_FTD);
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyFloat32);
- srcOpnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat64);
- srcOpnd->SetValueType(ValueType::Float);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Conv_Prim, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat1Reg1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Conv_VTF);
- BuildFromVar(offset, dstRegSlot, srcRegSlot, TyFloat32, ValueType::Float);
- }
- void
- IRBuilderAsmJs::BuildDouble1Reg1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Conv_VTD);
- BuildFromVar(offset, dstRegSlot, srcRegSlot, TyFloat64, ValueType::Float);
- }
- void
- IRBuilderAsmJs::BuildInt1Reg1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Conv_VTI);
- BuildFromVar(offset, dstRegSlot, srcRegSlot, TyInt32, ValueType::GetInt(false));
- }
- void
- IRBuilderAsmJs::BuildReg1Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstReg, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyFloat64);
- srcOpnd->SetValueType(ValueType::Float);
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::ArgOut_Db:
- BuildArgOut(srcOpnd, dstReg, offset, TyVar);
- break;
- case Js::OpCodeAsmJs::I_ArgOut_Db:
- BuildArgOut(srcOpnd, dstReg, offset, TyFloat64, ValueType::Float);
- break;
- default:
- Assume(UNREACHED);
- }
- }
- void
- IRBuilderAsmJs::BuildReg1Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstReg, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyFloat32);
- srcOpnd->SetValueType(ValueType::Float);
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::ArgOut_Flt:
- BuildArgOut(srcOpnd, dstReg, offset, TyVar);
- break;
- case Js::OpCodeAsmJs::I_ArgOut_Flt:
- BuildArgOut(srcOpnd, dstReg, offset, TyFloat32, ValueType::Float);
- break;
- default:
- Assume(UNREACHED);
- }
- }
- void
- IRBuilderAsmJs::BuildReg1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstReg, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyInt32);
- srcOpnd->SetValueType(ValueType::GetInt(false));
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::ArgOut_Int:
- BuildArgOut(srcOpnd, dstReg, offset, TyVar);
- break;
- case Js::OpCodeAsmJs::I_ArgOut_Int:
- BuildArgOut(srcOpnd, dstReg, offset, TyInt32, ValueType::GetInt(false));
- break;
- default:
- Assume(UNREACHED);
- }
- }
- void
- IRBuilderAsmJs::BuildInt1Const1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, int constInt)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Ld_IntConst);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Ld_I4, dstOpnd, IR::IntConstOpnd::New(constInt, TyInt32, m_func), m_func);
- if (dstOpnd->m_sym->IsSingleDef())
- {
- dstOpnd->m_sym->SetIsIntConst(constInt);
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildReg1IntConst1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot reg1, int constInt)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::CheckSignature);
- IR::RegOpnd * funcReg = BuildSrcOpnd(reg1, TyMachPtr);
- IR::IntConstOpnd * sigIndex = IR::IntConstOpnd::New(constInt, TyInt32, m_func);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::CheckWasmSignature, m_func);
- instr->SetSrc1(funcReg);
- instr->SetSrc2(sigIndex);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat1Const1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, float constVal)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Ld_FltConst);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat32);
- dstOpnd->SetValueType(ValueType::Float);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::LdC_F8_R8, dstOpnd, IR::FloatConstOpnd::New(constVal, TyFloat32, m_func), m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildDouble1Const1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, double constVal)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Ld_DbConst);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat64);
- dstOpnd->SetValueType(ValueType::Float);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::LdC_F8_R8, dstOpnd, IR::FloatConstOpnd::New(constVal, TyFloat64, m_func), m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildInt1Double2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyFloat64);
- src1Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyFloat64);
- src2Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::CmLt_Db:
- instr = IR::Instr::New(Js::OpCode::CmLt_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmLe_Db:
- instr = IR::Instr::New(Js::OpCode::CmLe_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGt_Db:
- instr = IR::Instr::New(Js::OpCode::CmGt_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGe_Db:
- instr = IR::Instr::New(Js::OpCode::CmGe_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmEq_Db:
- instr = IR::Instr::New(Js::OpCode::CmEq_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmNe_Db:
- instr = IR::Instr::New(Js::OpCode::CmNeq_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildInt1Float2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyFloat32);
- src1Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyFloat32);
- src2Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::CmLt_Flt:
- instr = IR::Instr::New(Js::OpCode::CmLt_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmLe_Flt:
- instr = IR::Instr::New(Js::OpCode::CmLe_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGt_Flt:
- instr = IR::Instr::New(Js::OpCode::CmGt_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGe_Flt:
- instr = IR::Instr::New(Js::OpCode::CmGe_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmEq_Flt:
- instr = IR::Instr::New(Js::OpCode::CmEq_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmNe_Flt:
- instr = IR::Instr::New(Js::OpCode::CmNeq_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildInt2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyInt32);
- srcOpnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::BeginSwitch_Int:
- m_switchBuilder.BeginSwitch();
- // fall-through
- case Js::OpCodeAsmJs::Ld_Int:
- instr = IR::Instr::New(Js::OpCode::Ld_I4, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Neg_Int:
- instr = IR::Instr::New(Js::OpCode::Neg_I4, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Not_Int:
- instr = IR::Instr::New(Js::OpCode::Not_I4, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::LogNot_Int:
- instr = IR::Instr::New(Js::OpCode::CmEq_I4, dstOpnd, srcOpnd, IR::IntConstOpnd::New(0, TyInt32, m_func), m_func);
- break;
- case Js::OpCodeAsmJs::Conv_ITB:
- instr = IR::Instr::New(Js::OpCode::CmNeq_I4, dstOpnd, srcOpnd, IR::IntConstOpnd::New(0, TyInt32, m_func), m_func);
- break;
- case Js::OpCodeAsmJs::Abs_Int:
- instr = IR::Instr::New(Js::OpCode::InlineMathAbs, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Clz32_Int:
- instr = IR::Instr::New(Js::OpCode::InlineMathClz, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Ctz_Int:
- instr = IR::Instr::New(Js::OpCode::Ctz, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::I_Conv_VTI:
- instr = IR::Instr::New(Js::OpCode::Ld_I4, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::PopCnt_Int:
- instr = IR::Instr::New(Js::OpCode::PopCnt, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Return_Int:
- instr = IR::Instr::New(Js::OpCode::Ld_I4, dstOpnd, srcOpnd, m_func);
- if (m_func->IsLoopBody())
- {
- IR::Instr* slotInstr = GenerateStSlotForReturn(srcOpnd, IRType::TyInt32);
- AddInstr(slotInstr, offset);
- }
- break;
- case Js::OpCodeAsmJs::Eqz_Int:
- instr = IR::Instr::New(Js::OpCode::CmEq_I4, dstOpnd, srcOpnd, IR::IntConstOpnd::New(0, TyInt32, m_func), m_func);
- break;
- case Js::OpCodeAsmJs::GrowMemory:
- instr = IR::Instr::New(Js::OpCode::GrowWasmMemory, dstOpnd, BuildSrcOpnd(AsmJsRegSlots::WasmMemoryReg, TyVar), srcOpnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- if (newOpcode == Js::OpCodeAsmJs::GrowMemory)
- {
- BuildHeapBufferReload(offset);
- }
- }
- IR::RegOpnd* IRBuilderAsmJs::BuildTrapIfZero(IR::RegOpnd* srcOpnd, uint32 offset)
- {
- IR::RegOpnd* newSrc = IR::RegOpnd::New(srcOpnd->GetType(), m_func);
- newSrc->SetValueType(ValueType::GetInt(false));
- AddInstr(IR::Instr::New(Js::OpCode::TrapIfZero, newSrc, srcOpnd, m_func), offset);
- return newSrc;
- }
- IR::RegOpnd* IRBuilderAsmJs::BuildTrapIfMinIntOverNegOne(IR::RegOpnd* src1Opnd, IR::RegOpnd* src2Opnd, uint32 offset)
- {
- IR::RegOpnd* newSrc = IR::RegOpnd::New(src2Opnd->GetType(), m_func);
- newSrc->SetValueType(ValueType::GetInt(false));
- AddInstr(IR::Instr::New(Js::OpCode::TrapIfMinIntOverNegOne, newSrc, src1Opnd, src2Opnd, m_func), offset);
- return newSrc;
- }
- void
- IRBuilderAsmJs::BuildInt3(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyInt32);
- src1Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Add_Int:
- instr = IR::Instr::New(Js::OpCode::Add_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Sub_Int:
- instr = IR::Instr::New(Js::OpCode::Sub_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Mul_Int:
- instr = IR::Instr::New(Js::OpCode::Mul_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Div_Trap_UInt:
- src1Opnd->SetType(TyUint32);
- src2Opnd->SetType(TyUint32);
- // Fall through for trap
- case Js::OpCodeAsmJs::Div_Trap_Int:
- #ifdef _WIN32
- if (CONFIG_FLAG(WasmMathExFilter))
- {
- // Do not emit traps, but make sure we don't remove the div
- dstOpnd->m_dontDeadStore = true;
- }
- else
- #endif
- {
- src2Opnd = BuildTrapIfZero(src2Opnd, offset);
- if (newOpcode == Js::OpCodeAsmJs::Div_Trap_Int)
- {
- src1Opnd = BuildTrapIfMinIntOverNegOne(src1Opnd, src2Opnd, offset);
- }
- }
- instr = IR::Instr::New(newOpcode == Js::OpCodeAsmJs::Div_Trap_UInt ? Js::OpCode::DivU_I4 : Js::OpCode::Div_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Div_UInt:
- src1Opnd->SetType(TyUint32);
- src2Opnd->SetType(TyUint32);
- instr = IR::Instr::New(Js::OpCode::DivU_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Div_Int:
- instr = IR::Instr::New(Js::OpCode::Div_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Rem_Trap_UInt:
- src1Opnd->SetType(TyUint32);
- src2Opnd->SetType(TyUint32);
- // Fall through for trap
- case Js::OpCodeAsmJs::Rem_Trap_Int:
- #ifdef _WIN32
- if (CONFIG_FLAG(WasmMathExFilter))
- {
- // Do not emit traps, but make sure we don't remove the rem
- dstOpnd->m_dontDeadStore = true;
- }
- else
- #endif
- {
- src2Opnd = BuildTrapIfZero(src2Opnd, offset);
- }
- instr = IR::Instr::New(newOpcode == Js::OpCodeAsmJs::Rem_Trap_UInt ? Js::OpCode::RemU_I4 : Js::OpCode::Rem_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Rem_UInt:
- src1Opnd->SetType(TyUint32);
- src2Opnd->SetType(TyUint32);
- instr = IR::Instr::New(Js::OpCode::RemU_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Rem_Int:
- instr = IR::Instr::New(Js::OpCode::Rem_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::And_Int:
- instr = IR::Instr::New(Js::OpCode::And_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Or_Int:
- instr = IR::Instr::New(Js::OpCode::Or_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Xor_Int:
- instr = IR::Instr::New(Js::OpCode::Xor_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Shl_Int:
- instr = IR::Instr::New(Js::OpCode::Shl_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Shr_Int:
- instr = IR::Instr::New(Js::OpCode::Shr_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Shr_UInt:
- instr = IR::Instr::New(Js::OpCode::ShrU_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmLt_Int:
- instr = IR::Instr::New(Js::OpCode::CmLt_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmLe_Int:
- instr = IR::Instr::New(Js::OpCode::CmLe_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGt_Int:
- instr = IR::Instr::New(Js::OpCode::CmGt_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGe_Int:
- instr = IR::Instr::New(Js::OpCode::CmGe_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmEq_Int:
- instr = IR::Instr::New(Js::OpCode::CmEq_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmNe_Int:
- instr = IR::Instr::New(Js::OpCode::CmNeq_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmLt_UInt:
- instr = IR::Instr::New(Js::OpCode::CmUnLt_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmLe_UInt:
- instr = IR::Instr::New(Js::OpCode::CmUnLe_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGt_UInt:
- instr = IR::Instr::New(Js::OpCode::CmUnGt_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGe_UInt:
- instr = IR::Instr::New(Js::OpCode::CmUnGe_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Min_Int:
- instr = IR::Instr::New(Js::OpCode::InlineMathMin, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Max_Int:
- instr = IR::Instr::New(Js::OpCode::InlineMathMax, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Imul_Int:
- instr = IR::Instr::New(Js::OpCode::InlineMathImul, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Rol_Int:
- instr = IR::Instr::New(Js::OpCode::Rol_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Ror_Int:
- instr = IR::Instr::New(Js::OpCode::Ror_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildDouble2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyFloat64);
- srcOpnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat64);
- dstOpnd->SetValueType(ValueType::Float);
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Ld_Db:
- instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Neg_Db:
- instr = IR::Instr::New(Js::OpCode::Neg_A, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Sin_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathSin, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Cos_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathCos, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Tan_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathTan, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Asin_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathAsin, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Acos_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathAcos, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Atan_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathAtan, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Abs_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathAbs, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Ceil_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathCeil, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Floor_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathFloor, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Exp_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathExp, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Log_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathLog, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Sqrt_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathSqrt, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Return_Db:
- instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- if (m_func->IsLoopBody())
- {
- IR::Instr* slotInstr = GenerateStSlotForReturn(srcOpnd, IRType::TyFloat64);
- AddInstr(slotInstr, offset);
- }
- break;
- case Js::OpCodeAsmJs::I_Conv_VTD:
- instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Trunc_Db:
- instr = IR::Instr::New(Js::OpCode::Trunc_A, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Nearest_Db:
- instr = IR::Instr::New(Js::OpCode::Nearest_A, dstOpnd, srcOpnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyFloat32);
- srcOpnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat32);
- dstOpnd->SetValueType(ValueType::Float);
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Ld_Flt:
- instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Neg_Flt:
- instr = IR::Instr::New(Js::OpCode::Neg_A, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Ceil_Flt:
- instr = IR::Instr::New(Js::OpCode::InlineMathCeil, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Floor_Flt:
- instr = IR::Instr::New(Js::OpCode::InlineMathFloor, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Sqrt_Flt:
- instr = IR::Instr::New(Js::OpCode::InlineMathSqrt, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Abs_Flt:
- instr = IR::Instr::New(Js::OpCode::InlineMathAbs, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Fround_Flt:
- instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Return_Flt:
- instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- if (m_func->IsLoopBody())
- {
- IR::Instr* slotInstr = GenerateStSlotForReturn(srcOpnd, IRType::TyFloat32);
- AddInstr(slotInstr, offset);
- }
- break;
- case Js::OpCodeAsmJs::I_Conv_VTF:
- instr = IR::Instr::New(Js::OpCode::Ld_A, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Trunc_Flt:
- instr = IR::Instr::New(Js::OpCode::Trunc_A, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Nearest_Flt:
- instr = IR::Instr::New(Js::OpCode::Nearest_A, dstOpnd, srcOpnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat3(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyFloat32);
- src1Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyFloat32);
- src2Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat32);
- dstOpnd->SetValueType(ValueType::Float);
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Add_Flt:
- instr = IR::Instr::New(Js::OpCode::Add_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Sub_Flt:
- instr = IR::Instr::New(Js::OpCode::Sub_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Mul_Flt:
- instr = IR::Instr::New(Js::OpCode::Mul_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Div_Flt:
- instr = IR::Instr::New(Js::OpCode::Div_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Copysign_Flt:
- instr = IR::Instr::New(Js::OpCode::Copysign_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Min_Flt:
- instr = IR::Instr::New(Js::OpCode::InlineMathMin, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Max_Flt:
- instr = IR::Instr::New(Js::OpCode::InlineMathMax, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat1Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Fround_Db);
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyFloat64);
- srcOpnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat32);
- dstOpnd->SetValueType(ValueType::Float);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::InlineMathFround, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Fround_Int || newOpcode == Js::OpCodeAsmJs::Conv_UTF || newOpcode == Js::OpCodeAsmJs::Reinterpret_ITF);
- Js::OpCode op = Js::OpCode::Conv_Prim;
- IR::RegOpnd * srcOpnd = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Fround_Int:
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyInt32);
- break;
- case Js::OpCodeAsmJs::Conv_UTF:
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyUint32);
- break;
- case Js::OpCodeAsmJs::Reinterpret_ITF:
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyInt32);
- op = Js::OpCode::Reinterpret_Prim;
- break;
- default:
- Assume(UNREACHED);
- }
- srcOpnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat32);
- dstOpnd->SetValueType(ValueType::Float);
- IR::Instr * instr = IR::Instr::New(op, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildDouble3(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyFloat64);
- src1Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyFloat64);
- src2Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat64);
- dstOpnd->SetValueType(ValueType::Float);
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Add_Db:
- instr = IR::Instr::New(Js::OpCode::Add_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Sub_Db:
- instr = IR::Instr::New(Js::OpCode::Sub_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Mul_Db:
- instr = IR::Instr::New(Js::OpCode::Mul_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Div_Db:
- instr = IR::Instr::New(Js::OpCode::Div_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Rem_Db:
- instr = IR::Instr::New(Js::OpCode::Rem_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Pow_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathPow, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Atan2_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathAtan2, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Min_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathMin, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Max_Db:
- instr = IR::Instr::New(Js::OpCode::InlineMathMax, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Copysign_Db:
- instr = IR::Instr::New(Js::OpCode::Copysign_A, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- }
- template <typename SizePolicy>
- void
- IRBuilderAsmJs::BuildBrInt1(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- auto layout = m_jnReader.GetLayout<Js::OpLayoutT_BrInt1<SizePolicy>>();
- BuildBrInt1(newOpcode, offset, layout->RelativeJumpOffset, layout->I1);
- }
- void
- IRBuilderAsmJs::BuildBrInt1(Js::OpCodeAsmJs newOpcode, uint32 offset, int32 relativeOffset, Js::RegSlot src)
- {
- Js::OpCode op = Js::OpCode::Nop;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::BrTrue_Int:
- op = Js::OpCode::BrTrue_I4;
- break;
- case Js::OpCodeAsmJs::BrFalse_Int:
- op = Js::OpCode::BrFalse_I4;
- break;
- default:
- Assume(UNREACHED);
- }
- Js::RegSlot src1RegSlot = GetRegSlotFromIntReg(src);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyInt32);
- src1Opnd->SetValueType(ValueType::GetInt(false));
- uint targetOffset = m_jnReader.GetCurrentOffset() + relativeOffset;
- IR::BranchInstr * branchInstr = IR::BranchInstr::New(op, nullptr, src1Opnd, m_func);
- AddBranchInstr(branchInstr, offset, targetOffset);
- }
- template <typename SizePolicy>
- void
- IRBuilderAsmJs::BuildBrInt2(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- auto layout = m_jnReader.GetLayout<Js::OpLayoutT_BrInt2<SizePolicy>>();
- BuildBrInt2(newOpcode, offset, layout->RelativeJumpOffset, layout->I1, layout->I2);
- }
- template <typename SizePolicy>
- void
- IRBuilderAsmJs::BuildBrInt1Const1(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- auto layout = m_jnReader.GetLayout<Js::OpLayoutT_BrInt1Const1<SizePolicy>>();
- BuildBrInt1Const1(newOpcode, offset, layout->RelativeJumpOffset, layout->I1, layout->C1);
- }
- void
- IRBuilderAsmJs::BuildBrInt2(Js::OpCodeAsmJs newOpcode, uint32 offset, int32 relativeOffset, Js::RegSlot src1, Js::RegSlot src2)
- {
- Js::RegSlot src1RegSlot = GetRegSlotFromIntReg(src1);
- Js::RegSlot src2RegSlot = GetRegSlotFromIntReg(src2);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyInt32);
- src1Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- BuildBrCmp(newOpcode, offset, relativeOffset, src1Opnd, src2Opnd);
- }
- void
- IRBuilderAsmJs::BuildBrInt1Const1(Js::OpCodeAsmJs newOpcode, uint32 offset, int32 relativeOffset, Js::RegSlot src1, int32 src2)
- {
- Js::RegSlot src1RegSlot = GetRegSlotFromIntReg(src1);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyInt32);
- src1Opnd->SetValueType(ValueType::GetInt(false));
- IR::Opnd * src2Opnd = IR::IntConstOpnd::New(src2, TyInt32, this->m_func);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- BuildBrCmp(newOpcode, offset, relativeOffset, src1Opnd, src2Opnd);
- }
- void
- IRBuilderAsmJs::BuildBrCmp(Js::OpCodeAsmJs newOpcode, uint32 offset, int32 relativeOffset, IR::RegOpnd* src1Opnd, IR::Opnd* src2Opnd)
- {
- uint targetOffset = m_jnReader.GetCurrentOffset() + relativeOffset;
- if (newOpcode == Js::OpCodeAsmJs::Case_Int || newOpcode == Js::OpCodeAsmJs::Case_IntConst)
- {
- // branches for cases are generated entirely by the switch builder
- m_switchBuilder.OnCase(
- src1Opnd,
- src2Opnd,
- offset,
- targetOffset);
- }
- else
- {
- Assert(newOpcode == Js::OpCodeAsmJs::BrEq_Int);
- IR::BranchInstr * branchInstr = IR::BranchInstr::New(Js::OpCode::BrEq_I4, nullptr, src1Opnd, src2Opnd, m_func);
- AddBranchInstr(branchInstr, offset, targetOffset);
- }
- }
- void
- IRBuilderAsmJs::BuildLong1Reg1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Conv_VTL);
- BuildFromVar(offset, dstRegSlot, src1RegSlot, TyInt64, ValueType::GetInt(false));
- }
- void
- IRBuilderAsmJs::BuildReg1Long1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstReg, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyInt64);
- srcOpnd->SetValueType(ValueType::GetInt(false));
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::ArgOut_Long:
- BuildArgOut(srcOpnd, dstReg, offset, TyVar);
- break;
- case Js::OpCodeAsmJs::I_ArgOut_Long:
- BuildArgOut(srcOpnd, dstReg, offset, TyInt64, ValueType::GetInt(false));
- break;
- default:
- Assume(UNREACHED);
- }
- }
- void
- IRBuilderAsmJs::BuildLong1Const1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, int64 constInt64)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Ld_LongConst);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt64);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Ld_I4, dstOpnd, IR::Int64ConstOpnd::New(constInt64, TyInt64, m_func), m_func);
- if (dstOpnd->m_sym->IsSingleDef())
- {
- dstOpnd->m_sym->SetIsInt64Const();
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildLong2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyInt64);
- srcOpnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt64);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Ld_Long:
- instr = IR::Instr::New(Js::OpCode::Ld_I4, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Clz_Long:
- instr = IR::Instr::New(Js::OpCode::InlineMathClz, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Ctz_Long:
- instr = IR::Instr::New(Js::OpCode::Ctz, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::PopCnt_Long:
- instr = IR::Instr::New(Js::OpCode::PopCnt, dstOpnd, srcOpnd, m_func);
- break;
- case Js::OpCodeAsmJs::Return_Long:
- instr = IR::Instr::New(Js::OpCode::Ld_I4, dstOpnd, srcOpnd, m_func);
- if (m_func->IsLoopBody())
- {
- IR::Instr* slotInstr = GenerateStSlotForReturn(srcOpnd, IRType::TyInt64);
- AddInstr(slotInstr, offset);
- }
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildLong3(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyInt64);
- src1Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt64);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt64);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Add_Long:
- instr = IR::Instr::New(Js::OpCode::Add_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Sub_Long:
- instr = IR::Instr::New(Js::OpCode::Sub_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Mul_Long:
- instr = IR::Instr::New(Js::OpCode::Mul_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Div_Trap_ULong:
- src1Opnd->SetType(TyUint64);
- src2Opnd->SetType(TyUint64);
- // Fall Through for trap
- case Js::OpCodeAsmJs::Div_Trap_Long:
- {
- #ifdef _WIN32
- if (CONFIG_FLAG(WasmMathExFilter))
- {
- // Do not emit traps, but make sure we don't remove the div
- dstOpnd->m_dontDeadStore = true;
- }
- else
- #endif
- {
- src2Opnd = BuildTrapIfZero(src2Opnd, offset);
- if (newOpcode == Js::OpCodeAsmJs::Div_Trap_Long)
- {
- src1Opnd = BuildTrapIfMinIntOverNegOne(src1Opnd, src2Opnd, offset);
- }
- }
- Js::OpCode op = newOpcode == Js::OpCodeAsmJs::Div_Trap_ULong ? Js::OpCode::DivU_I4 : Js::OpCode::Div_I4;
- instr = IR::Instr::New(op, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- }
- case Js::OpCodeAsmJs::Rem_Trap_ULong:
- src1Opnd->SetType(TyUint64);
- src2Opnd->SetType(TyUint64);
- // Fall Through for trap
- case Js::OpCodeAsmJs::Rem_Trap_Long:
- {
- #ifdef _WIN32
- if (CONFIG_FLAG(WasmMathExFilter))
- {
- // Do not emit traps, but make sure we don't remove the rem
- dstOpnd->m_dontDeadStore = true;
- }
- else
- #endif
- {
- src2Opnd = BuildTrapIfZero(src2Opnd, offset);
- }
- Js::OpCode op = newOpcode == Js::OpCodeAsmJs::Rem_Trap_ULong ? Js::OpCode::RemU_I4 : Js::OpCode::Rem_I4;
- instr = IR::Instr::New(op, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- }
- case Js::OpCodeAsmJs::And_Long:
- instr = IR::Instr::New(Js::OpCode::And_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Or_Long:
- instr = IR::Instr::New(Js::OpCode::Or_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Xor_Long:
- instr = IR::Instr::New(Js::OpCode::Xor_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Shl_Long:
- instr = IR::Instr::New(Js::OpCode::Shl_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Shr_Long:
- instr = IR::Instr::New(Js::OpCode::Shr_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Shr_ULong:
- instr = IR::Instr::New(Js::OpCode::ShrU_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Rol_Long:
- instr = IR::Instr::New(Js::OpCode::Rol_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Ror_Long:
- instr = IR::Instr::New(Js::OpCode::Ror_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildInt1Long2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyInt64);
- src1Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt64);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::CmLt_Long:
- instr = IR::Instr::New(Js::OpCode::CmLt_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmLe_Long:
- instr = IR::Instr::New(Js::OpCode::CmLe_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGt_Long:
- instr = IR::Instr::New(Js::OpCode::CmGt_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGe_Long:
- instr = IR::Instr::New(Js::OpCode::CmGe_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmEq_Long:
- instr = IR::Instr::New(Js::OpCode::CmEq_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmNe_Long:
- instr = IR::Instr::New(Js::OpCode::CmNeq_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmLt_ULong:
- instr = IR::Instr::New(Js::OpCode::CmUnLt_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmLe_ULong:
- instr = IR::Instr::New(Js::OpCode::CmUnLe_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGt_ULong:
- instr = IR::Instr::New(Js::OpCode::CmUnGt_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::CmGe_ULong:
- instr = IR::Instr::New(Js::OpCode::CmUnGe_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildLong1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Conv_ITL:
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyInt32);
- break;
- case Js::OpCodeAsmJs::Conv_UTL:
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyUint32);
- break;
- default:
- Assume(UNREACHED);
- }
- srcOpnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt64);
- dstOpnd->SetValueType(ValueType::Float);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Conv_Prim, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildInt1Long1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyInt64);
- src1Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr * instr = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Eqz_Long:
- instr = IR::Instr::New(Js::OpCode::CmEq_I4, dstOpnd, src1Opnd, IR::Int64ConstOpnd::New(0, TyInt64, m_func), m_func);
- break;
- case Js::OpCodeAsmJs::Conv_LTI:
- instr = IR::Instr::New(Js::OpCode::Conv_Prim, dstOpnd, src1Opnd, m_func);
- break;
- default:
- Assume(UNREACHED);
- }
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildLong1Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyFloat32);
- IR::RegOpnd * dstOpnd = nullptr;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Conv_Check_FTL:
- dstOpnd = BuildDstOpnd(dstRegSlot, TyInt64);
- break;
- case Js::OpCodeAsmJs::Conv_Check_FTUL:
- dstOpnd = BuildDstOpnd(dstRegSlot, TyUint64);
- break;
- default:
- Assume(UNREACHED);
- }
- IR::RegOpnd* tmpDst = IR::RegOpnd::New(src1Opnd->GetType(), m_func);
- tmpDst->SetValueType(ValueType::Float);
- AddInstr(IR::Instr::New(Js::OpCode::TrapIfTruncOverflow, tmpDst, src1Opnd, m_func), offset);
- dstOpnd->m_dontDeadStore = true;
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Conv_Prim, dstOpnd, tmpDst, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat1Long1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot)
- {
- IR::RegOpnd * srcOpnd = nullptr;
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat32);
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Conv_LTF:
- srcOpnd = BuildSrcOpnd(src1RegSlot, TyInt64);
- break;
- case Js::OpCodeAsmJs::Conv_ULTF:
- srcOpnd = BuildSrcOpnd(src1RegSlot, TyUint64);
- break;
- default:
- Assume(UNREACHED);
- }
- IR::Instr * instr = IR::Instr::New(Js::OpCode::Conv_Prim, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildLong1Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TyFloat64);
- srcOpnd->SetValueType(ValueType::Float);
- IRType dstType;
- Js::OpCode op;
- bool doTruncTrapCheck = false;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Conv_Check_DTL:
- op = Js::OpCode::Conv_Prim;
- dstType = TyInt64;
- doTruncTrapCheck = true;
- break;
- case Js::OpCodeAsmJs::Conv_Check_DTUL:
- op = Js::OpCode::Conv_Prim;
- dstType = TyUint64;
- doTruncTrapCheck = true;
- break;
- case Js::OpCodeAsmJs::Reinterpret_DTL:
- op = Js::OpCode::Reinterpret_Prim;
- dstType = TyInt64;
- break;
- default:
- Assume(UNREACHED);
- Js::Throw::FatalInternalError();
- }
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, dstType);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- if (doTruncTrapCheck)
- {
- IR::RegOpnd* tmpDst = IR::RegOpnd::New(srcOpnd->GetType(), m_func);
- tmpDst->SetValueType(ValueType::Float);
- AddInstr(IR::Instr::New(Js::OpCode::TrapIfTruncOverflow, tmpDst, srcOpnd, m_func), offset);
- dstOpnd->m_dontDeadStore = true;
- srcOpnd = tmpDst;
- }
- IR::Instr * instr = IR::Instr::New(op, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildDouble1Long1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot)
- {
- IR::RegOpnd * srcOpnd = nullptr;
- Js::OpCode op = Js::OpCode::Conv_Prim;
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat64);
- dstOpnd->SetValueType(ValueType::Float);
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Conv_LTD:
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyInt64);
- break;
- case Js::OpCodeAsmJs::Conv_ULTD:
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyUint64);
- break;
- case Js::OpCodeAsmJs::Reinterpret_LTD:
- srcOpnd = BuildSrcOpnd(srcRegSlot, TyInt64);
- op = Js::OpCode::Reinterpret_Prim;
- break;
- default:
- Assume(UNREACHED);
- }
- srcOpnd->SetValueType(ValueType::GetInt(false));
- IR::Instr* instr = IR::Instr::New(op, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- }
- ///Loop Body Code
- bool
- IRBuilderAsmJs::IsLoopBody() const
- {
- return m_func->IsLoopBody();
- }
- bool
- IRBuilderAsmJs::IsLoopBodyReturnIPInstr(IR::Instr * instr) const
- {
- IR::Opnd * dst = instr->GetDst();
- return (dst && dst->IsRegOpnd() && dst->AsRegOpnd()->m_sym == m_loopBodyRetIPSym);
- }
- bool
- IRBuilderAsmJs::IsLoopBodyOuterOffset(uint offset) const
- {
- if (!IsLoopBody())
- {
- return false;
- }
- return (offset >= m_func->GetWorkItem()->GetLoopHeader()->endOffset || offset < m_func->GetWorkItem()->GetLoopHeader()->startOffset);
- }
- uint
- IRBuilderAsmJs::GetLoopBodyExitInstrOffset() const
- {
- // End of loop body, start of StSlot and Ret instruction at endOffset + 1
- return m_func->GetWorkItem()->GetLoopHeader()->endOffset + 1;
- }
- IR::Instr *
- IRBuilderAsmJs::CreateLoopBodyReturnIPInstr(uint targetOffset, uint offset)
- {
- IR::RegOpnd * retOpnd = IR::RegOpnd::New(m_loopBodyRetIPSym, TyInt32, m_func);
- IR::IntConstOpnd * exitOffsetOpnd = IR::IntConstOpnd::New(targetOffset, TyInt32, m_func);
- return IR::Instr::New(Js::OpCode::Ld_I4, retOpnd, exitOffsetOpnd, m_func);
- }
- IR::Opnd *
- IRBuilderAsmJs::InsertLoopBodyReturnIPInstr(uint targetOffset, uint offset)
- {
- IR::Instr * setRetValueInstr = CreateLoopBodyReturnIPInstr(targetOffset, offset);
- this->AddInstr(setRetValueInstr, offset);
- return setRetValueInstr->GetDst();
- }
- IR::SymOpnd *
- IRBuilderAsmJs::BuildAsmJsLoopBodySlotOpnd(SymID symId, IRType opndType)
- {
- // There is no unsigned locals, make sure we create only signed locals
- opndType = IRType_EnsureSigned(opndType);
- // Get the interpreter frame instance that was passed in.
- StackSym *loopParamSym = m_func->EnsureLoopParamSym();
- // property ID is the offset
- Js::PropertyId propOffSet = CalculatePropertyOffset(symId, opndType);
- // Get the bytecodeRegSlot and Get the offset from m_localSlots
- PropertySym * fieldSym = PropertySym::FindOrCreate(loopParamSym->m_id, propOffSet, (uint32)-1, (uint)-1, PropertyKindLocalSlots, m_func);
- return IR::SymOpnd::New(fieldSym, opndType, m_func);
- }
- void
- IRBuilderAsmJs::EnsureLoopBodyAsmJsLoadSlot(SymID symId, IRType type)
- {
- if (this->m_ldSlots->TestAndSet(symId))
- {
- return;
- }
- IR::SymOpnd * fieldSymOpnd = this->BuildAsmJsLoopBodySlotOpnd(symId, type);
- StackSym * symDst = StackSym::FindOrCreate(symId, (Js::RegSlot)symId, m_func, fieldSymOpnd->GetType());
- IR::RegOpnd * dstOpnd = IR::RegOpnd::New(symDst, symDst->GetType(), m_func);
- IR::Instr * ldSlotInstr = IR::Instr::New(Js::OpCode::LdSlot, dstOpnd, fieldSymOpnd, m_func);
- m_func->m_headInstr->InsertAfter(ldSlotInstr);
- if (m_lastInstr == m_func->m_headInstr)
- {
- m_lastInstr = ldSlotInstr;
- }
- }
- void
- IRBuilderAsmJs::GenerateLoopBodySlotAccesses(uint offset)
- {
- //
- // The interpreter instance is passed as 0th argument to the JITted loop body function.
- // Always load the argument, then use it to generate any necessary store-slots.
- //
- uint16 argument = 0;
- StackSym *symSrc = StackSym::NewParamSlotSym(argument + 1, m_func);
- symSrc->m_offset = (argument + LowererMD::GetFormalParamOffset()) * MachPtr;
- symSrc->m_allocated = true;
- m_func->SetHasImplicitParamLoad();
- IR::SymOpnd *srcOpnd = IR::SymOpnd::New(symSrc, TyMachPtr, m_func);
- StackSym *loopParamSym = m_func->EnsureLoopParamSym();
- IR::RegOpnd *loopParamOpnd = IR::RegOpnd::New(loopParamSym, TyMachPtr, m_func);
- IR::Instr *instrArgIn = IR::Instr::New(Js::OpCode::ArgIn_A, loopParamOpnd, srcOpnd, m_func);
- m_func->m_headInstr->InsertAfter(instrArgIn);
- GenerateLoopBodyStSlots(loopParamSym->m_id, offset);
- }
- void
- IRBuilderAsmJs::GenerateLoopBodyStSlots(SymID loopParamSymId, uint offset)
- {
- if (this->m_stSlots->Count() == 0)
- {
- return;
- }
- FOREACH_BITSET_IN_FIXEDBV(regSlot, this->m_stSlots)
- {
- Assert(!this->RegIsConstant((Js::RegSlot)regSlot));
- IRType type = IRType::TyInt32;
- ValueType valueType = ValueType::GetInt(false);
- if (RegIsIntVar(regSlot))
- {
- type = IRType::TyInt32;
- valueType = ValueType::GetInt(false);
- }
- else if (RegIsFloatVar(regSlot))
- {
- type = IRType::TyFloat32;
- valueType = ValueType::Float;
- }
- else if (RegIsDoubleVar(regSlot))
- {
- type = IRType::TyFloat64;
- valueType = ValueType::Float;
- }
- else if (RegIsInt64Var(regSlot))
- {
- type = IRType::TyInt64;
- valueType = ValueType::GetInt(false);
- }
- else if (RegIsSimd128Var(regSlot))
- {
- type = IRType::TySimd128F4;
- // SIMD regs are non-typed. There is no way to know the incoming SIMD type to a StSlot after a loop body, so we pick any type.
- // However, at this point all src syms are already defined and assigned a type.
- valueType = ValueType::GetObject(ObjectType::UninitializedObject);
- }
- else
- {
- AnalysisAssert(UNREACHED);
- }
- Js::PropertyId propOffSet = CalculatePropertyOffset(regSlot, type);
- IR::RegOpnd* regOpnd = this->BuildSrcOpnd((Js::RegSlot)regSlot, type);
- regOpnd->SetValueType(valueType);
- // Get the bytecodeRegSlot and Get the offset from m_localSlots
- PropertySym * fieldSym = PropertySym::FindOrCreate(loopParamSymId, propOffSet, (uint32)-1, (uint)-1, PropertyKindLocalSlots, m_func);
- IR::SymOpnd * fieldSymOpnd = IR::SymOpnd::New(fieldSym, regOpnd->GetType(), m_func);
- Js::OpCode opcode = Js::OpCode::StSlot;
- IR::Instr * stSlotInstr = IR::Instr::New(opcode, fieldSymOpnd, regOpnd, m_func);
- this->AddInstr(stSlotInstr, offset);
- }
- NEXT_BITSET_IN_FIXEDBV;
- }
- Js::PropertyId IRBuilderAsmJs::CalculatePropertyOffset(SymID id, IRType type, bool isVar)
- {
- // Compute the offset to the start of the interpreter frame's locals array as a Var index.
- size_t localsOffset = 0;
- if (!m_IsTJLoopBody)
- {
- localsOffset = Js::InterpreterStackFrame::GetOffsetOfLocals();
- }
- Assert(localsOffset % sizeof(AsmJsSIMDValue) == 0);
- WAsmJs::Types asmType = WAsmJs::FromIRType(type);
- const auto typedInfo = m_asmFuncInfo->GetTypedSlotInfo(asmType);
- uint32 regSlot = 0;
- if (isVar)
- {
- // Get the bytecodeRegSlot
- regSlot = id - GetFirstVar(asmType) + typedInfo.constCount;
- }
- return (Js::PropertyId)(regSlot * TySize[type] + typedInfo.byteOffset + localsOffset);
- }
- IR::Instr* IRBuilderAsmJs::GenerateStSlotForReturn(IR::RegOpnd* srcOpnd, IRType retType)
- {
- // Compute the offset to the start of the interpreter frame's locals array as a Var index.
- size_t localsOffset = 0;
- if (!m_IsTJLoopBody)
- {
- localsOffset = Js::InterpreterStackFrame::GetOffsetOfLocals();
- }
- Assert(localsOffset % sizeof(AsmJsSIMDValue) == 0);
- StackSym *loopParamSym = m_func->EnsureLoopParamSym();
- Js::PropertyId propOffSet = CalculatePropertyOffset(0, retType, false);
- // Get the bytecodeRegSlot and Get the offset from m_localSlots
- PropertySym * fieldSym = PropertySym::FindOrCreate(loopParamSym->m_id, propOffSet, (uint32)-1, (uint)-1, PropertyKindLocalSlots, m_func);
- IR::SymOpnd * fieldSymOpnd = IR::SymOpnd::New(fieldSym, srcOpnd->GetType(), m_func);
- Js::OpCode opcode = Js::OpCode::StSlot;
- IR::Instr * stSlotInstr = IR::Instr::New(opcode, fieldSymOpnd, srcOpnd, m_func);
- return stSlotInstr;
- }
- Js::OpCode IRBuilderAsmJs::GetSimdOpcode(Js::OpCodeAsmJs asmjsOpcode)
- {
- Js::OpCode opcode = (Js::OpCode) 0;
- Assert(IsSimd128AsmJsOpcode(asmjsOpcode));
- if (asmjsOpcode <= Js::OpCodeAsmJs::Simd128_End)
- {
- opcode = m_simdOpcodesMap[(uint32)((Js::OpCodeAsmJs)asmjsOpcode - Js::OpCodeAsmJs::Simd128_Start)];
- }
- else
- {
- Assert(asmjsOpcode >= Js::OpCodeAsmJs::Simd128_Start_Extend && asmjsOpcode <= Js::OpCodeAsmJs::Simd128_End_Extend);
- opcode = m_simdOpcodesMap[(uint32)((Js::OpCodeAsmJs)asmjsOpcode - Js::OpCodeAsmJs::Simd128_Start_Extend) + (uint32)(Js::OpCodeAsmJs::Simd128_End - Js::OpCodeAsmJs::Simd128_Start) + 1];
- }
- Assert(IsSimd128Opcode(opcode));
- return opcode;
- }
- void IRBuilderAsmJs::GetSimdTypesFromAsmType(Js::AsmJsType::Which asmType, IRType *pIRType, ValueType *pValueType /* = nullptr */)
- {
- IRType irType = IRType::TyVar;
- ValueType vType = ValueType::Uninitialized;
- #define SIMD_TYPE_CHECK(type1, type2, type3) \
- case Js::AsmJsType::Which::##type1: \
- irType = type2; \
- vType = ValueType::GetSimd128(ObjectType::##type3); \
- break;
- switch (asmType)
- {
- SIMD_TYPE_CHECK(Float32x4, TySimd128F4, Simd128Float32x4)
- SIMD_TYPE_CHECK(Int32x4, TySimd128I4, Simd128Int32x4 )
- SIMD_TYPE_CHECK(Int16x8, TySimd128I8, Simd128Int16x8 )
- SIMD_TYPE_CHECK(Int8x16, TySimd128I16, Simd128Int8x16 )
- SIMD_TYPE_CHECK(Uint32x4, TySimd128U4, Simd128Uint32x4 )
- SIMD_TYPE_CHECK(Uint16x8, TySimd128U8, Simd128Uint16x8 )
- SIMD_TYPE_CHECK(Uint8x16, TySimd128U16, Simd128Uint8x16 )
- SIMD_TYPE_CHECK(Bool32x4, TySimd128B4, Simd128Bool32x4 )
- SIMD_TYPE_CHECK(Bool16x8, TySimd128B8, Simd128Bool16x8 )
- SIMD_TYPE_CHECK(Bool8x16, TySimd128B16, Simd128Bool8x16 )
- default:
- Assert(UNREACHED);
- }
- *pIRType = irType;
- if (pValueType)
- {
- *pValueType = vType;
- }
- #undef SIMD_TYPE_CHECK
- }
- // !!NOTE: Always build the src opnds first, before dst. So we record the use of any temps before assigning new symId for the dst temp.
- #define BUILD_SIMD_ARGS_REG2 Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot
- #define BUILD_SIMD_ARGS_REG3 BUILD_SIMD_ARGS_REG2, Js::RegSlot src2RegSlot
- #define BUILD_SIMD_ARGS_REG4 BUILD_SIMD_ARGS_REG3, Js::RegSlot src3RegSlot
- #define BUILD_SIMD_ARGS_REG5 BUILD_SIMD_ARGS_REG4, Js::RegSlot src4RegSlot
- #define BUILD_SIMD_ARGS_REG6 BUILD_SIMD_ARGS_REG5, Js::RegSlot src5RegSlot
- #define BUILD_SIMD_ARGS_REG7 BUILD_SIMD_ARGS_REG6, Js::RegSlot src6RegSlot
- #define BUILD_SIMD_ARGS_REG9 BUILD_SIMD_ARGS_REG7, Js::RegSlot src7RegSlot, Js::RegSlot src8RegSlot
- #define BUILD_SIMD_ARGS_REG10 BUILD_SIMD_ARGS_REG9, Js::RegSlot src9RegSlot
- #define BUILD_SIMD_ARGS_REG11 BUILD_SIMD_ARGS_REG10, Js::RegSlot src10RegSlot
- #define BUILD_SIMD_ARGS_REG17 BUILD_SIMD_ARGS_REG11, Js::RegSlot src11RegSlot, Js::RegSlot src12RegSlot, Js::RegSlot src13RegSlot, Js::RegSlot src14RegSlot, Js::RegSlot src15RegSlot, Js::RegSlot src16RegSlot
- #define BUILD_SIMD_ARGS_REG18 BUILD_SIMD_ARGS_REG17, Js::RegSlot src17RegSlot
- #define BUILD_SIMD_ARGS_REG19 BUILD_SIMD_ARGS_REG18, Js::RegSlot src18RegSlot
- // Float32x4
- void
- IRBuilderAsmJs::BuildFloat32x4_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- BuildSimd_2(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128F4);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_3(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128F4);
- }
- void
- IRBuilderAsmJs::BuildBool32x4_1Float32x4_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128B4, TySimd128F4);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_1Bool32x4_1Float32x4_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B4);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128F4);
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TySimd128F4);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128F4);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool32x4));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- src3Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- // Given bytecode: dst = op s1, s2, s3
- // Generate:
- // t1 = ExtendedArg_A s1
- // t2 = ExtendedArg_A s2, t1
- // t3 = ExtendedArg_A s3, t2
- // dst = op t3
- // Later phases will chain the arguments by following singleDefInstr of each use of ti.
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_Select_F4, "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128F4);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128F4);
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TySimd128F4);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128F4);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- src3Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- // Given bytecode: dst = op s1, s2, s3
- // Generate:
- // t1 = ExtendedArg_A s1
- // t2 = ExtendedArg_A s2, t1
- // t3 = ExtendedArg_A s3, t2
- // dst = op t3
- // Later phases will chain the arguments by following singleDefInstr of each use of ti.
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_Select_I4, "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void IRBuilderAsmJs::BuildFloat32x4_1Float4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG5)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyFloat32);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyFloat32);
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TyFloat32);
- IR::RegOpnd * src4Opnd = BuildSrcOpnd(src4RegSlot, TyFloat32);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128F4);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- src1Opnd->SetValueType(ValueType::Float);
- src2Opnd->SetValueType(ValueType::Float);
- src3Opnd->SetValueType(ValueType::Float);
- src4Opnd->SetValueType(ValueType::Float);
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_FloatsToF4, "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_2Int4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG6)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128F4);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128F4);
- IR::RegOpnd * src2Opnd = BuildIntConstOpnd(src2RegSlot);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = Js::OpCode::Simd128_Swizzle_F4;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_3Int4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG7)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128F4);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128F4);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128F4);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::RegOpnd * src6Opnd = BuildIntConstOpnd(src6RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src6Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = Js::OpCode::Simd128_Shuffle_F4;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_1Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyFloat32);
- src1Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128F4);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Splat_F4);
- Js::OpCode opcode = Js::OpCode::Simd128_Splat_F4;
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_2Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128F4);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyFloat32);
- src1Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128F4);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((uint32)opcode, "Invalid backend SIMD opcode");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- // Disable for now
- #if 0
- void
- IRBuilderAsmJs::BuildFloat32x4_1Float64x2_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128D2);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128F4);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_FromFloat64x2_F4 || opcode == Js::OpCode::Simd128_FromFloat64x2Bits_F4, "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- #endif // 0
- void
- IRBuilderAsmJs::BuildFloat32x4_1Int32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt32x4_F4 || newOpcode == Js::OpCodeAsmJs::Simd128_FromInt32x4Bits_F4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128F4, TySimd128I4);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_1Uint32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint32x4_F4 || newOpcode == Js::OpCodeAsmJs::Simd128_FromUint32x4Bits_F4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128F4, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_1Int16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt16x8Bits_F4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128F4, TySimd128I8);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_1Uint16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint16x8Bits_F4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128F4, TySimd128U8);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_1Int8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt8x16Bits_F4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128F4, TySimd128I16);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_1Uint8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint8x16Bits_F4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128F4, TySimd128U16);
- }
- void IRBuilderAsmJs::BuildReg1Float32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TySimd128F4);
- srcOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- IR::Instr * instr = nullptr;
- IR::Opnd * dstOpnd = nullptr;
- StackSym * symDst = nullptr;
- if (newOpcode == Js::OpCodeAsmJs::Simd128_I_ArgOut_F4)
- {
- symDst = StackSym::NewArgSlotSym((uint16)dstRegSlot, m_func, TySimd128F4);
- symDst->m_allocated = true;
- if ((uint16)(dstRegSlot) != (dstRegSlot))
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- dstOpnd = IR::SymOpnd::New(symDst, TySimd128F4, m_func);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- else
- {
- Assert(UNREACHED);
- }
- }
- /* Int32x4 */
- void
- IRBuilderAsmJs::BuildInt32x4_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- BuildSimd_2(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I4);
- }
- void
- IRBuilderAsmJs::BuildInt32x4_3(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128I4);
- }
- void
- IRBuilderAsmJs::BuildBool32x4_1Int32x4_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128B4, TySimd128I4);
- }
- void
- IRBuilderAsmJs::BuildInt32x4_1Bool32x4_1Int32x4_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B4);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128I4);
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TySimd128I4);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I4);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool32x4));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- src3Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- // Given bytecode: dst = op s1, s2, s3
- // Generate:
- // t1 = ExtendedArg_A s1
- // t2 = ExtendedArg_A s2, t1
- // t3 = ExtendedArg_A s3, t2
- // dst = op t3
- // Later phases will chain the arguments by following singleDefInstr of each use of ti.
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_Select_I4, "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void IRBuilderAsmJs::BuildInt32x4_1Int4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG5)
- {
- uint const LANES = 4;
- Js::RegSlot srcRegSlot[LANES];
- srcRegSlot[0] = src1RegSlot;
- srcRegSlot[1] = src2RegSlot;
- srcRegSlot[2] = src3RegSlot;
- srcRegSlot[3] = src4RegSlot;
- BuildSimd_1Ints(newOpcode, offset, TySimd128I4, srcRegSlot, dstRegSlot, LANES);
- }
- void IRBuilderAsmJs::BuildInt32x4_2Int4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG6)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I4);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128I4);
- IR::RegOpnd * src2Opnd = BuildIntConstOpnd(src2RegSlot);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Swizzle_I4);
- Js::OpCode opcode = Js::OpCode::Simd128_Swizzle_I4;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void IRBuilderAsmJs::BuildInt32x4_3Int4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG7)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I4);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128I4);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128I4);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::RegOpnd * src6Opnd = BuildIntConstOpnd(src6RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src6Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Shuffle_I4);
- Js::OpCode opcode = Js::OpCode::Simd128_Shuffle_I4;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildInt32x4_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Splat_I4);
- BuildSimd_1Int1(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I4);
- }
- void
- IRBuilderAsmJs::BuildInt32x4_2Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_2Int1(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128I4);
- }
- //ReplaceLane
- void
- IRBuilderAsmJs::BuildInt32x4_2Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- AssertMsg((newOpcode == Js::OpCodeAsmJs::Simd128_ReplaceLane_I4), "Unexpected opcode for this format.");
- BuildSimd_2Int2(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, src3RegSlot, TySimd128I4);
- }
- void
- IRBuilderAsmJs::BuildInt1Int32x4_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128I4);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_ExtractLane_I4), "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat32x4_2Int1Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128F4);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TyFloat32);
- src3Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128F4);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- // Given bytecode: dst = op s1, s2, s3
- // Generate:
- // t1 = ExtendedArg_A s1
- // t2 = ExtendedArg_A s2, t1
- // t3 = ExtendedArg_A s3, t2
- // dst = op t3
- IR::Instr* instr = nullptr;
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_ReplaceLane_F4), "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildFloat1Float32x4_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128F4);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyFloat32);
- dstOpnd->SetValueType(ValueType::Float);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_ExtractLane_F4), "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildInt32x4_1Float32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromFloat32x4_I4 || newOpcode == Js::OpCodeAsmJs::Simd128_FromFloat32x4Bits_I4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I4, TySimd128F4);
- }
- void
- IRBuilderAsmJs::BuildInt32x4_1Uint32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint32x4Bits_I4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I4, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildInt32x4_1Int16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt16x8Bits_I4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I4, TySimd128I8);
- }
- void
- IRBuilderAsmJs::BuildInt32x4_1Uint16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint16x8Bits_I4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I4, TySimd128U8);
- }
- void
- IRBuilderAsmJs::BuildInt32x4_1Int8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt8x16Bits_I4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I4, TySimd128I16);
- }
- void
- IRBuilderAsmJs::BuildInt32x4_1Uint8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint8x16Bits_I4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I4, TySimd128U16);
- }
- #if 0
- void
- IRBuilderAsmJs::BuildInt32x4_1Float64x2_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromFloat64x2_I4 || newOpcode == Js::OpCodeAsmJs::Simd128_FromFloat64x2Bits_I4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I4, TySimd128D2);
- }
- #endif //0
- void IRBuilderAsmJs::BuildReg1Int32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TySimd128I4);
- srcOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- IR::Instr * instr = nullptr;
- IR::Opnd * dstOpnd = nullptr;
- StackSym * symDst = nullptr;
- if (newOpcode == Js::OpCodeAsmJs::Simd128_I_ArgOut_I4)
- {
- symDst = StackSym::NewArgSlotSym((uint16)dstRegSlot, m_func, TySimd128I4);
- symDst->m_allocated = true;
- if ((uint16)(dstRegSlot) != (dstRegSlot))
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- dstOpnd = IR::SymOpnd::New(symDst, TySimd128I4, m_func);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- else
- {
- Assert(UNREACHED);
- }
- }
- //Int8x16
- void
- IRBuilderAsmJs::BuildInt8x16_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- BuildSimd_2(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I16);
- }
- //
- void
- IRBuilderAsmJs::BuildInt8x16_3(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128I16);
- }
- void IRBuilderAsmJs::BuildInt8x16_1Int16(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG17)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_IntsToI16, "Unexpected opcode for this format.");
- uint const LANES = 16;
- Js::RegSlot srcRegSlots[LANES] = {
- srcRegSlots[0] = src1RegSlot,
- srcRegSlots[1] = src2RegSlot,
- srcRegSlots[2] = src3RegSlot,
- srcRegSlots[3] = src4RegSlot,
- srcRegSlots[4] = src5RegSlot,
- srcRegSlots[5] = src6RegSlot,
- srcRegSlots[6] = src7RegSlot,
- srcRegSlots[7] = src8RegSlot,
- srcRegSlots[8] = src9RegSlot,
- srcRegSlots[9] = src10RegSlot,
- srcRegSlots[10] = src11RegSlot,
- srcRegSlots[11] = src12RegSlot,
- srcRegSlots[12] = src13RegSlot,
- srcRegSlots[13] = src14RegSlot,
- srcRegSlots[14] = src15RegSlot,
- srcRegSlots[15] = src16RegSlot
- };
- BuildSimd_1Ints(newOpcode, offset, TySimd128I16, srcRegSlots, dstRegSlot, LANES);
- }
- void
- IRBuilderAsmJs::BuildBool8x16_1Int8x16_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128B8, TySimd128I8);
- }
- void
- IRBuilderAsmJs::BuildInt8x16_1Bool8x16_1Int8x16_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B16);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128I16);
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TySimd128I16);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I16);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int8x16));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool8x16));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int8x16));
- src3Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int8x16));
- // Given bytecode: dst = op s1, s2, s3
- // Generate:
- // t1 = ExtendedArg_A s1
- // t2 = ExtendedArg_A s2, t1
- // t3 = ExtendedArg_A s3, t2
- // dst = op t3
- // Later phases will chain the arguments by following singleDefInstr of each use of ti.
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_Select_I16, "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildInt8x16_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Splat_I16);
- BuildSimd_1Int1(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I16);
- }
- //ExtractLane ReplaceLane
- void
- IRBuilderAsmJs::BuildInt8x16_2Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_2Int1(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128I16);
- }
- void
- IRBuilderAsmJs::BuildInt8x16_2Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- AssertMsg((newOpcode == Js::OpCodeAsmJs::Simd128_ReplaceLane_I16), "Unexpected opcode for this format.");
- BuildSimd_2Int2(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, src3RegSlot, TySimd128I16);
- }
- void
- IRBuilderAsmJs::BuildInt1Int8x16_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128I16);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int8x16));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_ExtractLane_I16), "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void IRBuilderAsmJs::BuildInt8x16_3Int16(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG19)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I16);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128I16);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128I16);
- IR::RegOpnd* srcOpnds[16];
- srcOpnds[0] = BuildIntConstOpnd(src3RegSlot);
- srcOpnds[1] = BuildIntConstOpnd(src4RegSlot);
- srcOpnds[2] = BuildIntConstOpnd(src5RegSlot);
- srcOpnds[3] = BuildIntConstOpnd(src6RegSlot);
- srcOpnds[4] = BuildIntConstOpnd(src7RegSlot);
- srcOpnds[5] = BuildIntConstOpnd(src8RegSlot);
- srcOpnds[6] = BuildIntConstOpnd(src9RegSlot);
- srcOpnds[7] = BuildIntConstOpnd(src10RegSlot);
- srcOpnds[8] = BuildIntConstOpnd(src11RegSlot);
- srcOpnds[9] = BuildIntConstOpnd(src12RegSlot);
- srcOpnds[10] = BuildIntConstOpnd(src13RegSlot);
- srcOpnds[11] = BuildIntConstOpnd(src14RegSlot);
- srcOpnds[12] = BuildIntConstOpnd(src15RegSlot);
- srcOpnds[13] = BuildIntConstOpnd(src16RegSlot);
- srcOpnds[14] = BuildIntConstOpnd(src17RegSlot);
- srcOpnds[15] = BuildIntConstOpnd(src18RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int8x16));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int8x16));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int8x16));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- for (int i = 0; i < 16; ++i)
- {
- instr = AddExtendedArg(srcOpnds[i], instr->GetDst()->AsRegOpnd(), offset);
- }
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Shuffle_I16);
- Js::OpCode opcode = Js::OpCode::Simd128_Shuffle_I16;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void IRBuilderAsmJs::BuildInt8x16_2Int16(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG18)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I16);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128I16);
- IR::RegOpnd* srcOpnds[16];
- srcOpnds[0] = BuildIntConstOpnd(src2RegSlot);
- srcOpnds[1] = BuildIntConstOpnd(src3RegSlot);
- srcOpnds[2] = BuildIntConstOpnd(src4RegSlot);
- srcOpnds[3] = BuildIntConstOpnd(src5RegSlot);
- srcOpnds[4] = BuildIntConstOpnd(src6RegSlot);
- srcOpnds[5] = BuildIntConstOpnd(src7RegSlot);
- srcOpnds[6] = BuildIntConstOpnd(src8RegSlot);
- srcOpnds[7] = BuildIntConstOpnd(src9RegSlot);
- srcOpnds[8] = BuildIntConstOpnd(src10RegSlot);
- srcOpnds[9] = BuildIntConstOpnd(src11RegSlot);
- srcOpnds[10] = BuildIntConstOpnd(src12RegSlot);
- srcOpnds[11] = BuildIntConstOpnd(src13RegSlot);
- srcOpnds[12] = BuildIntConstOpnd(src14RegSlot);
- srcOpnds[13] = BuildIntConstOpnd(src15RegSlot);
- srcOpnds[14] = BuildIntConstOpnd(src16RegSlot);
- srcOpnds[15] = BuildIntConstOpnd(src17RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int8x16));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int8x16));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- for (int i = 0; i < 16; ++i)
- {
- instr = AddExtendedArg(srcOpnds[i], instr->GetDst()->AsRegOpnd(), offset);
- }
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Swizzle_I16);
- Js::OpCode opcode = Js::OpCode::Simd128_Swizzle_I16;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildInt8x16_1Float32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromFloat32x4Bits_I16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I16, TySimd128F4);
- }
- void
- IRBuilderAsmJs::BuildInt8x16_1Int32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt32x4Bits_I16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I16, TySimd128I4);
- }
- void
- IRBuilderAsmJs::BuildInt8x16_1Int16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt16x8Bits_I16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I16, TySimd128I8);
- }
- void
- IRBuilderAsmJs::BuildInt8x16_1Uint32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint32x4Bits_I16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I16, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildInt8x16_1Uint16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint16x8Bits_I16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I16, TySimd128U8);
- }
- void
- IRBuilderAsmJs::BuildInt8x16_1Uint8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint8x16Bits_I16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I16, TySimd128U16);
- }
- void IRBuilderAsmJs::BuildReg1Int8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TySimd128I16);
- srcOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int8x16));
- IR::Instr * instr = nullptr;
- IR::Opnd * dstOpnd = nullptr;
- StackSym * symDst = nullptr;
- if (newOpcode == Js::OpCodeAsmJs::Simd128_I_ArgOut_I16)
- {
- symDst = StackSym::NewArgSlotSym((uint16)dstRegSlot, m_func, TySimd128I16);
- symDst->m_allocated = true;
- if (symDst == NULL || (uint16)(dstRegSlot) != (dstRegSlot))
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- dstOpnd = IR::SymOpnd::New(symDst, TySimd128I16, m_func);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int8x16));
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- else
- {
- Assert(UNREACHED);
- }
- }
- /* Float64x2 */
- // Disabled for now
- #if 0
- void
- IRBuilderAsmJs::BuildFloat64x2_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128D2);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- Js::OpCode opcode;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Simd128_Return_D2:
- if (m_func->IsLoopBody())
- {
- IR::Instr* slotInstr = GenerateStSlotForReturn(src1Opnd, IRType::TySimd128D2);
- AddInstr(slotInstr, offset);
- }
- opcode = Js::OpCode::Ld_A;
- break;
- case Js::OpCodeAsmJs::Simd128_I_Conv_VTD2:
- case Js::OpCodeAsmJs::Simd128_Ld_D2:
- opcode = Js::OpCode::Ld_A;
- break;
- default:
- opcode = GetSimdOpcode(newOpcode);
- }
- AssertMsg((uint32)opcode, "Invalid backend SIMD opcode");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat64x2_3(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128D2);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128D2);
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- Js::OpCode opcode;
- opcode = GetSimdOpcode(newOpcode);
- AssertMsg((uint32)opcode, "Invalid backend SIMD opcode");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat64x2_4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128D2);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128D2);
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TySimd128D2);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- src3Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- // Given bytecode: dst = op s1, s2, s3
- // Generate:
- // t1 = ExtendedArg_A s1
- // t2 = ExtendedArg_A s2, t1
- // t3 = ExtendedArg_A s3, t2
- // dst = op t3
- // Later phases will chain the arguments by following singleDefInstr of each use of ti.
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_Clamp_D2, "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void IRBuilderAsmJs::BuildFloat64x2_1Double2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyFloat64);
- src1Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyFloat64);
- src2Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_DoublesToD2, "Invalid backend SIMD opcode");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void IRBuilderAsmJs::BuildFloat64x2_1Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyFloat64);
- src1Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_Splat_D2, "Invalid backend SIMD opcode");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat64x2_2Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128D2);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyFloat64);
- src1Opnd->SetValueType(ValueType::Float);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((uint32)opcode, "Invalid backend SIMD opcode");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat64x2_2Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128D2);
- IR::RegOpnd * src2Opnd = BuildIntConstOpnd(src2RegSlot);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Swizzle_D2);
- Js::OpCode opcode = Js::OpCode::Simd128_Swizzle_D2;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildFloat64x2_3Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG5)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128D2);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128D2);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Shuffle_D2);
- Js::OpCode opcode = Js::OpCode::Simd128_Shuffle_D2;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildFloat64x2_1Float32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128F4);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float32x4));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_FromFloat32x4_D2 || opcode == Js::OpCode::Simd128_FromFloat32x4Bits_D2, "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat64x2_1Int32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128I4);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_FromInt32x4_D2 || opcode == Js::OpCode::Simd128_FromInt32x4Bits_D2, "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildFloat64x2_1Int32x4_1Float64x2_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128I4);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128D2);
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TySimd128D2);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128D2);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int32x4));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- src3Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_Select_D2, "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void IRBuilderAsmJs::BuildReg1Float64x2_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TySimd128D2);
- srcOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- IR::Instr * instr = nullptr;
- IR::Opnd * dstOpnd = nullptr;
- StackSym * symDst = nullptr;
- if (newOpcode == Js::OpCodeAsmJs::Simd128_I_ArgOut_D2)
- {
- symDst = StackSym::NewArgSlotSym((uint16)dstRegSlot, m_func, TySimd128D2);
- symDst->m_allocated = true;
- if ((uint16)(dstRegSlot) != (dstRegSlot))
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- dstOpnd = IR::SymOpnd::New(symDst, TySimd128D2, m_func);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Float64x2));
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- else
- {
- Assert(UNREACHED);
- }
- }
- #endif // 0
- /* Int16x8 */
- void IRBuilderAsmJs::BuildInt16x8_1Int8(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG9)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_IntsToI8, "Unexpected opcode for this format.");
- uint const LANES = 8;
- Js::RegSlot srcRegSlots[LANES];
- srcRegSlots[0] = src1RegSlot;
- srcRegSlots[1] = src2RegSlot;
- srcRegSlots[2] = src3RegSlot;
- srcRegSlots[3] = src4RegSlot;
- srcRegSlots[4] = src5RegSlot;
- srcRegSlots[5] = src6RegSlot;
- srcRegSlots[6] = src7RegSlot;
- srcRegSlots[7] = src8RegSlot;
- BuildSimd_1Ints(newOpcode, offset, TySimd128I8, srcRegSlots, dstRegSlot, LANES);
- }
- void IRBuilderAsmJs::BuildReg1Int16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TySimd128I8);
- srcOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int16x8));
- IR::Instr * instr = nullptr;
- IR::Opnd * dstOpnd = nullptr;
- StackSym * symDst = nullptr;
- if (newOpcode == Js::OpCodeAsmJs::Simd128_I_ArgOut_I8)
- {
- symDst = StackSym::NewArgSlotSym((uint16)dstRegSlot, m_func, TySimd128I8);
- symDst->m_allocated = true;
- if (symDst == nullptr || (uint16)(dstRegSlot) != (dstRegSlot))
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- dstOpnd = IR::SymOpnd::New(symDst, TySimd128I8, m_func);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int16x8));
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- else
- {
- Assert(UNREACHED);
- }
- }
- void
- IRBuilderAsmJs::BuildInt1Int16x8_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128I8);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int16x8));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_ExtractLane_I8), "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void IRBuilderAsmJs::BuildInt16x8_2Int8(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG10)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I8);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128I8);
- IR::RegOpnd * src2Opnd = BuildIntConstOpnd(src2RegSlot);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::RegOpnd * src6Opnd = BuildIntConstOpnd(src6RegSlot);
- IR::RegOpnd * src7Opnd = BuildIntConstOpnd(src7RegSlot);
- IR::RegOpnd * src8Opnd = BuildIntConstOpnd(src8RegSlot);
- IR::RegOpnd * src9Opnd = BuildIntConstOpnd(src9RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int16x8));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int16x8));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src6Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src7Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src8Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src9Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Swizzle_I8);
- Js::OpCode opcode = Js::OpCode::Simd128_Swizzle_I8;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void IRBuilderAsmJs::BuildInt16x8_3Int8(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG11)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I8);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128I8);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128I8);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::RegOpnd * src6Opnd = BuildIntConstOpnd(src6RegSlot);
- IR::RegOpnd * src7Opnd = BuildIntConstOpnd(src7RegSlot);
- IR::RegOpnd * src8Opnd = BuildIntConstOpnd(src8RegSlot);
- IR::RegOpnd * src9Opnd = BuildIntConstOpnd(src9RegSlot);
- IR::RegOpnd * src10Opnd = BuildIntConstOpnd(src10RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int16x8));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int16x8));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int16x8));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src6Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src7Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src8Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src9Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src10Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Shuffle_I8);
- Js::OpCode opcode = Js::OpCode::Simd128_Shuffle_U8;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Splat_I8);
- BuildSimd_1Int1(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I8);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_2Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- AssertMsg((newOpcode == Js::OpCodeAsmJs::Simd128_ReplaceLane_I8), "Unexpected opcode for this format.");
- BuildSimd_2Int2(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, src3RegSlot, TySimd128I8);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- BuildSimd_2(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I8);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_3(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128I8);
- }
- void
- IRBuilderAsmJs::BuildBool16x8_1Int16x8_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128B8, TySimd128I8);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_1Bool16x8_1Int16x8_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B8);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128I8);
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TySimd128I8);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128I8);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int16x8));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool16x8));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int16x8));
- src3Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Int16x8));
- // Given bytecode: dst = op s1, s2, s3
- // Generate:
- // t1 = ExtendedArg_A s1
- // t2 = ExtendedArg_A s2, t1
- // t3 = ExtendedArg_A s3, t2
- // dst = op t3
- // Later phases will chain the arguments by following singleDefInstr of each use of ti.
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_Select_I8, "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_2Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_2Int1(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128I8);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_1Float32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromFloat32x4Bits_I8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I8, TySimd128F4);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_1Int32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt32x4Bits_I8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I8, TySimd128I4);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_1Int8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt8x16Bits_I8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I8, TySimd128I16);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_1Uint32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint32x4Bits_I8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I8, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_1Uint16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint16x8Bits_I8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I8, TySimd128U8);
- }
- void
- IRBuilderAsmJs::BuildInt16x8_1Uint8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint8x16Bits_I8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128I8, TySimd128U16);
- }
- /* Uint32x4 */
- void IRBuilderAsmJs::BuildUint32x4_1Int4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG5)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_IntsToU4, "Unexpected opcode for this format.");
- uint const LANES = 4;
- Js::RegSlot srcRegSlot[LANES];
- srcRegSlot[0] = src1RegSlot;
- srcRegSlot[1] = src2RegSlot;
- srcRegSlot[2] = src3RegSlot;
- srcRegSlot[3] = src4RegSlot;
- BuildSimd_1Ints(newOpcode, offset, TySimd128U4, srcRegSlot, dstRegSlot, LANES);
- }
- void IRBuilderAsmJs::BuildReg1Uint32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TySimd128U4);
- srcOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint32x4));
- IR::Instr * instr = nullptr;
- IR::Opnd * dstOpnd = nullptr;
- StackSym * symDst = nullptr;
- if (newOpcode == Js::OpCodeAsmJs::Simd128_I_ArgOut_U4)
- {
- symDst = StackSym::NewArgSlotSym((uint16)dstRegSlot, m_func, TySimd128U4);
- symDst->m_allocated = true;
- if (symDst == nullptr || (uint16)(dstRegSlot) != (dstRegSlot))
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- dstOpnd = IR::SymOpnd::New(symDst, TySimd128U4, m_func);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint32x4));
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- else
- {
- Assert(UNREACHED);
- }
- }
- void
- IRBuilderAsmJs::BuildInt1Uint32x4_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128U4);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint32x4));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_ExtractLane_U4), "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void IRBuilderAsmJs::BuildUint32x4_2Int4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG6)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U4);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128U4);
- IR::RegOpnd * src2Opnd = BuildIntConstOpnd(src2RegSlot);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint32x4));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint32x4));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Swizzle_U4);
- Js::OpCode opcode = Js::OpCode::Simd128_Swizzle_U4;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void IRBuilderAsmJs::BuildUint32x4_3Int4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG7)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U4);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128U4);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128U4);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::RegOpnd * src6Opnd = BuildIntConstOpnd(src6RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint32x4));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint32x4));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint32x4));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src6Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Shuffle_U4);
- Js::OpCode opcode = Js::OpCode::Simd128_Shuffle_U4;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildUint32x4_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Splat_U4);
- BuildSimd_1Int1(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildUint32x4_2Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- AssertMsg((newOpcode == Js::OpCodeAsmJs::Simd128_ReplaceLane_U4), "Unexpected opcode for this format.");
- BuildSimd_2Int2(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, src3RegSlot, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildUint32x4_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- BuildSimd_2(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildUint32x4_3(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildBool32x4_1Uint32x4_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128B4, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildUint32x4_1Bool32x4_1Uint32x4_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B4);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128U4);
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TySimd128U4);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U4);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint32x4));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool32x4));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint32x4));
- src3Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint32x4));
- // Given bytecode: dst = op s1, s2, s3
- // Generate:
- // t1 = ExtendedArg_A s1
- // t2 = ExtendedArg_A s2, t1
- // t3 = ExtendedArg_A s3, t2
- // dst = op t3
- // Later phases will chain the arguments by following singleDefInstr of each use of ti.
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_Select_U4, "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildUint32x4_2Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_2Int1(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildUint32x4_1Float32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromFloat32x4_U4 || newOpcode == Js::OpCodeAsmJs::Simd128_FromFloat32x4Bits_U4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U4, TySimd128F4);
- }
- void
- IRBuilderAsmJs::BuildUint32x4_1Int32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt32x4Bits_U4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U4, TySimd128I4);
- }
- void
- IRBuilderAsmJs::BuildUint32x4_1Int16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {;
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt16x8Bits_U4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U4, TySimd128I8);
- }
- /* Enable with Int8x16 support*/
- void
- IRBuilderAsmJs::BuildUint32x4_1Int8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt8x16Bits_U4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U4, TySimd128I16);
- }
- void
- IRBuilderAsmJs::BuildUint32x4_1Uint16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint16x8Bits_U4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U4, TySimd128U8);
- }
- void
- IRBuilderAsmJs::BuildUint32x4_1Uint8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint8x16Bits_U4, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U4, TySimd128U16);
- }
- /* Uint16x8 */
- void IRBuilderAsmJs::BuildUint16x8_1Int8(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG9)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_IntsToU8, "Unexpected opcode for this format.");
- uint const LANES = 8;
- Js::RegSlot srcRegSlots[LANES];
- srcRegSlots[0] = src1RegSlot;
- srcRegSlots[1] = src2RegSlot;
- srcRegSlots[2] = src3RegSlot;
- srcRegSlots[3] = src4RegSlot;
- srcRegSlots[4] = src5RegSlot;
- srcRegSlots[5] = src6RegSlot;
- srcRegSlots[6] = src7RegSlot;
- srcRegSlots[7] = src8RegSlot;
- BuildSimd_1Ints(newOpcode, offset, TySimd128U8, srcRegSlots, dstRegSlot, LANES);
- }
- void IRBuilderAsmJs::BuildReg1Uint16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TySimd128U8);
- srcOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- IR::Instr * instr = nullptr;
- IR::Opnd * dstOpnd = nullptr;
- StackSym * symDst = nullptr;
- if (newOpcode == Js::OpCodeAsmJs::Simd128_I_ArgOut_U8)
- {
- symDst = StackSym::NewArgSlotSym((uint16)dstRegSlot, m_func, TySimd128U8);
- symDst->m_allocated = true;
- if (symDst == nullptr || (uint16)(dstRegSlot) != (dstRegSlot))
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- dstOpnd = IR::SymOpnd::New(symDst, TySimd128U4, m_func);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- else
- {
- Assert(UNREACHED);
- }
- }
- void
- IRBuilderAsmJs::BuildInt1Uint16x8_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128U8);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_ExtractLane_U8), "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void IRBuilderAsmJs::BuildUint16x8_2Int8(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG10)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U8);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128U8);
- IR::RegOpnd * src2Opnd = BuildIntConstOpnd(src2RegSlot);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::RegOpnd * src6Opnd = BuildIntConstOpnd(src6RegSlot);
- IR::RegOpnd * src7Opnd = BuildIntConstOpnd(src7RegSlot);
- IR::RegOpnd * src8Opnd = BuildIntConstOpnd(src8RegSlot);
- IR::RegOpnd * src9Opnd = BuildIntConstOpnd(src9RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src6Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src7Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src8Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src9Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Swizzle_U8);
- Js::OpCode opcode = Js::OpCode::Simd128_Swizzle_U8;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void IRBuilderAsmJs::BuildUint16x8_3Int8(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG11)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U8);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128U8);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128U8);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::RegOpnd * src6Opnd = BuildIntConstOpnd(src6RegSlot);
- IR::RegOpnd * src7Opnd = BuildIntConstOpnd(src7RegSlot);
- IR::RegOpnd * src8Opnd = BuildIntConstOpnd(src8RegSlot);
- IR::RegOpnd * src9Opnd = BuildIntConstOpnd(src9RegSlot);
- IR::RegOpnd * src10Opnd = BuildIntConstOpnd(src10RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src6Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src7Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src8Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src9Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src10Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Shuffle_U8);
- Js::OpCode opcode = Js::OpCode::Simd128_Shuffle_U8;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Splat_U8);
- BuildSimd_1Int1(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U8);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_2Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- AssertMsg((newOpcode == Js::OpCodeAsmJs::Simd128_ReplaceLane_U8), "Unexpected opcode for this format.");
- BuildSimd_2Int2(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, src3RegSlot, TySimd128U8);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- BuildSimd_2(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U8);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_3(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128U8);
- }
- void
- IRBuilderAsmJs::BuildBool16x8_1Uint16x8_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128B8, TySimd128U8);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_1Bool16x8_1Uint16x8_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B8);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128U8);
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TySimd128U8);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U8);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool16x8));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- src3Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- // Given bytecode: dst = op s1, s2, s3
- // Generate:
- // t1 = ExtendedArg_A s1
- // t2 = ExtendedArg_A s2, t1
- // t3 = ExtendedArg_A s3, t2
- // dst = op t3
- // Later phases will chain the arguments by following singleDefInstr of each use of ti.
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_Select_U8, "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_2Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_2Int1(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128U8);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_1Float32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromFloat32x4Bits_U8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U8, TySimd128F4);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_1Int32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt32x4Bits_U8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U8, TySimd128I4);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_1Int16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt16x8Bits_U8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U8, TySimd128I8);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_1Int8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt8x16Bits_U8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U8, TySimd128I16);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_1Uint32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint32x4Bits_U8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U8, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildUint16x8_1Uint8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint8x16Bits_U8, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U8, TySimd128U16);
- }
- /* Uint8x16 */
- void IRBuilderAsmJs::BuildUint8x16_1Int16(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG17)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_IntsToU16, "Unexpected opcode for this format.");
- uint const LANES = 16;
- Js::RegSlot srcRegSlots[LANES];
- srcRegSlots[0] = src1RegSlot;
- srcRegSlots[1] = src2RegSlot;
- srcRegSlots[2] = src3RegSlot;
- srcRegSlots[3] = src4RegSlot;
- srcRegSlots[4] = src5RegSlot;
- srcRegSlots[5] = src6RegSlot;
- srcRegSlots[6] = src7RegSlot;
- srcRegSlots[7] = src8RegSlot;
- srcRegSlots[8] = src9RegSlot;
- srcRegSlots[9] = src10RegSlot;
- srcRegSlots[10] = src11RegSlot;
- srcRegSlots[11] = src12RegSlot;
- srcRegSlots[12] = src13RegSlot;
- srcRegSlots[13] = src14RegSlot;
- srcRegSlots[14] = src15RegSlot;
- srcRegSlots[15] = src16RegSlot;
- BuildSimd_1Ints(newOpcode, offset, TySimd128U16, srcRegSlots, dstRegSlot, LANES);
- }
- void IRBuilderAsmJs::BuildReg1Uint8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TySimd128U16);
- srcOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
- IR::Instr * instr = nullptr;
- IR::Opnd * dstOpnd = nullptr;
- StackSym * symDst = nullptr;
- if (newOpcode == Js::OpCodeAsmJs::Simd128_I_ArgOut_U16)
- {
- symDst = StackSym::NewArgSlotSym((uint16)dstRegSlot, m_func, TySimd128U16);
- symDst->m_allocated = true;
- if (symDst == nullptr || (uint16)(dstRegSlot) != (dstRegSlot))
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- dstOpnd = IR::SymOpnd::New(symDst, TySimd128U16, m_func);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint16x8));
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- else
- {
- Assert(UNREACHED);
- }
- }
- void
- IRBuilderAsmJs::BuildUint8x16_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- BuildSimd_2(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U16);
- }
- void
- IRBuilderAsmJs::BuildInt1Uint8x16_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128U16);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_ExtractLane_U16), "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void IRBuilderAsmJs::BuildUint8x16_2Int16(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG18)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U16);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128U16);
- IR::RegOpnd * src2Opnd = BuildIntConstOpnd(src2RegSlot);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::RegOpnd * src6Opnd = BuildIntConstOpnd(src6RegSlot);
- IR::RegOpnd * src7Opnd = BuildIntConstOpnd(src7RegSlot);
- IR::RegOpnd * src8Opnd = BuildIntConstOpnd(src8RegSlot);
- IR::RegOpnd * src9Opnd = BuildIntConstOpnd(src9RegSlot);
- IR::RegOpnd * src10Opnd = BuildIntConstOpnd(src10RegSlot);
- IR::RegOpnd * src11Opnd = BuildIntConstOpnd(src11RegSlot);
- IR::RegOpnd * src12Opnd = BuildIntConstOpnd(src12RegSlot);
- IR::RegOpnd * src13Opnd = BuildIntConstOpnd(src13RegSlot);
- IR::RegOpnd * src14Opnd = BuildIntConstOpnd(src14RegSlot);
- IR::RegOpnd * src15Opnd = BuildIntConstOpnd(src15RegSlot);
- IR::RegOpnd * src16Opnd = BuildIntConstOpnd(src16RegSlot);
- IR::RegOpnd * src17Opnd = BuildIntConstOpnd(src17RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src6Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src7Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src8Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src9Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src10Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src11Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src12Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src13Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src14Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src15Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src16Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src17Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Swizzle_U16);
- Js::OpCode opcode = Js::OpCode::Simd128_Swizzle_U16;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void IRBuilderAsmJs::BuildUint8x16_3Int16(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG19)
- {
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U16);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128U16);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128U16);
- IR::RegOpnd * src3Opnd = BuildIntConstOpnd(src3RegSlot);
- IR::RegOpnd * src4Opnd = BuildIntConstOpnd(src4RegSlot);
- IR::RegOpnd * src5Opnd = BuildIntConstOpnd(src5RegSlot);
- IR::RegOpnd * src6Opnd = BuildIntConstOpnd(src6RegSlot);
- IR::RegOpnd * src7Opnd = BuildIntConstOpnd(src7RegSlot);
- IR::RegOpnd * src8Opnd = BuildIntConstOpnd(src8RegSlot);
- IR::RegOpnd * src9Opnd = BuildIntConstOpnd(src9RegSlot);
- IR::RegOpnd * src10Opnd = BuildIntConstOpnd(src10RegSlot);
- IR::RegOpnd * src11Opnd = BuildIntConstOpnd(src11RegSlot);
- IR::RegOpnd * src12Opnd = BuildIntConstOpnd(src12RegSlot);
- IR::RegOpnd * src13Opnd = BuildIntConstOpnd(src13RegSlot);
- IR::RegOpnd * src14Opnd = BuildIntConstOpnd(src14RegSlot);
- IR::RegOpnd * src15Opnd = BuildIntConstOpnd(src15RegSlot);
- IR::RegOpnd * src16Opnd = BuildIntConstOpnd(src16RegSlot);
- IR::RegOpnd * src17Opnd = BuildIntConstOpnd(src17RegSlot);
- IR::RegOpnd * src18Opnd = BuildIntConstOpnd(src18RegSlot);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src6Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src7Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src8Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src9Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src10Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src11Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src12Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src13Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src14Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src15Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src16Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src17Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src18Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Shuffle_U16);
- Js::OpCode opcode = Js::OpCode::Simd128_Shuffle_U16;
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildUint8x16_2Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- AssertMsg((newOpcode == Js::OpCodeAsmJs::Simd128_ReplaceLane_U16), "Unexpected opcode for this format.");
- BuildSimd_2Int2(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, src3RegSlot, TySimd128U16);
- }
- void
- IRBuilderAsmJs::BuildUint8x16_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Splat_U16);
- BuildSimd_1Int1(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U16);
- }
- void
- IRBuilderAsmJs::BuildUint8x16_3(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128U16);
- }
- void
- IRBuilderAsmJs::BuildBool8x16_1Uint8x16_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128B16, TySimd128U16);
- }
- void
- IRBuilderAsmJs::BuildUint8x16_1Bool8x16_1Uint8x16_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B16);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TySimd128U16);
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TySimd128U16);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TySimd128U16);
- IR::Instr * instr = nullptr;
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool8x16));
- src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
- src3Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
- // Given bytecode: dst = op s1, s2, s3
- // Generate:
- // t1 = ExtendedArg_A s1
- // t2 = ExtendedArg_A s2, t1
- // t3 = ExtendedArg_A s3, t2
- // dst = op t3
- // Later phases will chain the arguments by following singleDefInstr of each use of ti.
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg(opcode == Js::OpCode::Simd128_Select_U16, "Unexpected opcode for this format.");
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void
- IRBuilderAsmJs::BuildUint8x16_2Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_2Int1(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128U16);
- }
- void
- IRBuilderAsmJs::BuildUint8x16_1Float32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromFloat32x4Bits_U16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U16, TySimd128F4);
- }
- void
- IRBuilderAsmJs::BuildUint8x16_1Int32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt32x4Bits_U16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U16, TySimd128I4);
- }
- void
- IRBuilderAsmJs::BuildUint8x16_1Int16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt16x8Bits_U16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U16, TySimd128I8);
- }
- /* Enable with Int8x16 support */
- void
- IRBuilderAsmJs::BuildUint8x16_1Int8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromInt8x16Bits_U16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U16, TySimd128I16);
- }
- void
- IRBuilderAsmJs::BuildUint8x16_1Uint32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint32x4Bits_U16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U16, TySimd128U4);
- }
- void
- IRBuilderAsmJs::BuildUint8x16_1Uint16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_FromUint16x8Bits_U16, "Unexpected opcode for this format.");
- BuildSimdConversion(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128U16, TySimd128U8);
- }
- //Bool32x4
- void IRBuilderAsmJs::BuildBool32x4_1Int4(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG5)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_IntsToB4, "Unexpected opcode for this format.");
- uint const LANES = 4;
- Js::RegSlot srcRegSlot[LANES];
- srcRegSlot[0] = src1RegSlot;
- srcRegSlot[1] = src2RegSlot;
- srcRegSlot[2] = src3RegSlot;
- srcRegSlot[3] = src4RegSlot;
- BuildSimd_1Ints(newOpcode, offset, TySimd128B4, srcRegSlot, dstRegSlot, LANES);
- }
- void
- IRBuilderAsmJs::BuildInt1Bool32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B4);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool32x4));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_AllTrue_B4 || opcode == Js::OpCode::Simd128_AnyTrue_B4),
- "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildBool32x4_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- BuildSimd_2(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128B4);
- }
- void
- IRBuilderAsmJs::BuildBool32x4_3(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128B4);
- }
- void IRBuilderAsmJs::BuildReg1Bool32x4_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TySimd128B4);
- srcOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool32x4));
- IR::Instr * instr = nullptr;
- IR::Opnd * dstOpnd = nullptr;
- StackSym * symDst = nullptr;
- if (newOpcode == Js::OpCodeAsmJs::Simd128_I_ArgOut_B4)
- {
- symDst = StackSym::NewArgSlotSym((uint16)dstRegSlot, m_func, TySimd128B4);
- symDst->m_allocated = true;
- if ((uint16)(dstRegSlot) != (dstRegSlot))
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- dstOpnd = IR::SymOpnd::New(symDst, TySimd128B4, m_func);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool32x4));
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- else
- {
- Assert(UNREACHED);
- }
- }
- //Bool16x8
- void IRBuilderAsmJs::BuildBool16x8_1Int8(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG9)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_IntsToB8, "Unexpected opcode for this format.");
- uint const LANES = 8;
- Js::RegSlot srcRegSlots[LANES];
- srcRegSlots[0] = src1RegSlot;
- srcRegSlots[1] = src2RegSlot;
- srcRegSlots[2] = src3RegSlot;
- srcRegSlots[3] = src4RegSlot;
- srcRegSlots[4] = src5RegSlot;
- srcRegSlots[5] = src6RegSlot;
- srcRegSlots[6] = src7RegSlot;
- srcRegSlots[7] = src8RegSlot;
- BuildSimd_1Ints(newOpcode, offset, TySimd128B8, srcRegSlots, dstRegSlot, LANES);
- }
- void
- IRBuilderAsmJs::BuildInt1Bool16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B8);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool16x8));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_AllTrue_B8 || opcode == Js::OpCode::Simd128_AnyTrue_B8),
- "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildBool16x8_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- BuildSimd_2(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128B8);
- }
- void
- IRBuilderAsmJs::BuildBool16x8_3(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128B8);
- }
- void
- IRBuilderAsmJs::BuildReg1Bool16x8_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TySimd128B8);
- srcOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool16x8));
- IR::Instr * instr = nullptr;
- IR::Opnd * dstOpnd = nullptr;
- StackSym * symDst = nullptr;
- if (newOpcode == Js::OpCodeAsmJs::Simd128_I_ArgOut_B8)
- {
- symDst = StackSym::NewArgSlotSym((uint16)dstRegSlot, m_func, TySimd128B8);
- symDst->m_allocated = true;
- if ((uint16)(dstRegSlot) != (dstRegSlot))
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- dstOpnd = IR::SymOpnd::New(symDst, TySimd128B8, m_func);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool16x8));
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- else
- {
- Assert(UNREACHED);
- }
- }
- //Bool8x16
- void IRBuilderAsmJs::BuildBool8x16_1Int16(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG17)
- {
- AssertMsg(newOpcode == Js::OpCodeAsmJs::Simd128_IntsToB16, "Unexpected opcode for this format.");
- uint const LANES = 16;
- Js::RegSlot srcRegSlots[LANES];
- srcRegSlots[0] = src1RegSlot;
- srcRegSlots[1] = src2RegSlot;
- srcRegSlots[2] = src3RegSlot;
- srcRegSlots[3] = src4RegSlot;
- srcRegSlots[4] = src5RegSlot;
- srcRegSlots[5] = src6RegSlot;
- srcRegSlots[6] = src7RegSlot;
- srcRegSlots[7] = src8RegSlot;
- srcRegSlots[8] = src9RegSlot;
- srcRegSlots[9] = src10RegSlot;
- srcRegSlots[10] = src11RegSlot;
- srcRegSlots[11] = src12RegSlot;
- srcRegSlots[12] = src13RegSlot;
- srcRegSlots[13] = src14RegSlot;
- srcRegSlots[14] = src15RegSlot;
- srcRegSlots[15] = src16RegSlot;
- BuildSimd_1Ints(newOpcode, offset, TySimd128B16, srcRegSlots, dstRegSlot, LANES);
- }
- void
- IRBuilderAsmJs::BuildInt1Bool8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B16);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool8x16));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_AllTrue_B16 || opcode == Js::OpCode::Simd128_AnyTrue_B16),
- "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildBool8x16_2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- BuildSimd_2(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128B16);
- }
- void
- IRBuilderAsmJs::BuildBool8x16_3(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, TySimd128B16);
- }
- void IRBuilderAsmJs::BuildReg1Bool8x16_1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TySimd128B16);
- srcOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool8x16));
- IR::Instr * instr = nullptr;
- IR::Opnd * dstOpnd = nullptr;
- StackSym * symDst = nullptr;
- if (newOpcode == Js::OpCodeAsmJs::Simd128_I_ArgOut_B16)
- {
- symDst = StackSym::NewArgSlotSym((uint16)dstRegSlot, m_func, TySimd128B16);
- symDst->m_allocated = true;
- if ((uint16)(dstRegSlot) != (dstRegSlot))
- {
- AssertMsg(UNREACHED, "Arg count too big...");
- Fatal();
- }
- dstOpnd = IR::SymOpnd::New(symDst, TySimd128B16, m_func);
- dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool8x16));
- instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, offset);
- m_argStack->Push(instr);
- }
- else
- {
- Assert(UNREACHED);
- }
- }
- //Bool extractLane/ReplaceLane
- void
- IRBuilderAsmJs::BuildBool32x4_2Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- AssertMsg((newOpcode == Js::OpCodeAsmJs::Simd128_ReplaceLane_B4), "Unexpected opcode for this format.");
- BuildSimd_2Int2(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, src3RegSlot, TySimd128B4);
- }
- void
- IRBuilderAsmJs::BuildBool16x8_2Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- AssertMsg((newOpcode == Js::OpCodeAsmJs::Simd128_ReplaceLane_B8), "Unexpected opcode for this format.");
- BuildSimd_2Int2(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, src3RegSlot, TySimd128B8);
- }
- void
- IRBuilderAsmJs::BuildBool8x16_2Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG4)
- {
- AssertMsg((newOpcode == Js::OpCodeAsmJs::Simd128_ReplaceLane_B16), "Unexpected opcode for this format.");
- BuildSimd_2Int2(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, src3RegSlot, TySimd128B16);
- }
- void
- IRBuilderAsmJs::BuildInt1Bool32x4_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B4);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool32x4));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_ExtractLane_B4), "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildInt1Bool16x8_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B8);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool16x8));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_ExtractLane_B8), "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void
- IRBuilderAsmJs::BuildInt1Bool8x16_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG3)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TySimd128B16);
- src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Bool8x16));
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
- dstOpnd->SetValueType(ValueType::GetInt(false));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((opcode == Js::OpCode::Simd128_ExtractLane_B16), "Unexpected opcode for this format.");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void IRBuilderAsmJs::BuildSimd_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, IRType simdType)
- {
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyInt32);
- src1Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, simdType);
- dstOpnd->SetValueType(GetSimdValueTypeFromIRType(simdType));
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- void IRBuilderAsmJs::BuildSimd_2Int2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot, Js::RegSlot src3RegSlot, IRType simdType)
- {
- ValueType valueType = GetSimdValueTypeFromIRType(simdType);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, simdType);
- src1Opnd->SetValueType(valueType);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * src3Opnd = BuildSrcOpnd(src3RegSlot, TyInt32);
- src3Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, simdType);
- dstOpnd->SetValueType(valueType);
- // Given bytecode: dst = op s1, s2, s3
- // Generate:
- // t1 = ExtendedArg_A s1
- // t2 = ExtendedArg_A s2, t1
- // t3 = ExtendedArg_A s3, t2
- // dst = op t3
- IR::Instr* instr = nullptr;
- instr = AddExtendedArg(src1Opnd, nullptr, offset);
- instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
- instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- void IRBuilderAsmJs::BuildSimd_2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, IRType simdType)
- {
- ValueType valueType = GetSimdValueTypeFromIRType(simdType);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, simdType);
- src1Opnd->SetValueType(valueType);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, simdType);
- dstOpnd->SetValueType(valueType);
- Js::OpCode opcode;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Simd128_Return_F4:
- case Js::OpCodeAsmJs::Simd128_Return_I4:
- case Js::OpCodeAsmJs::Simd128_Return_I8:
- case Js::OpCodeAsmJs::Simd128_Return_I16:
- case Js::OpCodeAsmJs::Simd128_Return_U4:
- case Js::OpCodeAsmJs::Simd128_Return_U8:
- case Js::OpCodeAsmJs::Simd128_Return_U16:
- case Js::OpCodeAsmJs::Simd128_Return_B4:
- case Js::OpCodeAsmJs::Simd128_Return_B8:
- case Js::OpCodeAsmJs::Simd128_Return_B16:
- if (m_func->IsLoopBody())
- {
- IR::Instr* slotInstr = GenerateStSlotForReturn(src1Opnd, simdType);
- AddInstr(slotInstr, offset);
- }
- opcode = Js::OpCode::Ld_A;
- break;
- case Js::OpCodeAsmJs::Simd128_I_Conv_VTF4:
- case Js::OpCodeAsmJs::Simd128_I_Conv_VTI4:
- case Js::OpCodeAsmJs::Simd128_I_Conv_VTI8:
- case Js::OpCodeAsmJs::Simd128_I_Conv_VTI16:
- case Js::OpCodeAsmJs::Simd128_I_Conv_VTU4:
- case Js::OpCodeAsmJs::Simd128_I_Conv_VTU8:
- case Js::OpCodeAsmJs::Simd128_I_Conv_VTU16:
- case Js::OpCodeAsmJs::Simd128_I_Conv_VTB4:
- case Js::OpCodeAsmJs::Simd128_I_Conv_VTB8:
- case Js::OpCodeAsmJs::Simd128_I_Conv_VTB16:
- case Js::OpCodeAsmJs::Simd128_Ld_F4:
- case Js::OpCodeAsmJs::Simd128_Ld_I4:
- case Js::OpCodeAsmJs::Simd128_Ld_I8:
- case Js::OpCodeAsmJs::Simd128_Ld_I16:
- case Js::OpCodeAsmJs::Simd128_Ld_U4:
- case Js::OpCodeAsmJs::Simd128_Ld_U8:
- case Js::OpCodeAsmJs::Simd128_Ld_U16:
- case Js::OpCodeAsmJs::Simd128_Ld_B4:
- case Js::OpCodeAsmJs::Simd128_Ld_B8:
- case Js::OpCodeAsmJs::Simd128_Ld_B16:
- opcode = Js::OpCode::Ld_A;
- break;
- default:
- opcode = GetSimdOpcode(newOpcode);
- }
- AssertMsg((uint32)opcode, "Invalid backend SIMD opcode");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- void IRBuilderAsmJs::BuildSimd_2Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot, IRType simdType)
- {
- ValueType valueType = GetSimdValueTypeFromIRType(simdType);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, simdType);
- src1Opnd->SetValueType(valueType);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, TyInt32);
- src2Opnd->SetValueType(ValueType::GetInt(false));
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, simdType);
- dstOpnd->SetValueType(valueType);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- AssertMsg((uint32)opcode, "Invalid backend SIMD opcode");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- void IRBuilderAsmJs::BuildSimd_3(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot, IRType simdType)
- {
- BuildSimd_3(newOpcode, offset, dstRegSlot, src1RegSlot, src2RegSlot, simdType, simdType);
- }
- void IRBuilderAsmJs::BuildSimd_3(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot, Js::RegSlot src2RegSlot, IRType dstSimdType, IRType srcSimdType)
- {
- ValueType valueType = GetSimdValueTypeFromIRType(srcSimdType);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, srcSimdType);
- src1Opnd->SetValueType(valueType);
- IR::RegOpnd * src2Opnd = BuildSrcOpnd(src2RegSlot, srcSimdType);
- src2Opnd->SetValueType(valueType);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, dstSimdType);
- dstOpnd->SetValueType(GetSimdValueTypeFromIRType(dstSimdType));
- Js::OpCode opcode;
- opcode = GetSimdOpcode(newOpcode);
- AssertMsg((uint32)opcode, "Invalid backend SIMD opcode");
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, src2Opnd, m_func);
- AddInstr(instr, offset);
- }
- // bool32x4
- void
- IRBuilderAsmJs::BuildBool32x4_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Splat_B4);
- BuildSimd_1Int1(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128B4);
- }
- // bool16x8
- void
- IRBuilderAsmJs::BuildBool16x8_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Splat_B8);
- BuildSimd_1Int1(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128B8);
- }
- // bool8x16
- void
- IRBuilderAsmJs::BuildBool8x16_1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, BUILD_SIMD_ARGS_REG2)
- {
- Assert(newOpcode == Js::OpCodeAsmJs::Simd128_Splat_B16);
- BuildSimd_1Int1(newOpcode, offset, dstRegSlot, src1RegSlot, TySimd128B16);
- }
- void IRBuilderAsmJs::BuildSimdConversion(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot srcRegSlot, IRType dstSimdType, IRType srcSimdType)
- {
- ValueType srcValueType = GetSimdValueTypeFromIRType(srcSimdType);
- ValueType dstValueType = GetSimdValueTypeFromIRType(dstSimdType);
- IR::RegOpnd * src1Opnd = BuildSrcOpnd(srcRegSlot, srcSimdType);
- src1Opnd->SetValueType(srcValueType);
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, dstSimdType);
- dstOpnd->SetValueType(dstValueType);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- IR::Instr * instr = IR::Instr::New(opcode, dstOpnd, src1Opnd, m_func);
- AddInstr(instr, offset);
- }
- ValueType IRBuilderAsmJs::GetSimdValueTypeFromIRType(IRType type)
- {
- switch (type)
- {
- case TySimd128F4:
- return ValueType::GetSimd128(ObjectType::Simd128Float32x4);
- case TySimd128D2:
- return ValueType::GetSimd128(ObjectType::Simd128Float64x2);
- case TySimd128I4:
- return ValueType::GetSimd128(ObjectType::Simd128Int32x4);
- case TySimd128I8:
- return ValueType::GetSimd128(ObjectType::Simd128Int16x8);
- case TySimd128I16:
- return ValueType::GetSimd128(ObjectType::Simd128Int8x16);
- case TySimd128U4:
- return ValueType::GetSimd128(ObjectType::Simd128Uint32x4);
- case TySimd128U8:
- return ValueType::GetSimd128(ObjectType::Simd128Uint16x8);
- case TySimd128U16:
- return ValueType::GetSimd128(ObjectType::Simd128Uint8x16);
- case TySimd128B4:
- return ValueType::GetSimd128(ObjectType::Simd128Bool32x4);
- case TySimd128B8:
- return ValueType::GetSimd128(ObjectType::Simd128Bool16x8);
- case TySimd128B16:
- return ValueType::GetSimd128(ObjectType::Simd128Bool8x16);
- default:
- Assert(UNREACHED);
- }
- return ValueType::GetObject(ObjectType::UninitializedObject);
- }
- void IRBuilderAsmJs::BuildSimd_1Ints(Js::OpCodeAsmJs newOpcode, uint32 offset, IRType dstSimdType, Js::RegSlot* srcRegSlots, Js::RegSlot dstRegSlot, uint LANES)
- {
- Assert(dstSimdType == TySimd128B4 || dstSimdType == TySimd128I4 || dstSimdType == TySimd128U4 ||
- dstSimdType == TySimd128B8 || dstSimdType == TySimd128I8 || dstSimdType == TySimd128U8 ||
- dstSimdType == TySimd128B16|| dstSimdType == TySimd128I16|| dstSimdType == TySimd128U16);
- IR::RegOpnd * srcOpnds[16];
- IR::Instr * instr = nullptr;
- Assert(LANES <= 16);
- Js::OpCode opcode = GetSimdOpcode(newOpcode);
- // first arg
- srcOpnds[0] = BuildSrcOpnd(srcRegSlots[0], TyInt32);
- srcOpnds[0]->SetValueType(ValueType::GetInt(false));
- instr = AddExtendedArg(srcOpnds[0], nullptr, offset);
- // reset of args
- for (uint i = 1; i < LANES && i < 16; i++)
- {
- srcOpnds[i] = BuildSrcOpnd(srcRegSlots[i], TyInt32);
- srcOpnds[i]->SetValueType(ValueType::GetInt(false));
- instr = AddExtendedArg(srcOpnds[i], instr->GetDst()->AsRegOpnd(), offset);
- }
- IR::RegOpnd * dstOpnd = BuildDstOpnd(dstRegSlot, dstSimdType);
- dstOpnd->SetValueType(GetSimdValueTypeFromIRType(dstSimdType));
- AddInstr(IR::Instr::New(opcode, dstOpnd, instr->GetDst(), m_func), offset);
- }
- template<typename SizePolicy>
- void IRBuilderAsmJs::BuildAsmSimdTypedArr(Js::OpCodeAsmJs newOpcode, uint32 offset)
- {
- Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode));
- auto layout = m_jnReader.GetLayout<Js::OpLayoutT_AsmSimdTypedArr<SizePolicy>>();
- BuildAsmSimdTypedArr(newOpcode, offset, layout->SlotIndex, layout->Value, layout->ViewType, layout->DataWidth);
- }
- void
- IRBuilderAsmJs::BuildAsmSimdTypedArr(Js::OpCodeAsmJs newOpcode, uint32 offset, uint32 slotIndex, Js::RegSlot value, Js::ArrayBufferView::ViewType viewType, uint8 dataWidth)
- {
- IRType type = TySimd128F4;
- Js::RegSlot valueRegSlot = GetRegSlotFromSimd128Reg(value);
- IR::RegOpnd * maskedOpnd = nullptr;
- IR::Instr * maskInstr = nullptr;
- Js::OpCode op = GetSimdOpcode(newOpcode);
- ValueType arrayType, valueType;
- bool isLd = false, isConst = false;
- uint32 mask = 0;
- switch (newOpcode)
- {
- case Js::OpCodeAsmJs::Simd128_LdArr_I4:
- valueType = ValueType::GetObject(ObjectType::Simd128Int32x4);
- isLd = true;
- isConst = false;
- type = TySimd128I4;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArr_I8:
- valueType = ValueType::GetObject(ObjectType::Simd128Int16x8);
- isLd = true;
- isConst = false;
- type = TySimd128I8;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArr_I16:
- valueType = ValueType::GetObject(ObjectType::Simd128Int8x16);
- isLd = true;
- isConst = false;
- type = TySimd128I16;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArr_U4:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint32x4);
- isLd = true;
- isConst = false;
- type = TySimd128U4;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArr_U8:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint16x8);
- isLd = true;
- isConst = false;
- type = TySimd128U8;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArr_U16:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint8x16);
- isLd = true;
- isConst = false;
- type = TySimd128U16;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArr_F4:
- valueType = ValueType::GetObject(ObjectType::Simd128Float32x4);
- isLd = true;
- isConst = false;
- type = TySimd128F4;
- break;
- #if 0
- case Js::OpCodeAsmJs::Simd128_LdArr_D2:
- valueType = ValueType::GetObject(ObjectType::Simd128Float64x2);
- isLd = true;
- isConst = false;
- type = TySimd128D2;
- break;
- #endif // 0
- case Js::OpCodeAsmJs::Simd128_StArr_I4:
- valueType = ValueType::GetObject(ObjectType::Simd128Int32x4);
- isLd = false;
- isConst = false;
- type = TySimd128I4;
- break;
- case Js::OpCodeAsmJs::Simd128_StArr_I8:
- valueType = ValueType::GetObject(ObjectType::Simd128Int16x8);
- isLd = false;
- isConst = false;
- type = TySimd128I8;
- break;
- case Js::OpCodeAsmJs::Simd128_StArr_I16:
- valueType = ValueType::GetObject(ObjectType::Simd128Int8x16);
- isLd = false;
- isConst = false;
- type = TySimd128I16;
- break;
- case Js::OpCodeAsmJs::Simd128_StArr_U4:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint32x4);
- isLd = false;
- isConst = false;
- type = TySimd128U4;
- break;
- case Js::OpCodeAsmJs::Simd128_StArr_U8:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint16x8);
- isLd = false;
- isConst = false;
- type = TySimd128U8;
- break;
- case Js::OpCodeAsmJs::Simd128_StArr_U16:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint8x16);
- isLd = false;
- isConst = false;
- type = TySimd128U16;
- break;
- case Js::OpCodeAsmJs::Simd128_StArr_F4:
- valueType = ValueType::GetObject(ObjectType::Simd128Float32x4);
- isLd = false;
- isConst = false;
- type = TySimd128F4;
- break;
- #if 0
- case Js::OpCodeAsmJs::Simd128_StArr_D2:
- valueType = ValueType::GetObject(ObjectType::Simd128Float64x2);
- isLd = false;
- isConst = false;
- type = TySimd128D2;
- break;
- #endif // 0
- case Js::OpCodeAsmJs::Simd128_LdArrConst_I4:
- valueType = ValueType::GetObject(ObjectType::Simd128Int32x4);
- isLd = true;
- isConst = true;
- type = TySimd128I4;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArrConst_I8:
- valueType = ValueType::GetObject(ObjectType::Simd128Int16x8);
- isLd = true;
- isConst = true;
- type = TySimd128I8;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArrConst_I16:
- valueType = ValueType::GetObject(ObjectType::Simd128Int8x16);
- isLd = true;
- isConst = true;
- type = TySimd128I16;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArrConst_U4:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint32x4);
- isLd = true;
- isConst = true;
- type = TySimd128U4;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArrConst_U8:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint16x8);
- isLd = true;
- isConst = true;
- type = TySimd128U8;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArrConst_U16:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint8x16);
- isLd = true;
- isConst = true;
- type = TySimd128U16;
- break;
- case Js::OpCodeAsmJs::Simd128_LdArrConst_F4:
- valueType = ValueType::GetObject(ObjectType::Simd128Float32x4);
- isLd = true;
- isConst = true;
- type = TySimd128F4;
- break;
- #if 0
- case Js::OpCodeAsmJs::Simd128_LdArrConst_D2:
- valueType = ValueType::GetObject(ObjectType::Simd128Float64x2);
- isLd = true;
- isConst = true;
- type = TySimd128D2;
- break;
- #endif
- case Js::OpCodeAsmJs::Simd128_StArrConst_I4:
- valueType = ValueType::GetObject(ObjectType::Simd128Int32x4);
- isLd = false;
- type = TySimd128I4;
- isConst = true;
- break;
- case Js::OpCodeAsmJs::Simd128_StArrConst_I8:
- valueType = ValueType::GetObject(ObjectType::Simd128Int16x8);
- isLd = false;
- isConst = true;
- type = TySimd128I8;
- break;
- case Js::OpCodeAsmJs::Simd128_StArrConst_I16:
- valueType = ValueType::GetObject(ObjectType::Simd128Int8x16);
- isLd = false;
- isConst = true;
- type = TySimd128I16;
- break;
- case Js::OpCodeAsmJs::Simd128_StArrConst_U4:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint32x4);
- isLd = false;
- isConst = true;
- type = TySimd128U4;
- break;
- case Js::OpCodeAsmJs::Simd128_StArrConst_U8:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint16x8);
- isLd = false;
- isConst = true;
- type = TySimd128U8;
- break;
- case Js::OpCodeAsmJs::Simd128_StArrConst_U16:
- valueType = ValueType::GetObject(ObjectType::Simd128Uint8x16);
- isLd = false;
- isConst = true;
- type = TySimd128U16;
- break;
- case Js::OpCodeAsmJs::Simd128_StArrConst_F4:
- valueType = ValueType::GetObject(ObjectType::Simd128Float32x4);
- isLd = false;
- isConst = true;
- type = TySimd128F4;
- break;
- #if 0
- case Js::OpCodeAsmJs::Simd128_StArrConst_D2:
- valueType = ValueType::GetObject(ObjectType::Simd128Float64x2);
- isLd = false;
- isConst = true;
- type = TySimd128D2;
- break;
- #endif
- default:
- Assert(UNREACHED);
- }
- switch (viewType)
- {
- case Js::ArrayBufferView::TYPE_INT8:
- arrayType = ValueType::GetObject(ObjectType::Int8Array);
- break;
- case Js::ArrayBufferView::TYPE_UINT8:
- arrayType = ValueType::GetObject(ObjectType::Uint8Array);
- break;
- case Js::ArrayBufferView::TYPE_INT16:
- arrayType = ValueType::GetObject(ObjectType::Int16Array);
- mask = (uint32)~1;
- break;
- case Js::ArrayBufferView::TYPE_UINT16:
- arrayType = ValueType::GetObject(ObjectType::Uint16Array);
- mask = (uint32)~1;
- break;
- case Js::ArrayBufferView::TYPE_INT32:
- arrayType = ValueType::GetObject(ObjectType::Int32Array);
- mask = (uint32)~3;
- break;
- case Js::ArrayBufferView::TYPE_UINT32:
- arrayType = ValueType::GetObject(ObjectType::Uint32Array);
- mask = (uint32)~3;
- break;
- case Js::ArrayBufferView::TYPE_FLOAT32:
- arrayType = ValueType::GetObject(ObjectType::Float32Array);
- mask = (uint32)~3;
- break;
- case Js::ArrayBufferView::TYPE_FLOAT64:
- arrayType = ValueType::GetObject(ObjectType::Float64Array);
- mask = (uint32)~7;
- break;
- default:
- Assert(UNREACHED);
- }
- IR::Opnd * sizeOpnd = BuildSrcOpnd(AsmJsRegSlots::LengthReg, TyUint32);
- if (!isConst)
- {
- Js::RegSlot indexRegSlot = GetRegSlotFromIntReg(slotIndex);
- if (mask)
- {
- // AND_I4 index, mask
- maskedOpnd = IR::RegOpnd::New(TyUint32, m_func);
- maskInstr = IR::Instr::New(Js::OpCode::And_I4, maskedOpnd, BuildSrcOpnd(indexRegSlot, TyInt32), IR::IntConstOpnd::New(mask, TyUint32, m_func), m_func);
- }
- else
- {
- maskedOpnd = BuildSrcOpnd(indexRegSlot, TyInt32);
- }
- }
- IR::Instr * instr = nullptr;
- IR::RegOpnd * regOpnd = nullptr;
- IR::IndirOpnd * indirOpnd = nullptr;
- IR::RegOpnd * baseOpnd = BuildSrcOpnd(AsmJsRegSlots::BufferReg, TyVar);
- baseOpnd->SetValueType(arrayType);
- baseOpnd->SetValueTypeFixed();
- if (isLd)
- {
- regOpnd = BuildDstOpnd(valueRegSlot, type);
- regOpnd->SetValueType(valueType);
- if (!isConst)
- {
- Assert(maskedOpnd);
- // Js::OpCodeAsmJs::Simd128_LdArr_I4:
- // Js::OpCodeAsmJs::Simd128_LdArr_F4:
- // Js::OpCodeAsmJs::Simd128_LdArr_D2:
- indirOpnd = IR::IndirOpnd::New(baseOpnd, maskedOpnd, type, m_func);
- }
- else
- {
- // Js::OpCodeAsmJs::Simd128_LdArrConst_I4:
- // Js::OpCodeAsmJs::Simd128_LdArrConst_F4:
- // Js::OpCodeAsmJs::Simd128_LdArrConst_D2:
- indirOpnd = IR::IndirOpnd::New(baseOpnd, slotIndex, type, m_func);
- }
- instr = IR::Instr::New(op, regOpnd, indirOpnd, sizeOpnd, m_func);
- }
- else
- {
- regOpnd = BuildSrcOpnd(valueRegSlot, type);
- regOpnd->SetValueType(valueType);
- if (!isConst)
- {
- Assert(maskedOpnd);
- // Js::OpCodeAsmJs::Simd128_StArr_I4:
- // Js::OpCodeAsmJs::Simd128_StArr_F4:
- // Js::OpCodeAsmJs::Simd128_StArr_D2:
- indirOpnd = IR::IndirOpnd::New(baseOpnd, maskedOpnd, type, m_func);
- }
- else
- {
- // Js::OpCodeAsmJs::Simd128_StArrConst_I4:
- // Js::OpCodeAsmJs::Simd128_StArrConst_F4:
- // Js::OpCodeAsmJs::Simd128_StArrConst_D2:
- indirOpnd = IR::IndirOpnd::New(baseOpnd, slotIndex, type, m_func);
- }
- instr = IR::Instr::New(op, indirOpnd, regOpnd, sizeOpnd, m_func);
- }
- // REVIEW: Store dataWidth in the instruction itself instead of an argument to avoid using ExtendedArgs or excessive opcodes.
- Assert(dataWidth >= 4 && dataWidth <= 16);
- instr->dataWidth = dataWidth;
- if (maskInstr)
- {
- AddInstr(maskInstr, offset);
- }
- AddInstr(instr, offset);
- }
- #endif
|