| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737 |
- //-------------------------------------------------------------------------------------------------------
- // 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;
- Js::RegSlot 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;
- 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 (tempCount > 0)
- {
- m_tempMap = (SymID*)m_tempAlloc->AllocZero(sizeof(SymID) * tempCount);
- m_fbvTempUsed = BVFixed::New<JitArenaAllocator>(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();
- }
- #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
- if (!this->IsLoopBody() && PHASE_TRACE(Js::AsmjsFunctionEntryPhase, m_func))
- {
- BuildArgInTracing();
- }
- #endif
- 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);
- int* intConstTable = reinterpret_cast<int*>(((byte*)constTable) + info.constSrcByteOffset);
- Js::RegSlot srcReg = GetTypedRegFromRegSlot(regSlot, WAsmJs::INT32);
- Assert(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?");
- return m_tempMap[reg - GetFirstTmp(WAsmJs::FirstType)];
- }
- 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?");
- m_tempMap[reg - GetFirstTmp(WAsmJs::FirstType)] = 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?");
- return m_fbvTempUsed->Test(reg - GetFirstTmp(WAsmJs::FirstType));
- }
- 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?");
- if (used)
- {
- m_fbvTempUsed->Set(reg - GetFirstTmp(WAsmJs::FirstType));
- }
- else
- {
- m_fbvTempUsed->Clear(reg - GetFirstTmp(WAsmJs::FirstType));
- }
- }
- 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);
- // 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);
- }
- }
- #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
- void
- IRBuilderAsmJs::BuildArgInTracing()
- {
- // todo:: fix implementation on x64
- #ifdef _M_IX86
- int32 intArgInCount = 0;
- int32 int64ArgInCount = 0;
- int32 floatArgInCount = 0;
- int32 doubleArgInCount = 0;
- int32 simd128ArgInCount = 0;
- Js::ArgSlot nArgs = 0;
- if (m_func->GetJITFunctionBody()->HasImplicitArgIns())
- {
- // -1 to remove the implicit this pointer
- nArgs = m_func->GetJITFunctionBody()->GetInParamsCount() - 1;
- }
- int32 argSize = 0;
- Js::ArgSlot argOutSlot = 1;
- // Start Call
- IR::RegOpnd * dstOpnd = IR::RegOpnd::New(TyVar, m_func);
- IR::IntConstOpnd * argSizeOpnd = IR::IntConstOpnd::New(nArgs, TyInt32, m_func);
- IR::Instr *instr = IR::Instr::New(Js::OpCode::StartCall, dstOpnd, argSizeOpnd, m_func);
- AddInstr(instr, Js::Constants::NoByteCodeOffset);
- m_argStack->Push(instr);
- auto PushArg = [&](IRType type, ValueType valueType, IR::Opnd* srcOpnd) {
- StackSym* symDst = StackSym::NewArgSlotSym(argOutSlot++, m_func, type);
- symDst->m_allocated = true;
- IR::SymOpnd * dstOpnd = IR::SymOpnd::New(symDst, type, m_func);
- dstOpnd->SetValueType(valueType);
- IR::Instr * instr = IR::Instr::New(Js::OpCode::ArgOut_A, dstOpnd, srcOpnd, m_func);
- AddInstr(instr, Js::Constants::NoByteCodeOffset);
- m_argStack->Push(instr);
- argSize += max(TySize[type], MachPtr);
- };
- // Move the function object as an argument
- {
- StackSym* stackSym = StackSym::New(m_func);
- IR::RegOpnd* stackOpnd = IR::RegOpnd::New(stackSym, TyVar, m_func);
- AddInstr(IR::Instr::New(Js::OpCode::LdFuncObj, stackOpnd, m_func), Js::Constants::NoByteCodeOffset);
- PushArg(TyVar, ValueType::GetObject(ObjectType::Object), stackOpnd);
- }
- PushArg(TyInt32, ValueType::GetInt(false), IR::IntConstOpnd::New(nArgs, TyInt32, m_func));
- for (Js::ArgSlot i = 0; i < nArgs; ++i)
- {
- IRType argType;
- Js::RegSlot argSlot;
- ValueType valueType;
- Js::AsmJsVarType varType = m_asmFuncInfo->GetArgType(i);
- switch (varType.which())
- {
- case Js::AsmJsVarType::Which::Int:
- argType = TyInt32;
- argSlot = GetFirstVar(WAsmJs::INT32) + intArgInCount;
- valueType = ValueType::GetInt(false);
- ++intArgInCount;
- break;
- case Js::AsmJsVarType::Which::Float:
- argType = TyFloat32;
- argSlot = GetFirstVar(WAsmJs::FLOAT32) + floatArgInCount;
- valueType = ValueType::Float;
- ++floatArgInCount;
- break;
- case Js::AsmJsVarType::Which::Double:
- argType = TyFloat64;
- argSlot = GetFirstVar(WAsmJs::FLOAT64) + doubleArgInCount;
- valueType = ValueType::Float;
- ++doubleArgInCount;
- break;
- case Js::AsmJsVarType::Which::Int64:
- argType = TyInt64;
- argSlot = GetFirstVar(WAsmJs::INT64) + int64ArgInCount;
- valueType = ValueType::GetInt(false);
- ++int64ArgInCount;
- break;
- default:
- // SIMD_JS
- GetSimdTypesFromAsmType((Js::AsmJsType::Which)varType.which(), &argType, &valueType);
- argSlot = GetFirstVar(WAsmJs::SIMD) + simd128ArgInCount;
- ++simd128ArgInCount;
- break;
- }
- PushArg(TyInt32, ValueType::GetInt(false), IR::IntConstOpnd::New((int32)argType, TyInt32, m_func));
- PushArg(argType, valueType, BuildSrcOpnd(argSlot, argType));
- }
- // save this so we can calculate arg offsets later on
- m_argOffsetStack->Push(argSize);
- argSizeOpnd->SetValue(argSize);
- BuildAsmCall(Js::OpCodeAsmJs::AsmJsEntryTracing, Js::Constants::NoByteCodeOffset, nArgs * 2 + 1, 0, 0, 0);
- #endif
- }
- #endif
- void
- IRBuilderAsmJs::InsertLabels()
- {
- AssertMsg(m_branchRelocList, "Malformed branch reloc list");
- SList<BranchReloc *>::Iterator iter(m_branchRelocList);
- while (iter.Next())
- {
- IR::LabelInstr * labelInstr;
- 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::Unreachable_Void:
- instr = IR::Instr::New(Js::OpCode::Unreachable_Void, 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);
- }
- }
- 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, int8 viewType)
- {
- IRType type = TyInt32;
- bool isWasm = this->m_func->GetJITFunctionBody()->IsWasmFunction();
- bool isLd = newOpcode == Js::OpCodeAsmJs::LdArr || newOpcode == Js::OpCodeAsmJs::LdArrWasm || newOpcode == Js::OpCodeAsmJs::LdArrConst;
- Js::OpCode op = isLd ? (isWasm ?
- Js::OpCode::LdArrViewElemWasm : Js::OpCode::LdArrViewElem) : Js::OpCode::StArrViewElem;
- ValueType arrayType;
- WAsmJs::Types valueRegType = WAsmJs::INT32;
- switch (viewType)
- {
- case Js::ArrayBufferView::TYPE_INT8_TO_INT64:
- valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_INT8:
- arrayType = ValueType::GetObject(ObjectType::Int8Array);
- type = TyInt8;
- break;
- case Js::ArrayBufferView::TYPE_UINT8_TO_INT64:
- valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_UINT8:
- arrayType = ValueType::GetObject(ObjectType::Uint8Array);
- type = TyUint8;
- break;
- case Js::ArrayBufferView::TYPE_INT16_TO_INT64:
- valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_INT16:
- arrayType = ValueType::GetObject(ObjectType::Int16Array);
- type = TyInt16;
- break;
- case Js::ArrayBufferView::TYPE_UINT16_TO_INT64:
- valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_UINT16:
- arrayType = ValueType::GetObject(ObjectType::Uint16Array);
- type = TyUint16;
- break;
- case Js::ArrayBufferView::TYPE_INT32_TO_INT64:
- valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_INT32:
- arrayType = ValueType::GetObject(ObjectType::Int32Array);
- type = TyInt32;
- break;
- case Js::ArrayBufferView::TYPE_UINT32_TO_INT64:
- valueRegType = WAsmJs::INT64;
- case Js::ArrayBufferView::TYPE_UINT32:
- arrayType = ValueType::GetObject(ObjectType::Uint32Array);
- type = TyUint32;
- break;
- case Js::ArrayBufferView::TYPE_FLOAT32:
- valueRegType = WAsmJs::FLOAT32;
- arrayType = ValueType::GetObject(ObjectType::Float32Array);
- type = TyFloat32;
- break;
- case Js::ArrayBufferView::TYPE_FLOAT64:
- valueRegType = WAsmJs::FLOAT64;
- arrayType = ValueType::GetObject(ObjectType::Float64Array);
- type = TyFloat64;
- break;
- case Js::ArrayBufferView::TYPE_INT64:
- valueRegType = WAsmJs::INT64;
- arrayType = ValueType::GetObject(ObjectType::Int64Array);
- type = TyInt64;
- break;
- default:
- Assume(UNREACHED);
- }
- Js::RegSlot valueRegSlot = GetRegSlotFromTypedReg(value, 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 && !m_func->GetJITFunctionBody()->IsWasmFunction())
- {
- 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, type, m_func);
- indirOpnd->GetBaseOpnd()->SetValueType(arrayType);
- }
- else if (newOpcode == Js::OpCodeAsmJs::LdArrWasm || newOpcode == Js::OpCodeAsmJs::StArrWasm)
- {
- Js::RegSlot indexRegSlot = GetRegSlotFromInt64Reg(slotIndex);
- IR::RegOpnd * maskedOpnd = BuildSrcOpnd(indexRegSlot, TyUint64);
- indirOpnd = IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::BufferReg, TyVar), maskedOpnd, type, m_func);
- indirOpnd->GetBaseOpnd()->SetValueType(arrayType);
- }
- else
- {
- Assert(newOpcode == Js::OpCodeAsmJs::LdArrConst || newOpcode == Js::OpCodeAsmJs::StArrConst);
- indirOpnd = IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::BufferReg, TyVar), slotIndex, type, m_func);
- indirOpnd->GetBaseOpnd()->SetValueType(arrayType);
- }
- // Setup the value/destination
- if (valueRegType == WAsmJs::FLOAT32 || valueRegType == WAsmJs::FLOAT64)
- {
- Assert(IRType_IsFloat(type));
- regOpnd = !isLd ? BuildSrcOpnd(valueRegSlot, type) : BuildDstOpnd(valueRegSlot, type);
- regOpnd->SetValueType(ValueType::Float);
- }
- else if (valueRegType == WAsmJs::INT64)
- {
- Assert(IRType_IsNativeInt(type));
- regOpnd = !isLd ? BuildSrcOpnd(valueRegSlot, TyInt64) : BuildDstOpnd(valueRegSlot, TyInt64);
- regOpnd->SetValueType(ValueType::GetInt(false));
- }
- else
- {
- Assert(IRType_IsNativeInt(type));
- Assert(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 (isWasm && !CONFIG_FLAG(WasmFastArray))
- #endif
- {
- instr->SetSrc2(BuildSrcOpnd(AsmJsRegSlots::LengthReg, TyUint32));
- }
- 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;
- case Js::OpCodeAsmJs::AsmJsEntryTracing:
- argOffset = m_argOffsetStack->Pop();
- instr = IR::Instr::New(Js::OpCode::AsmJsEntryTracing, 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 || newOpcode == Js::OpCodeAsmJs::AsmJsEntryTracing)
- {
- #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;
- #if defined(_M_X64)
- if (m_func->IsSIMDEnabled())
- {
- m_tempList->Push(argInstr);
- }
- #endif
- #if DBG
- count++;
- #endif
- }
- Assert(argOffset == 0);
- AnalysisAssert(argInstr);
- prevInstr->SetSrc2(argInstr->GetDst());
- #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
- if (m_func->m_argSlotsForFunctionsCalled < argCount)
- {
- m_func->m_argSlotsForFunctionsCalled = argCount;
- }
- if (m_asmFuncInfo->UsesHeapBuffer())
- {
- // if heap buffer can change, then we will insert reload after each call
- if (!m_asmFuncInfo->IsHeapBufferConst())
- {
- BuildHeapBufferReload(offset);
- }
- // after foreign function call, we need to make sure that the heap hasn't been detached
- if (newOpcode == Js::OpCodeAsmJs::Call)
- {
- IR::Instr * instrArrayDetachedCheck = IR::Instr::New(Js::OpCode::ArrayDetachedCheck, m_func);
- instrArrayDetachedCheck->SetSrc1(IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::ArrayReg, TyVar), Js::ArrayBuffer::GetIsDetachedOffset(), TyInt8, m_func));
- AddInstr(instrArrayDetachedCheck, offset);
- }
- }
- }
- 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(UInt16Math::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);
- 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);
- 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_UInt:
- src1Opnd->SetType(TyUint32);
- src2Opnd->SetType(TyUint32);
- case Js::OpCodeAsmJs::Mul_Int:
- instr = IR::Instr::New(Js::OpCode::Mul_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Div_Check_UInt:
- src1Opnd->SetType(TyUint32);
- src2Opnd->SetType(TyUint32);
- case Js::OpCodeAsmJs::Div_Check_Int:
- {
- src2Opnd = BuildTrapIfZero(src2Opnd, offset);
- src1Opnd = BuildTrapIfMinIntOverNegOne(src1Opnd, src2Opnd, offset);
- instr = IR::Instr::New(Js::OpCode::Div_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- }
- case Js::OpCodeAsmJs::Div_UInt:
- src1Opnd->SetType(TyUint32);
- src2Opnd->SetType(TyUint32);
- case Js::OpCodeAsmJs::Div_Int:
- instr = IR::Instr::New(Js::OpCode::Div_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Rem_Check_UInt:
- src1Opnd->SetType(TyUint32);
- src2Opnd->SetType(TyUint32);
- case Js::OpCodeAsmJs::Rem_Check_Int:
- src2Opnd = BuildTrapIfZero(src2Opnd, offset);
- instr = IR::Instr::New(Js::OpCode::Rem_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- case Js::OpCodeAsmJs::Rem_UInt:
- src1Opnd->SetType(TyUint32);
- src2Opnd->SetType(TyUint32);
- 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_ULong:
- src1Opnd->SetType(TyUint64);
- src2Opnd->SetType(TyUint64);
- case Js::OpCodeAsmJs::Div_Long:
- {
- src2Opnd = BuildTrapIfZero(src2Opnd, offset);
- src1Opnd = BuildTrapIfMinIntOverNegOne(src1Opnd, src2Opnd, offset);
- instr = IR::Instr::New(Js::OpCode::Div_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
- break;
- }
- case Js::OpCodeAsmJs::Rem_ULong:
- src1Opnd->SetType(TyUint64);
- src2Opnd->SetType(TyUint64);
- case Js::OpCodeAsmJs::Rem_Long:
- src2Opnd = BuildTrapIfZero(src2Opnd, offset);
- instr = IR::Instr::New(Js::OpCode::Rem_I4, 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);
- 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);
- 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)
- {
- // 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, int8 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
|