jit.c 168 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003
  1. /* Copyright 2018-2020
  2. Free Software Foundation, Inc.
  3. This file is part of Guile.
  4. Guile is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Lesser General Public License as published
  6. by the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. Guile is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  11. License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with Guile. If not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #ifdef HAVE_CONFIG_H
  16. # include <config.h>
  17. #endif
  18. /* All of this whole file is within an ENABLE_JIT flag. */
  19. #if ENABLE_JIT
  20. #include <stdio.h>
  21. #include <sys/mman.h>
  22. #include <lightening.h>
  23. #include "frames.h"
  24. #include "gsubr.h"
  25. #include "gc-inline.h"
  26. #include "instructions.h"
  27. #include "intrinsics.h"
  28. #include "simpos.h" /* scm_getenv_int */
  29. #include "threads.h"
  30. #include "vm-builtins.h"
  31. #include "vm-operations.h"
  32. #include "jit.h"
  33. /* Guile's just-in-time (JIT) compiler is a simple "template JIT". It
  34. produces machine code corresponding to each VM instruction,
  35. substituting in the arguments from the bytecode. The generated code
  36. performs the same operations on the Guile program state the VM
  37. interpreter would: the same stack reads and writes, the same calls,
  38. the same control flow: the same thing. It's a very simple JIT.
  39. This JIT uses GNU Lightning, a library for generating assembly code.
  40. It has backends for every architecture you can think of. Lightning
  41. exposes a minimum of 3 "volatile" or "scratch" registers, those that
  42. may be overwritten by called functions, and 3 "non-volatile" or
  43. "preserved" registers, those whose values will persist over calls.
  44. Guile's JIT uses two preserved registers for itself, to store the
  45. current thread and the current stack pointer. The other four
  46. registers are available for the JIT. However as Guile's JIT is
  47. really simple and doesn't do register allocation, no other register
  48. is live between bytecodes; the other four registers are just scratch
  49. space.
  50. Machine code emitted by the JIT (mcode) should only ever be entered
  51. from the interpreter (the VM). To enter bytecode, the interpreter
  52. calls an "entry trampoline" that saves the needed non-volatile
  53. registers, reserves some stack space, loads the thread and stack
  54. pointer into the reserved registers, then jumps into the mcode. The
  55. mcode then does its thing.
  56. When mcode needs to call out to another function, e.g. via the "call"
  57. instruction, it makes a new frame in just the same way the VM would,
  58. with the difference that it also sets the machine return address
  59. (mRA) in the stack frame, in addition to the virtual (bytecode)
  60. return address (vRA). If the callee has mcode, then the caller jumps
  61. to the callee's mcode. It's a jump, not a call, as the stack is
  62. maintained on the side: it's not the stack used by the e.g. x86
  63. "call" instruction.
  64. When mcode calls a function that doesn't have vcode, or returns to a
  65. continuation that doesn't have vcode, the mcode simply returns to the
  66. VM interpreter, allowing the interpreter to pick up from there. The
  67. return actually happens via an exit trampoline, which restores the
  68. saved register values.
  69. Every function in Guile's VM begins with an "instrument-entry"
  70. instruction. The instruction links to a statically allocated "struct
  71. scm_jit_function_data" corresponding to that function. When the
  72. interpreter sees instrument-entry, first it checks that if the
  73. function has mcode, by looking in the scm_jit_function_data. If it
  74. has mcode, the interpreter enters mcode directly, as described above.
  75. If a function doesn't have mcode, "instrument-entry" will increment a
  76. counter in the scm_jit_function_data. If the counter exceeds a
  77. threshold, the interpreter will ask the JIT compiler to produce
  78. mcode. If the JIT compiler was able to do so (always possible except
  79. in case of resource exhaustion), then it sets the mcode pointer in
  80. the scm_jit_function_data, and returns the mcode pointer to the
  81. interpreter. At that point the interpreter will enter mcode.
  82. If the counter value does not exceed the threshold, then the VM
  83. will interpret the function instead of running compiled code.
  84. Additionally, Guile puts an "instrument-loop" instruction into the
  85. body of each loop iteration. It works similarly, except that the
  86. returned mcode pointer starts in the middle of the function, at the
  87. point that corresponds to the program point of the "instrument-loop"
  88. instruction. The idea is that some functions have long-running loops
  89. in them, and it would be a shame to have to wait until the next time
  90. they're called to enter mcode. Being able to "tier up" from inside a
  91. loop reduces overall program latency.
  92. Think of the JIT as microarchitecture. The interpreter specifies the
  93. architecture of the VM, in terms of the stack, stack and frame
  94. pointers, and a virtual instruction pointer. Sometimes this
  95. architectural state is manipulated by the interpreter. Sometimes
  96. it's compiled down to native code. But the existence of native code
  97. is a detail that's fully encapsulated; systems-oriented Guile Scheme
  98. can walk stacks, throw errors, reinstate partial continuations, and
  99. so on without being aware of the existence of the JIT. */
  100. static const uint32_t default_jit_threshold = 1000;
  101. /* Threshold for when to JIT-compile a function. Set from the
  102. GUILE_JIT_THRESHOLD environment variable. */
  103. uint32_t scm_jit_counter_threshold = -1;
  104. /* If positive, stop JIT compilation after the Nth compilation. Useful
  105. for hunting down bugs. */
  106. static int jit_stop_after = -1;
  107. /* If nonzero, pause when stopping JIT compilation after the Nth
  108. compilation. For debugging. */
  109. static int jit_pause_when_stopping = 0;
  110. /* Log level for JIT events. 0 means off. */
  111. static int jit_log_level = 0;
  112. /* Entry trampoline: saves registers, initializes THREAD and SP
  113. registers, and jumps into mcode. */
  114. static void (*enter_mcode) (scm_thread *thread, const uint8_t *mcode);
  115. /* Exit trampoline: restores registers and returns to interpreter. */
  116. static void *exit_mcode;
  117. /* Handle interrupts trampoline: the slow path of the handle-interrupts
  118. instruction, compiled as a stub on the side to reduce code size. */
  119. static void *handle_interrupts_trampoline;
  120. /* Return to interpreter trampoline: trampoline to load IP from the VRA
  121. and tier down. */
  122. void *scm_jit_return_to_interpreter_trampoline;
  123. /* Thread-local buffer into which to write code. */
  124. struct code_arena
  125. {
  126. uint8_t *base;
  127. size_t used;
  128. size_t size;
  129. struct code_arena *prev;
  130. };
  131. /* Branches between instructions. */
  132. struct pending_reloc
  133. {
  134. jit_reloc_t reloc;
  135. /* Each instruction has two labels: one principal label, for inline
  136. code, and one auxiliary label for the slow path (if any). The
  137. inline label is the vcode offset times two, and the slow label is
  138. the vcode offset times two plus one. */
  139. ptrdiff_t target_label_offset;
  140. };
  141. /* State of the JIT compiler for the current thread. */
  142. struct scm_jit_state {
  143. jit_state_t *jit;
  144. scm_thread *thread;
  145. const uint32_t *start;
  146. uint32_t *ip;
  147. uint32_t *next_ip;
  148. const uint32_t *end;
  149. uint32_t *entry;
  150. uint8_t *op_attrs;
  151. struct pending_reloc *relocs;
  152. size_t reloc_idx;
  153. size_t reloc_count;
  154. void **labels;
  155. int32_t frame_size_min;
  156. int32_t frame_size_max;
  157. uint32_t register_state;
  158. jit_gpr_t sp_cache_gpr;
  159. jit_fpr_t sp_cache_fpr;
  160. uint32_t sp_cache_gpr_idx;
  161. uint32_t sp_cache_fpr_idx;
  162. struct code_arena *code_arena;
  163. };
  164. typedef struct scm_jit_state scm_jit_state;
  165. static const uint32_t program_word_offset_free_variable = 2;
  166. static const uint32_t frame_offset_mra = 0 * sizeof(union scm_vm_stack_element);
  167. static const uint32_t frame_offset_vra = 1 * sizeof(union scm_vm_stack_element);
  168. static const uint32_t frame_offset_prev = 2 * sizeof(union scm_vm_stack_element);
  169. static const uint32_t frame_overhead_slots = 3;
  170. #define DEFINE_THREAD_OFFSET(f) \
  171. static const uint32_t thread_offset_##f = \
  172. offsetof (struct scm_thread, f)
  173. DEFINE_THREAD_OFFSET (handle);
  174. DEFINE_THREAD_OFFSET (pending_asyncs);
  175. DEFINE_THREAD_OFFSET (block_asyncs);
  176. #define DEFINE_THREAD_VP_OFFSET(f) \
  177. static const uint32_t thread_offset_##f = \
  178. offsetof (struct scm_thread, vm) + offsetof (struct scm_vm, f)
  179. DEFINE_THREAD_VP_OFFSET (fp);
  180. DEFINE_THREAD_VP_OFFSET (sp);
  181. DEFINE_THREAD_VP_OFFSET (ip);
  182. DEFINE_THREAD_VP_OFFSET (stack_limit);
  183. /* The current scm_thread*. Preserved across callouts. */
  184. static const jit_gpr_t THREAD = JIT_V0;
  185. /* The current stack pointer. Clobbered across callouts. Can be
  186. reloaded from the thread. Note that any callout that might
  187. recursively enter the VM may move the stack pointer. */
  188. static const jit_gpr_t SP = JIT_R0;
  189. /* During calls and returns -- the parts of the code that manipulate the
  190. frame pointer -- the current frame pointer is stored in FP.
  191. Otherwise this is a temp register. It can always be reloaded from
  192. THREAD. Like SP, it can move. */
  193. static const jit_gpr_t FP = JIT_R1;
  194. /* When we return to a function that doesn't have mcode, the just-popped
  195. FP is stored in this register. The return-to-the-interpreter
  196. trampoline reads the vRA from the just-popped frame. */
  197. static const jit_gpr_t OLD_FP_FOR_RETURN_TRAMPOLINE = JIT_V1; /* T0 */
  198. /* Scratch registers. */
  199. static const jit_gpr_t T0 = JIT_V1;
  200. static const jit_gpr_t T1 = JIT_V2;
  201. static const jit_gpr_t T2 = JIT_R2;
  202. SCM_UNUSED static const jit_gpr_t T3_OR_FP = JIT_R1;
  203. SCM_UNUSED static const jit_gpr_t T4_OR_SP = JIT_R0;
  204. /* Sometimes you want to call out the fact that T0 and T1 are preserved
  205. across calls. In that case, use these. */
  206. SCM_UNUSED static const jit_gpr_t T0_PRESERVED = JIT_V1;
  207. static const jit_gpr_t T1_PRESERVED = JIT_V2;
  208. static const uint32_t SP_IN_REGISTER = 0x1;
  209. static const uint32_t FP_IN_REGISTER = 0x2;
  210. static const uint32_t UNREACHABLE = 0x4;
  211. static const uint32_t SP_CACHE_GPR = 0x8;
  212. static const uint32_t SP_CACHE_FPR = 0x10;
  213. static const uint8_t OP_ATTR_BLOCK = 0x1;
  214. static const uint8_t OP_ATTR_ENTRY = 0x2;
  215. #ifdef WORDS_BIGENDIAN
  216. #define BIGENDIAN 1
  217. #else
  218. #define BIGENDIAN 0
  219. #endif
  220. #if SCM_SIZEOF_UINTPTR_T == 4
  221. static const uint32_t log2_sizeof_uintptr_t = 2;
  222. #elif SCM_SIZEOF_UINTPTR_T == 8
  223. static const uint32_t log2_sizeof_uintptr_t = 3;
  224. #else
  225. #error unhandled uintptr_t size
  226. #endif
  227. #define LENGTH_NOP 0
  228. #define LENGTH_OP1(a) 1
  229. #define LENGTH_OP2(a,b) 2
  230. #define LENGTH_OP3(a,b,c) 3
  231. #define LENGTH_OP4(a,b,c,d) 4
  232. #define LENGTH_DOP1(a) 1
  233. #define LENGTH_DOP2(a,b) 2
  234. #define LENGTH_DOP3(a,b,c) 3
  235. #define LENGTH_DOP4(a,b,c,d) 4
  236. static const uint8_t op_lengths[256] = {
  237. #define OP_LENGTH(code, cname, name, arity) LENGTH_##arity,
  238. FOR_EACH_VM_OPERATION(OP_LENGTH)
  239. #undef OP_LENGTH
  240. };
  241. static void die (int line, const char *msg) SCM_NORETURN;
  242. static void
  243. die (int line, const char *msg)
  244. {
  245. fprintf (stderr, "jit.c:%d: fatal: %s\n", line, msg);
  246. abort ();
  247. }
  248. #define DIE(msg) die(__LINE__, msg)
  249. #define ASSERT(x) \
  250. do { if (SCM_UNLIKELY (!(x))) DIE ("assertion failed"); } while (0)
  251. #define UNREACHABLE() \
  252. DIE ("unreachable")
  253. #define _LOG(level, ...) \
  254. do { \
  255. if (SCM_UNLIKELY (jit_log_level >= level)) \
  256. fprintf (stderr, "jit: " __VA_ARGS__); \
  257. } while (0)
  258. enum {
  259. LOG_LEVEL_NONE,
  260. LOG_LEVEL_INFO,
  261. LOG_LEVEL_DEBUG,
  262. LOG_LEVEL_LOG
  263. };
  264. #define INFO(...) _LOG(LOG_LEVEL_INFO, __VA_ARGS__)
  265. #define DEBUG(...) _LOG(LOG_LEVEL_DEBUG, __VA_ARGS__)
  266. #define LOG(...) _LOG(LOG_LEVEL_LOG, __VA_ARGS__)
  267. static void
  268. reset_register_state (scm_jit_state *j, uint32_t state)
  269. {
  270. j->register_state = state;
  271. }
  272. static void
  273. clear_register_state (scm_jit_state *j, uint32_t state)
  274. {
  275. j->register_state &= ~state;
  276. }
  277. static void
  278. clear_scratch_register_state (scm_jit_state *j)
  279. {
  280. reset_register_state (j, 0);
  281. }
  282. static void
  283. set_register_state (scm_jit_state *j, uint32_t state)
  284. {
  285. j->register_state |= state;
  286. }
  287. static uint32_t
  288. unreachable (scm_jit_state *j)
  289. {
  290. return j->register_state & UNREACHABLE;
  291. }
  292. static uint32_t
  293. has_register_state (scm_jit_state *j, uint32_t state)
  294. {
  295. return (j->register_state & state) == state;
  296. }
  297. #define ASSERT_HAS_REGISTER_STATE(state) \
  298. ASSERT (unreachable (j) || has_register_state (j, state));
  299. static void
  300. record_gpr_clobber (scm_jit_state *j, jit_gpr_t r)
  301. {
  302. if (jit_same_gprs (j->sp_cache_gpr, r))
  303. clear_register_state (j, SP_CACHE_GPR);
  304. if (jit_same_gprs (r, SP))
  305. clear_register_state (j, SP_IN_REGISTER);
  306. else if (jit_same_gprs (r, FP))
  307. clear_register_state (j, FP_IN_REGISTER);
  308. }
  309. static void
  310. record_fpr_clobber (scm_jit_state *j, jit_fpr_t r)
  311. {
  312. if (jit_same_fprs (j->sp_cache_fpr, r))
  313. clear_register_state (j, SP_CACHE_FPR);
  314. }
  315. static void
  316. set_sp_cache_gpr (scm_jit_state *j, uint32_t idx, jit_gpr_t r)
  317. {
  318. set_register_state (j, SP_CACHE_GPR);
  319. j->sp_cache_gpr_idx = idx;
  320. if (j->sp_cache_fpr_idx == idx)
  321. clear_register_state (j, SP_CACHE_FPR);
  322. }
  323. static void
  324. set_sp_cache_fpr (scm_jit_state *j, uint32_t idx, jit_fpr_t r)
  325. {
  326. set_register_state (j, SP_CACHE_FPR);
  327. j->sp_cache_fpr_idx = idx;
  328. if (j->sp_cache_gpr_idx == idx)
  329. clear_register_state (j, SP_CACHE_GPR);
  330. }
  331. static inline ptrdiff_t
  332. inline_label_offset (uint32_t vcode_offset)
  333. {
  334. return vcode_offset * 2;
  335. }
  336. static inline ptrdiff_t
  337. slow_label_offset (uint32_t vcode_offset)
  338. {
  339. return vcode_offset * 2 + 1;
  340. }
  341. /* Q: When should I use emit_retval instead of jit_retval? When to use
  342. emit_movi, emit_ldxi?
  343. A: Generally you should use the emit_ variants instead of the jit_
  344. variants. Guile's JIT compiler has a primitive form of local
  345. (intrablock) register allocation that records recent stores. A
  346. subsequent load might be able to replace a register read instead of a
  347. memory load. This simple allocator works for straight-line code, and
  348. it works as long as register writes are recorded. The JIT itself
  349. will clear the register allocator state at control-flow joins, but
  350. control flow within an instruction needs to be careful.
  351. It's OK to use the jit_emit, jit_retval etc primitives if you
  352. manually make corresponding changes to the register_state, perhaps by
  353. inserting record_gpr_clobber calls. If the register is later
  354. clobbered by e.g. emit_sp_set_scm, sometimes those can be omitted
  355. though. Also, if your instruction includes a call, that code will
  356. invalidate any cached register-stack-index associations, so if
  357. there's a call, maybe you can avoid calling emit_*.
  358. Note of course that an association between registers and
  359. stack-indexed locals is also invalidated if the stack frame expands
  360. via alloc-frame or push, or shrinks via reset-frame, pop, drop,
  361. etc. */
  362. static void
  363. emit_retval (scm_jit_state *j, jit_gpr_t r)
  364. {
  365. jit_retval (j->jit, r);
  366. record_gpr_clobber (j, r);
  367. }
  368. static void
  369. emit_retval_d (scm_jit_state *j, jit_fpr_t r)
  370. {
  371. jit_retval_d (j->jit, r);
  372. record_fpr_clobber (j, r);
  373. }
  374. static void
  375. emit_movi (scm_jit_state *j, jit_gpr_t r, jit_word_t i)
  376. {
  377. jit_movi (j->jit, r, i);
  378. record_gpr_clobber (j, r);
  379. }
  380. static jit_reloc_t
  381. emit_mov_addr (scm_jit_state *j, jit_gpr_t r)
  382. {
  383. record_gpr_clobber (j, r);
  384. return jit_mov_addr (j->jit, r);
  385. }
  386. static void
  387. emit_ldxi (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t src, jit_word_t offset)
  388. {
  389. if (offset == 0)
  390. jit_ldr (j->jit, dst, src);
  391. else
  392. jit_ldxi (j->jit, dst, src, offset);
  393. record_gpr_clobber (j, dst);
  394. }
  395. #define DEFINE_CLOBBER_RECORDING_EMITTER_R(stem, typ) \
  396. static void \
  397. emit_##stem (scm_jit_state *j, jit_##typ##_t dst, jit_##typ##_t a) \
  398. { \
  399. jit_##stem (j->jit, dst, a); \
  400. record_##typ##_clobber (j, dst); \
  401. }
  402. #define DEFINE_CLOBBER_RECORDING_EMITTER_P(stem, typ) \
  403. static void \
  404. emit_##stem (scm_jit_state *j, jit_##typ##_t dst, jit_pointer_t a) \
  405. { \
  406. jit_##stem (j->jit, dst, a); \
  407. record_##typ##_clobber (j, dst); \
  408. }
  409. #define DEFINE_CLOBBER_RECORDING_EMITTER_R_I(stem, typ) \
  410. static void \
  411. emit_##stem (scm_jit_state *j, jit_##typ##_t dst, \
  412. jit_##typ##_t a, jit_word_t b) \
  413. { \
  414. jit_##stem (j->jit, dst, a, b); \
  415. record_##typ##_clobber (j, dst); \
  416. }
  417. #define DEFINE_CLOBBER_RECORDING_EMITTER_R_R(stem, typ) \
  418. static void \
  419. emit_##stem (scm_jit_state *j, jit_##typ##_t dst, \
  420. jit_##typ##_t a, jit_##typ##_t b) \
  421. { \
  422. jit_##stem (j->jit, dst, a, b); \
  423. record_##typ##_clobber (j, dst); \
  424. }
  425. #define DEFINE_CLOBBER_RECORDING_EMITTER_R_R_2(stem, typ) \
  426. static void \
  427. emit_##stem (scm_jit_state *j, \
  428. jit_##typ##_t dst1, jit_##typ##_t dst2, \
  429. jit_##typ##_t a, jit_##typ##_t b) \
  430. { \
  431. jit_##stem (j->jit, dst1, dst2, a, b); \
  432. record_##typ##_clobber (j, dst1); \
  433. record_##typ##_clobber (j, dst2); \
  434. }
  435. DEFINE_CLOBBER_RECORDING_EMITTER_R(ldr, gpr)
  436. DEFINE_CLOBBER_RECORDING_EMITTER_P(ldi, gpr)
  437. DEFINE_CLOBBER_RECORDING_EMITTER_R(comr, gpr)
  438. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(ldxr, gpr)
  439. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(addi, gpr)
  440. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(addr, gpr)
  441. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(addr_d, fpr)
  442. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(subi, gpr)
  443. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(subr, gpr)
  444. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(subr_d, fpr)
  445. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(muli, gpr)
  446. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(mulr, gpr)
  447. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(mulr_d, fpr)
  448. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(divr_d, fpr)
  449. DEFINE_CLOBBER_RECORDING_EMITTER_R(absr_d, fpr)
  450. DEFINE_CLOBBER_RECORDING_EMITTER_R(sqrtr_d, fpr)
  451. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(andi, gpr)
  452. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(andr, gpr)
  453. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(orr, gpr)
  454. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(xorr, gpr)
  455. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(rshi, gpr)
  456. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(rshi_u, gpr)
  457. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(rshr, gpr)
  458. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(rshr_u, gpr)
  459. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(lshi, gpr)
  460. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(lshr, gpr)
  461. #if SIZEOF_UINTPTR_T < 8
  462. DEFINE_CLOBBER_RECORDING_EMITTER_R(movr, gpr)
  463. DEFINE_CLOBBER_RECORDING_EMITTER_R(negr, gpr)
  464. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(addci, gpr)
  465. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(addcr, gpr)
  466. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(addxi, gpr)
  467. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(addxr, gpr)
  468. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(subci, gpr)
  469. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(subcr, gpr)
  470. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(subxi, gpr)
  471. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(subxr, gpr)
  472. DEFINE_CLOBBER_RECORDING_EMITTER_R_R_2(qmulr_u, gpr)
  473. #endif
  474. static void
  475. emit_reload_sp (scm_jit_state *j)
  476. {
  477. emit_ldxi (j, SP, THREAD, thread_offset_sp);
  478. set_register_state (j, SP_IN_REGISTER);
  479. }
  480. static void
  481. emit_store_sp (scm_jit_state *j)
  482. {
  483. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  484. jit_stxi (j->jit, thread_offset_sp, THREAD, SP);
  485. }
  486. static void
  487. emit_reload_fp (scm_jit_state *j)
  488. {
  489. emit_ldxi (j, FP, THREAD, thread_offset_fp);
  490. set_register_state (j, FP_IN_REGISTER);
  491. }
  492. static void
  493. emit_store_fp (scm_jit_state *j)
  494. {
  495. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  496. jit_stxi (j->jit, thread_offset_fp, THREAD, FP);
  497. }
  498. static uint32_t
  499. save_reloadable_register_state (scm_jit_state *j)
  500. {
  501. return j->register_state & (SP_IN_REGISTER | FP_IN_REGISTER);
  502. }
  503. static void
  504. restore_reloadable_register_state (scm_jit_state *j, uint32_t state)
  505. {
  506. if ((state & SP_IN_REGISTER) && !has_register_state (j, SP_IN_REGISTER))
  507. emit_reload_sp (j);
  508. if ((state & FP_IN_REGISTER) && !has_register_state (j, FP_IN_REGISTER))
  509. emit_reload_fp (j);
  510. }
  511. static void
  512. emit_subtract_stack_slots (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t src,
  513. uint32_t n)
  514. {
  515. emit_subi (j, dst, src, n * sizeof (union scm_vm_stack_element));
  516. }
  517. static void
  518. emit_load_mra (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t fp)
  519. {
  520. emit_ldxi (j, dst, fp, frame_offset_mra);
  521. }
  522. static void
  523. emit_store_mra (scm_jit_state *j, jit_gpr_t fp, jit_gpr_t mra)
  524. {
  525. ASSERT (frame_offset_mra == 0);
  526. jit_str (j->jit, fp, mra);
  527. }
  528. static void
  529. emit_load_vra (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t fp)
  530. {
  531. emit_ldxi (j, dst, fp, frame_offset_vra);
  532. }
  533. static void
  534. emit_store_vra (scm_jit_state *j, jit_gpr_t fp, jit_gpr_t t, const uint32_t *vra)
  535. {
  536. emit_movi (j, t, (intptr_t) vra);
  537. jit_stxi (j->jit, frame_offset_vra, fp, t);
  538. }
  539. static void
  540. emit_load_prev_fp_offset (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t fp)
  541. {
  542. emit_ldxi (j, dst, fp, frame_offset_prev);
  543. }
  544. static void
  545. emit_store_prev_fp_offset (scm_jit_state *j, jit_gpr_t fp, jit_gpr_t t,
  546. uint32_t n)
  547. {
  548. emit_movi (j, t, n);
  549. jit_stxi (j->jit, frame_offset_prev, fp, t);
  550. }
  551. static void
  552. emit_store_ip (scm_jit_state *j, jit_gpr_t ip)
  553. {
  554. jit_stxi (j->jit, thread_offset_ip, THREAD, ip);
  555. }
  556. static void
  557. emit_store_current_ip (scm_jit_state *j, jit_gpr_t t)
  558. {
  559. emit_movi (j, t, (intptr_t) j->ip);
  560. emit_store_ip (j, t);
  561. }
  562. static void
  563. emit_pop_fp (scm_jit_state *j, jit_gpr_t old_fp)
  564. {
  565. emit_ldxi (j, old_fp, THREAD, thread_offset_fp);
  566. emit_load_prev_fp_offset (j, FP, old_fp);
  567. emit_lshi (j, FP, FP, 3); /* Multiply by sizeof (scm_vm_stack_element) */
  568. emit_addr (j, FP, old_fp, FP);
  569. set_register_state (j, FP_IN_REGISTER);
  570. emit_store_fp (j);
  571. }
  572. static void
  573. emit_reset_frame (scm_jit_state *j, uint32_t nlocals)
  574. {
  575. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  576. emit_subtract_stack_slots (j, SP, FP, nlocals);
  577. set_register_state (j, SP_IN_REGISTER);
  578. emit_store_sp (j);
  579. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  580. }
  581. static jit_operand_t
  582. thread_operand (void)
  583. {
  584. return jit_operand_gpr (JIT_OPERAND_ABI_POINTER, THREAD);
  585. }
  586. static void
  587. emit_call_0 (scm_jit_state *j, void *f)
  588. {
  589. jit_calli_0 (j->jit, f);
  590. clear_scratch_register_state (j);
  591. }
  592. static void
  593. emit_call_1 (scm_jit_state *j, void *f, jit_operand_t a)
  594. {
  595. jit_calli_1 (j->jit, f, a);
  596. clear_scratch_register_state (j);
  597. }
  598. static void
  599. emit_call_2 (scm_jit_state *j, void *f, jit_operand_t a, jit_operand_t b)
  600. {
  601. jit_calli_2 (j->jit, f, a, b);
  602. clear_scratch_register_state (j);
  603. }
  604. static void
  605. emit_call_3 (scm_jit_state *j, void *f, jit_operand_t a, jit_operand_t b,
  606. jit_operand_t c)
  607. {
  608. jit_calli_3 (j->jit, f, a, b, c);
  609. clear_scratch_register_state (j);
  610. }
  611. static jit_reloc_t
  612. emit_alloc_frame_for_sp_fast (scm_jit_state *j, jit_gpr_t t)
  613. {
  614. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  615. emit_ldxi (j, t, THREAD, thread_offset_stack_limit);
  616. jit_reloc_t slow = jit_bltr (j->jit, SP, t);
  617. emit_store_sp (j);
  618. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  619. return slow;
  620. }
  621. static void
  622. emit_alloc_frame_for_sp_slow (scm_jit_state *j, jit_gpr_t t)
  623. {
  624. /* Slow case: call out to expand stack. */
  625. emit_store_current_ip (j, t);
  626. emit_call_2 (j, scm_vm_intrinsics.expand_stack, thread_operand (),
  627. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, SP));
  628. restore_reloadable_register_state (j, SP_IN_REGISTER | FP_IN_REGISTER);
  629. }
  630. static void
  631. emit_alloc_frame (scm_jit_state *j, jit_gpr_t t, uint32_t nlocals)
  632. {
  633. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  634. emit_subtract_stack_slots (j, SP, FP, nlocals);
  635. set_register_state (j, SP_IN_REGISTER);
  636. jit_reloc_t slow = emit_alloc_frame_for_sp_fast (j, t);
  637. jit_reloc_t k = jit_jmp (j->jit);
  638. jit_patch_here (j->jit, slow);
  639. emit_alloc_frame_for_sp_slow (j, t);
  640. jit_patch_here (j->jit, k);
  641. }
  642. static void
  643. emit_get_callee_vcode (scm_jit_state *j, jit_gpr_t dst)
  644. {
  645. emit_call_1 (j, scm_vm_intrinsics.get_callee_vcode, thread_operand ());
  646. emit_retval (j, dst);
  647. emit_reload_sp (j);
  648. emit_reload_fp (j);
  649. }
  650. static void
  651. emit_get_ip_relative_addr (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t ip,
  652. uint32_t offset)
  653. {
  654. uint32_t byte_offset = offset * sizeof (uint32_t);
  655. jit_ldxi_i (j->jit, dst, ip, byte_offset);
  656. record_gpr_clobber (j, dst);
  657. emit_lshi (j, dst, dst, 2); /* Multiply by sizeof (uint32_t) */
  658. emit_addr (j, dst, dst, ip);
  659. }
  660. static void
  661. emit_exit (scm_jit_state *j)
  662. {
  663. jit_jmpi (j->jit, exit_mcode);
  664. }
  665. static void
  666. emit_push_frame (scm_jit_state *j, uint32_t proc_slot, uint32_t nlocals,
  667. const uint32_t *vra)
  668. {
  669. jit_gpr_t t = T0;
  670. emit_reload_fp (j);
  671. emit_subtract_stack_slots (j, FP, FP, proc_slot);
  672. set_register_state (j, FP_IN_REGISTER);
  673. emit_store_vra (j, FP, t, vra);
  674. emit_store_prev_fp_offset (j, FP, t, proc_slot);
  675. emit_store_fp (j);
  676. emit_reset_frame (j, nlocals);
  677. }
  678. static void
  679. emit_indirect_tail_call (scm_jit_state *j)
  680. {
  681. emit_get_callee_vcode (j, T0);
  682. emit_get_ip_relative_addr (j, T1, T0, 1);
  683. emit_ldxi (j, T1, T1, 0);
  684. jit_reloc_t no_mcode = jit_beqi (j->jit, T1, 0);
  685. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER | SP_IN_REGISTER);
  686. jit_jmpr (j->jit, T1);
  687. jit_patch_here (j->jit, no_mcode);
  688. emit_store_ip (j, T0);
  689. emit_exit (j);
  690. }
  691. static void
  692. emit_direct_tail_call (scm_jit_state *j, const uint32_t *vcode)
  693. {
  694. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER | SP_IN_REGISTER);
  695. ASSERT ((vcode[0] & 0xff) == scm_op_instrument_entry);
  696. if (vcode == j->start)
  697. {
  698. uint8_t *mcode = j->labels[inline_label_offset (0)];
  699. ASSERT (mcode);
  700. jit_jmpi (j->jit, mcode);
  701. }
  702. else
  703. {
  704. struct scm_jit_function_data *data;
  705. data = (struct scm_jit_function_data *) (vcode + (int32_t)(vcode[1]));
  706. if (data->mcode)
  707. {
  708. /* FIXME: Jump indirectly, to allow mcode to be changed
  709. (e.g. to add/remove breakpoints or hooks). */
  710. jit_jmpi (j->jit, data->mcode);
  711. }
  712. else
  713. {
  714. jit_reloc_t no_mcode;
  715. /* No need to track clobbers. */
  716. jit_ldi (j->jit, T0, &data->mcode);
  717. no_mcode = jit_beqi (j->jit, T0, 0);
  718. jit_jmpr (j->jit, T0);
  719. jit_patch_here (j->jit, no_mcode);
  720. jit_movi (j->jit, T0, (intptr_t) vcode);
  721. emit_store_ip (j, T0);
  722. emit_exit (j);
  723. }
  724. }
  725. }
  726. static jit_operand_t
  727. fp_scm_operand (scm_jit_state *j, uint32_t slot) SCM_UNUSED;
  728. static jit_operand_t
  729. fp_scm_operand (scm_jit_state *j, uint32_t slot)
  730. {
  731. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  732. return jit_operand_mem (JIT_OPERAND_ABI_POINTER, FP,
  733. -8 * ((ptrdiff_t) slot + 1));
  734. }
  735. static void
  736. emit_fp_ref_scm (scm_jit_state *j, jit_gpr_t dst, uint32_t slot)
  737. {
  738. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  739. emit_ldxi (j, dst, FP, -8 * ((ptrdiff_t) slot + 1));
  740. }
  741. static void
  742. emit_fp_set_scm (scm_jit_state *j, uint32_t slot, jit_gpr_t val)
  743. {
  744. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  745. jit_stxi (j->jit, -8 * ((ptrdiff_t) slot + 1), FP, val);
  746. clear_register_state (j, SP_CACHE_GPR);
  747. }
  748. static jit_operand_t
  749. sp_slot_operand (scm_jit_state *j, uint32_t slot) SCM_UNUSED;
  750. static jit_operand_t
  751. sp_slot_operand (scm_jit_state *j, uint32_t slot)
  752. {
  753. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  754. return jit_operand_addi (jit_operand_gpr (JIT_OPERAND_ABI_POINTER, SP),
  755. 8 * slot);
  756. }
  757. static jit_operand_t
  758. sp_scm_operand (scm_jit_state *j, uint32_t slot)
  759. {
  760. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  761. return jit_operand_mem (JIT_OPERAND_ABI_POINTER, SP, 8 * slot);
  762. }
  763. static void
  764. emit_sp_ref_scm (scm_jit_state *j, jit_gpr_t dst, uint32_t slot)
  765. {
  766. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  767. emit_ldxi (j, dst, SP, 8 * slot);
  768. }
  769. static void
  770. emit_sp_set_scm (scm_jit_state *j, uint32_t slot, jit_gpr_t val)
  771. {
  772. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  773. if (slot == 0)
  774. jit_str (j->jit, SP, val);
  775. else
  776. jit_stxi (j->jit, 8 * slot, SP, val);
  777. set_sp_cache_gpr (j, slot, val);
  778. }
  779. /* Use when you know that the u64 value will be within the size_t range,
  780. for example when it's ensured by the compiler. */
  781. static jit_operand_t
  782. sp_sz_operand (scm_jit_state *j, uint32_t src)
  783. {
  784. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  785. enum jit_operand_abi abi =
  786. sizeof (size_t) == 4 ? JIT_OPERAND_ABI_UINT32 : JIT_OPERAND_ABI_UINT64;
  787. if (BIGENDIAN && sizeof (size_t) == 4)
  788. return jit_operand_mem (abi, SP, src * 8 + 4);
  789. else
  790. return jit_operand_mem (abi, SP, src * 8);
  791. }
  792. static void
  793. emit_sp_ref_sz (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  794. {
  795. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  796. if (BIGENDIAN && sizeof (size_t) == 4)
  797. emit_ldxi (j, dst, SP, src * 8 + 4);
  798. else
  799. emit_ldxi (j, dst, SP, src * 8);
  800. }
  801. static void
  802. emit_sp_set_sz (scm_jit_state *j, uint32_t dst, jit_gpr_t src)
  803. {
  804. size_t offset = dst * 8;
  805. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  806. if (sizeof (size_t) == 4)
  807. {
  808. size_t lo, hi;
  809. if (BIGENDIAN)
  810. lo = offset + 4, hi = offset;
  811. else
  812. lo = offset, hi = offset + 4;
  813. jit_stxi (j->jit, lo, SP, src);
  814. /* Set high word to 0. Clobber src. */
  815. emit_xorr (j, src, src, src);
  816. jit_stxi (j->jit, hi, SP, src);
  817. }
  818. else
  819. {
  820. jit_stxi (j->jit, offset, SP, src);
  821. set_sp_cache_gpr (j, dst, src);
  822. }
  823. }
  824. static jit_operand_t
  825. sp_u64_operand (scm_jit_state *j, uint32_t slot)
  826. {
  827. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  828. return jit_operand_mem (JIT_OPERAND_ABI_UINT64, SP, 8 * slot);
  829. }
  830. #if SIZEOF_UINTPTR_T >= 8
  831. static void
  832. emit_sp_ref_u64 (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  833. {
  834. size_t offset = src * 8;
  835. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  836. emit_ldxi (j, dst, SP, offset);
  837. }
  838. static void
  839. emit_sp_set_u64 (scm_jit_state *j, uint32_t dst, jit_gpr_t src)
  840. {
  841. size_t offset = dst * 8;
  842. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  843. if (dst == 0)
  844. jit_str (j->jit, SP, src);
  845. else
  846. jit_stxi (j->jit, offset, SP, src);
  847. set_sp_cache_gpr (j, dst, src);
  848. }
  849. static void
  850. emit_sp_ref_s64 (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  851. {
  852. emit_sp_ref_u64 (j, dst, src);
  853. }
  854. static void
  855. emit_sp_set_s64 (scm_jit_state *j, uint32_t dst, jit_gpr_t src)
  856. {
  857. emit_sp_set_u64 (j, dst, src);
  858. }
  859. static void
  860. emit_sp_ref_ptr (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  861. {
  862. emit_sp_ref_u64 (j, dst, src);
  863. }
  864. #else /* SCM_SIZEOF_UINTPTR_T >= 8 */
  865. static jit_operand_t
  866. sp_s32_operand (scm_jit_state *j, uint32_t src)
  867. {
  868. return sp_sz_operand (j, src);
  869. }
  870. static void
  871. emit_sp_ref_s32 (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  872. {
  873. emit_sp_ref_sz (j, dst, src);
  874. }
  875. static void
  876. emit_sp_ref_u64 (scm_jit_state *j, jit_gpr_t dst_lo, jit_gpr_t dst_hi,
  877. uint32_t src)
  878. {
  879. size_t offset = src * 8;
  880. jit_gpr_t first, second;
  881. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  882. #if BIGENDIAN
  883. first = dst_hi, second = dst_lo;
  884. #else
  885. first = dst_lo, second = dst_hi;
  886. #endif
  887. emit_ldxi (j, first, SP, offset);
  888. emit_ldxi (j, second, SP, offset + 4);
  889. }
  890. static void
  891. emit_sp_set_u64 (scm_jit_state *j, uint32_t dst, jit_gpr_t lo, jit_gpr_t hi)
  892. {
  893. size_t offset = dst * 8;
  894. jit_gpr_t first, second;
  895. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  896. #if BIGENDIAN
  897. first = hi, second = lo;
  898. #else
  899. first = lo, second = hi;
  900. #endif
  901. if (offset == 0)
  902. jit_str (j->jit, SP, first);
  903. else
  904. jit_stxi (j->jit, offset, SP, first);
  905. jit_stxi (j->jit, offset + 4, SP, second);
  906. clear_register_state (j, SP_CACHE_GPR);
  907. }
  908. static void
  909. emit_sp_ref_s64 (scm_jit_state *j, jit_gpr_t dst_lo, jit_gpr_t dst_hi,
  910. uint32_t src)
  911. {
  912. emit_sp_ref_u64 (j, dst_lo, dst_hi, src);
  913. }
  914. static void
  915. emit_sp_set_s64 (scm_jit_state *j, uint32_t dst, jit_gpr_t lo, jit_gpr_t hi)
  916. {
  917. emit_sp_set_u64 (j, dst, lo, hi);
  918. }
  919. static void
  920. emit_sp_ref_u64_lower_half (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  921. {
  922. size_t offset = src * 8;
  923. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  924. emit_ldxi (j, dst, SP, offset);
  925. }
  926. static void
  927. emit_sp_ref_ptr (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  928. {
  929. emit_sp_ref_u64_lower_half (j, dst, src);
  930. }
  931. #endif /* SCM_SIZEOF_UINTPTR_T >= 8 */
  932. static jit_operand_t
  933. sp_f64_operand (scm_jit_state *j, uint32_t slot)
  934. {
  935. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  936. return jit_operand_mem (JIT_OPERAND_ABI_DOUBLE, SP, 8 * slot);
  937. }
  938. static void
  939. emit_sp_ref_f64 (scm_jit_state *j, jit_fpr_t dst, uint32_t src)
  940. {
  941. size_t offset = src * 8;
  942. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  943. if (offset == 0)
  944. jit_ldr_d (j->jit, dst, SP);
  945. else
  946. jit_ldxi_d (j->jit, dst, SP, offset);
  947. record_fpr_clobber (j, dst);
  948. }
  949. static void
  950. emit_sp_set_f64 (scm_jit_state *j, uint32_t dst, jit_fpr_t src)
  951. {
  952. size_t offset = dst * 8;
  953. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  954. if (offset == 0)
  955. jit_str_d (j->jit, SP, src);
  956. else
  957. jit_stxi_d (j->jit, offset, SP, src);
  958. set_sp_cache_fpr (j, dst, src);
  959. }
  960. static void
  961. emit_mov (scm_jit_state *j, uint32_t dst, uint32_t src, jit_gpr_t t)
  962. {
  963. emit_sp_ref_scm (j, t, src);
  964. emit_sp_set_scm (j, dst, t);
  965. /* FIXME: The compiler currently emits "push", "mov", etc for SCM,
  966. F64, U64, and S64 variables. However SCM values are the usual
  967. case, and on a 32-bit machine it might be cheaper to move a SCM
  968. than to move a 64-bit number. */
  969. if (sizeof (void*) < sizeof (union scm_vm_stack_element))
  970. {
  971. /* Copy the high word as well. */
  972. uintptr_t src_offset = src * sizeof (union scm_vm_stack_element);
  973. uintptr_t dst_offset = dst * sizeof (union scm_vm_stack_element);
  974. jit_ldxi (j->jit, t, SP, src_offset + sizeof (void*));
  975. jit_stxi (j->jit, dst_offset + sizeof (void*), SP, t);
  976. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  977. }
  978. else
  979. /* In any case since we move the register using GPRs, it won't be in
  980. a cached FPR. */
  981. clear_register_state (j, SP_CACHE_FPR);
  982. }
  983. static jit_reloc_t
  984. emit_branch_if_frame_locals_count_less_than (scm_jit_state *j, jit_gpr_t t,
  985. uint32_t nlocals)
  986. {
  987. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  988. emit_subr (j, t, FP, SP);
  989. return jit_blti (j->jit, t, nlocals * sizeof (union scm_vm_stack_element));
  990. }
  991. static jit_reloc_t
  992. emit_branch_if_frame_locals_count_eq (scm_jit_state *j, jit_gpr_t t,
  993. uint32_t nlocals)
  994. {
  995. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  996. emit_subr (j, t, FP, SP);
  997. return jit_beqi (j->jit, t, nlocals * sizeof (union scm_vm_stack_element));
  998. }
  999. static jit_reloc_t
  1000. emit_branch_if_frame_locals_count_not_eq (scm_jit_state *j, jit_gpr_t t,
  1001. uint32_t nlocals)
  1002. {
  1003. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  1004. emit_subr (j, t, FP, SP);
  1005. return jit_bnei (j->jit, t, nlocals * sizeof (union scm_vm_stack_element));
  1006. }
  1007. static jit_reloc_t
  1008. emit_branch_if_frame_locals_count_greater_than (scm_jit_state *j, jit_gpr_t t,
  1009. uint32_t nlocals)
  1010. {
  1011. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  1012. emit_subr (j, t, FP, SP);
  1013. return jit_bgti (j->jit, t, nlocals * sizeof (union scm_vm_stack_element));
  1014. }
  1015. static void
  1016. emit_load_fp_slot (scm_jit_state *j, jit_gpr_t dst, uint32_t slot)
  1017. {
  1018. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  1019. emit_subi (j, dst, FP, (slot + 1) * sizeof (union scm_vm_stack_element));
  1020. }
  1021. static jit_reloc_t
  1022. emit_branch_if_immediate (scm_jit_state *j, jit_gpr_t r)
  1023. {
  1024. return jit_bmsi (j->jit, r, 6);
  1025. }
  1026. static void
  1027. emit_load_heap_object_word (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t r,
  1028. uint32_t word)
  1029. {
  1030. emit_ldxi (j, dst, r, word * sizeof(SCM));
  1031. }
  1032. static void
  1033. emit_load_heap_object_tc (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t r,
  1034. scm_t_bits mask)
  1035. {
  1036. emit_load_heap_object_word (j, dst, r, 0);
  1037. emit_andi (j, dst, dst, mask);
  1038. }
  1039. static jit_reloc_t
  1040. emit_branch_if_heap_object_has_tc (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
  1041. scm_t_bits mask, scm_t_bits tc)
  1042. {
  1043. emit_load_heap_object_tc (j, t, r, mask);
  1044. return jit_beqi (j->jit, t, tc);
  1045. }
  1046. static jit_reloc_t
  1047. emit_branch_if_heap_object_not_tc (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
  1048. scm_t_bits mask, scm_t_bits tc)
  1049. {
  1050. emit_load_heap_object_tc (j, t, r, mask);
  1051. return jit_bnei (j->jit, t, tc);
  1052. }
  1053. static jit_reloc_t
  1054. emit_branch_if_heap_object_has_tc7 (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
  1055. scm_t_bits tc7)
  1056. {
  1057. return emit_branch_if_heap_object_has_tc (j, r, t, 0x7f, tc7);
  1058. }
  1059. static jit_reloc_t
  1060. emit_branch_if_heap_object_not_tc7 (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
  1061. scm_t_bits tc7)
  1062. {
  1063. return emit_branch_if_heap_object_not_tc (j, r, t, 0x7f, tc7);
  1064. }
  1065. static void
  1066. emit_entry_trampoline (scm_jit_state *j)
  1067. {
  1068. size_t align = jit_enter_jit_abi(j->jit, 3, 0, 0);
  1069. /* Load our reserved registers: THREAD and SP. Also load IP for the
  1070. mcode jump. */
  1071. jit_load_args_2 (j->jit, thread_operand (),
  1072. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T0));
  1073. emit_reload_sp (j);
  1074. /* Load FP, set during call sequences. */
  1075. emit_reload_fp (j);
  1076. /* Jump to the mcode! */
  1077. jit_jmpr (j->jit, T0);
  1078. /* Initialize global exit_mcode to point here. */
  1079. exit_mcode = jit_address (j->jit);
  1080. jit_leave_jit_abi(j->jit, 3, 0, align);
  1081. /* When mcode finishes, interpreter will continue with vp->ip. */
  1082. jit_ret (j->jit);
  1083. }
  1084. static void
  1085. emit_handle_interrupts_trampoline (scm_jit_state *j)
  1086. {
  1087. /* Precondition: IP synced. */
  1088. jit_pop_link_register (j->jit);
  1089. emit_call_2 (j, scm_vm_intrinsics.push_interrupt_frame,
  1090. thread_operand (),
  1091. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_LR));
  1092. emit_reload_sp (j);
  1093. emit_reload_fp (j);
  1094. emit_direct_tail_call (j, scm_vm_intrinsics.handle_interrupt_code);
  1095. }
  1096. /* To limit the number of mmap calls and re-emission of JIT code, use
  1097. 256 kB code arenas. Unused pages won't be resident. Assume pages
  1098. are power-of-two-sized and this size is a multiple of the page size
  1099. on all architectures. */
  1100. static const size_t default_code_arena_size = 0x40000;
  1101. static struct code_arena *
  1102. allocate_code_arena (size_t size, struct code_arena *prev)
  1103. {
  1104. struct code_arena *ret = malloc (sizeof (struct code_arena));
  1105. if (!ret) return NULL;
  1106. memset (ret, 0, sizeof (*ret));
  1107. ret->used = 0;
  1108. ret->size = size;
  1109. ret->prev = prev;
  1110. ret->base = mmap (NULL, ret->size,
  1111. PROT_EXEC | PROT_READ | PROT_WRITE,
  1112. MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  1113. if (ret->base == MAP_FAILED)
  1114. {
  1115. perror ("allocating JIT code buffer failed");
  1116. free (ret);
  1117. return NULL;
  1118. }
  1119. INFO ("allocated code arena, %p-%p\n", ret->base, ret->base + ret->size);
  1120. return ret;
  1121. }
  1122. static void *
  1123. emit_code (scm_jit_state *j, void (*emit) (scm_jit_state *))
  1124. {
  1125. if (!j->code_arena)
  1126. j->code_arena = allocate_code_arena (default_code_arena_size, NULL);
  1127. if (!j->code_arena)
  1128. /* Resource exhaustion; turn off JIT. */
  1129. return NULL;
  1130. while (1)
  1131. {
  1132. struct code_arena *arena = j->code_arena;
  1133. jit_begin(j->jit, arena->base + arena->used, arena->size - arena->used);
  1134. uint8_t *ret = jit_address (j->jit);
  1135. emit (j);
  1136. size_t size;
  1137. if (!jit_has_overflow (j->jit) && jit_end (j->jit, &size))
  1138. {
  1139. ASSERT (size <= (arena->size - arena->used));
  1140. DEBUG ("mcode: %p,+%zu\n", ret, size);
  1141. arena->used += size;
  1142. /* Align next JIT to 16-byte boundaries to optimize initial
  1143. icache fetch. */
  1144. arena->used = (arena->used + 15) & ~15;
  1145. /* Assertion should not be invalidated as arena size is a
  1146. multiple of 16. */
  1147. ASSERT (arena->used <= arena->size);
  1148. return ret;
  1149. }
  1150. else
  1151. {
  1152. jit_reset (j->jit);
  1153. if (arena->used == 0)
  1154. {
  1155. /* Code too big to fit into empty arena; allocate a larger
  1156. one. */
  1157. INFO ("code didn't fit in empty arena of size %zu\n", arena->size);
  1158. arena = allocate_code_arena (arena->size * 2, arena->prev);
  1159. if (!arena)
  1160. return NULL;
  1161. munmap (j->code_arena->base, j->code_arena->size);
  1162. free (j->code_arena);
  1163. j->code_arena = arena;
  1164. }
  1165. else
  1166. {
  1167. /* Arena full; allocate another. */
  1168. /* FIXME: If partial code that we wrote crosses a page
  1169. boundary, we could tell the OS to forget about the tail
  1170. pages. */
  1171. INFO ("code didn't fit in arena tail %zu\n",
  1172. arena->size - arena->used);
  1173. arena = allocate_code_arena (arena->size, arena);
  1174. if (!arena)
  1175. return NULL;
  1176. j->code_arena = arena;
  1177. }
  1178. }
  1179. }
  1180. }
  1181. static jit_operand_t
  1182. free_variable_operand (scm_jit_state *j, jit_gpr_t src, size_t n)
  1183. {
  1184. ptrdiff_t offset = (n + program_word_offset_free_variable) * sizeof(SCM);
  1185. return jit_operand_mem (JIT_OPERAND_ABI_POINTER, src, offset);
  1186. }
  1187. static void
  1188. add_pending_reloc (scm_jit_state *j, jit_reloc_t reloc, ptrdiff_t offset)
  1189. {
  1190. if (j->reloc_idx >= j->reloc_count)
  1191. {
  1192. size_t count = j->reloc_count * 2;
  1193. if (!count) count = 10;
  1194. size_t size = sizeof(*j->relocs) * count;
  1195. ASSERT(size / sizeof(*j->relocs) == count);
  1196. struct pending_reloc *relocs = realloc (j->relocs, size);
  1197. if (relocs)
  1198. {
  1199. j->reloc_count = count;
  1200. j->relocs = relocs;
  1201. }
  1202. }
  1203. ASSERT (j->reloc_idx < j->reloc_count);
  1204. ASSERT (0 <= offset && offset < (j->end - j->start) * 2);
  1205. j->relocs[j->reloc_idx].reloc = reloc;
  1206. j->relocs[j->reloc_idx].target_label_offset = offset;
  1207. j->reloc_idx++;
  1208. }
  1209. static void
  1210. add_inter_instruction_patch (scm_jit_state *j, jit_reloc_t reloc,
  1211. const uint32_t *target)
  1212. {
  1213. ASSERT (j->start <= target && target < j->end);
  1214. ptrdiff_t offset = inline_label_offset (target - j->start);
  1215. if (j->labels[offset])
  1216. {
  1217. jit_patch_there (j->jit, reloc, j->labels[offset]);
  1218. return;
  1219. }
  1220. add_pending_reloc (j, reloc, offset);
  1221. }
  1222. static void
  1223. add_slow_path_patch (scm_jit_state *j, jit_reloc_t reloc)
  1224. {
  1225. ASSERT (j->start <= j->ip && j->ip < j->end);
  1226. ptrdiff_t offset = slow_label_offset (j->ip - j->start);
  1227. add_pending_reloc (j, reloc, offset);
  1228. }
  1229. static void
  1230. continue_after_slow_path (scm_jit_state *j, const uint32_t *target)
  1231. {
  1232. void *label = j->labels[inline_label_offset (target - j->start)];
  1233. ASSERT (label);
  1234. restore_reloadable_register_state (j, SP_IN_REGISTER | FP_IN_REGISTER);
  1235. jit_jmpi (j->jit, label);
  1236. }
  1237. static void
  1238. bad_instruction (scm_jit_state *j)
  1239. {
  1240. ASSERT (0);
  1241. }
  1242. static void
  1243. compile_halt (scm_jit_state *j)
  1244. {
  1245. bad_instruction (j);
  1246. }
  1247. static void
  1248. compile_halt_slow (scm_jit_state *j)
  1249. {
  1250. }
  1251. static void
  1252. compile_call (scm_jit_state *j, uint32_t proc, uint32_t nlocals)
  1253. {
  1254. jit_reloc_t push_frame = jit_jmp (j->jit);
  1255. void *trampoline = jit_address (j->jit);
  1256. reset_register_state (j, FP_IN_REGISTER | SP_IN_REGISTER);
  1257. jit_pop_link_register (j->jit);
  1258. emit_store_mra (j, FP, JIT_LR);
  1259. emit_indirect_tail_call (j);
  1260. jit_patch_here (j->jit, push_frame);
  1261. /* 2 = size of call inst */
  1262. emit_push_frame (j, proc, nlocals, j->ip + 2);
  1263. jit_jmpi_with_link (j->jit, trampoline);
  1264. reset_register_state (j, FP_IN_REGISTER | SP_IN_REGISTER);
  1265. j->frame_size_min = proc;
  1266. j->frame_size_max = INT32_MAX;
  1267. }
  1268. static void
  1269. compile_call_slow (scm_jit_state *j, uint32_t proc, uint32_t nlocals)
  1270. {
  1271. }
  1272. static void
  1273. compile_call_label (scm_jit_state *j, uint32_t proc, uint32_t nlocals, const uint32_t *vcode)
  1274. {
  1275. jit_reloc_t push_frame = jit_jmp (j->jit);
  1276. void *trampoline = jit_address (j->jit);
  1277. reset_register_state (j, FP_IN_REGISTER | SP_IN_REGISTER);
  1278. jit_pop_link_register (j->jit);
  1279. emit_store_mra (j, FP, JIT_LR);
  1280. emit_direct_tail_call (j, vcode);
  1281. jit_patch_here (j->jit, push_frame);
  1282. /* 3 = size of call-label inst */
  1283. emit_push_frame (j, proc, nlocals, j->ip + 3);
  1284. jit_jmpi_with_link (j->jit, trampoline);
  1285. reset_register_state (j, FP_IN_REGISTER | SP_IN_REGISTER);
  1286. j->frame_size_min = proc;
  1287. j->frame_size_max = INT32_MAX;
  1288. }
  1289. static void
  1290. compile_call_label_slow (scm_jit_state *j, uint32_t proc, uint32_t nlocals, const uint32_t *vcode)
  1291. {
  1292. }
  1293. static void
  1294. compile_tail_call (scm_jit_state *j)
  1295. {
  1296. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  1297. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1298. emit_indirect_tail_call (j);
  1299. j->frame_size_min = 0;
  1300. j->frame_size_max = INT32_MAX;
  1301. }
  1302. static void
  1303. compile_tail_call_slow (scm_jit_state *j)
  1304. {
  1305. }
  1306. static void
  1307. compile_tail_call_label (scm_jit_state *j, const uint32_t *vcode)
  1308. {
  1309. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  1310. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1311. emit_direct_tail_call (j, vcode);
  1312. j->frame_size_min = 0;
  1313. j->frame_size_max = INT32_MAX;
  1314. }
  1315. static void
  1316. compile_tail_call_label_slow (scm_jit_state *j, const uint32_t *vcode)
  1317. {
  1318. }
  1319. static void
  1320. compile_instrument_entry (scm_jit_state *j, void *data)
  1321. {
  1322. }
  1323. static void
  1324. compile_instrument_entry_slow (scm_jit_state *j, void *data)
  1325. {
  1326. }
  1327. static void
  1328. compile_instrument_loop (scm_jit_state *j, void *data)
  1329. {
  1330. /* Nothing to do. */
  1331. }
  1332. static void
  1333. compile_instrument_loop_slow (scm_jit_state *j, void *data)
  1334. {
  1335. }
  1336. static void
  1337. compile_receive (scm_jit_state *j, uint16_t dst, uint16_t proc, uint32_t nlocals)
  1338. {
  1339. jit_gpr_t t = T0;
  1340. add_slow_path_patch
  1341. (j, emit_branch_if_frame_locals_count_less_than (j, t, proc + 1));
  1342. emit_fp_ref_scm (j, t, proc);
  1343. emit_fp_set_scm (j, dst, t);
  1344. emit_reset_frame (j, nlocals);
  1345. j->frame_size_min = j->frame_size_max = nlocals;
  1346. }
  1347. static void
  1348. compile_receive_slow (scm_jit_state *j, uint16_t dst, uint16_t proc, uint32_t nlocals)
  1349. {
  1350. emit_store_current_ip (j, T0);
  1351. emit_call_0 (j, scm_vm_intrinsics.error_no_values);
  1352. }
  1353. static void
  1354. compile_receive_values (scm_jit_state *j, uint32_t proc, uint8_t allow_extra,
  1355. uint32_t nvalues)
  1356. {
  1357. jit_gpr_t t = T0;
  1358. /* Although most uses of receive-values are after a call returns, the
  1359. baseline compiler will sometimes emit it elsewhere. In that case
  1360. ensure that FP is in a register for the frame-locals-count
  1361. branches. */
  1362. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1363. if (allow_extra)
  1364. add_slow_path_patch
  1365. (j, emit_branch_if_frame_locals_count_less_than (j, t, proc + nvalues));
  1366. else
  1367. add_slow_path_patch
  1368. (j, emit_branch_if_frame_locals_count_not_eq (j, t, proc + nvalues));
  1369. j->frame_size_min = proc + nvalues;
  1370. j->frame_size_max = allow_extra ? INT32_MAX : j->frame_size_min;
  1371. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1372. }
  1373. static void
  1374. compile_receive_values_slow (scm_jit_state *j, uint32_t proc, uint8_t allow_extra,
  1375. uint32_t nvalues)
  1376. {
  1377. emit_store_current_ip (j, T0);
  1378. if (allow_extra)
  1379. emit_call_0 (j, scm_vm_intrinsics.error_not_enough_values);
  1380. else
  1381. emit_call_1 (j, scm_vm_intrinsics.error_wrong_number_of_values,
  1382. jit_operand_imm (JIT_OPERAND_ABI_UINT32, nvalues));
  1383. }
  1384. static void
  1385. compile_shuffle_down (scm_jit_state *j, uint16_t from, uint16_t to)
  1386. {
  1387. jit_gpr_t walk = T0, t = T1;
  1388. size_t offset = (from - to) * sizeof (union scm_vm_stack_element);
  1389. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  1390. emit_load_fp_slot (j, walk, from);
  1391. jit_reloc_t done = jit_bltr (j->jit, walk, SP);
  1392. void *head = jit_address (j->jit);
  1393. jit_ldr (j->jit, t, walk);
  1394. jit_stxi (j->jit, offset, walk, t);
  1395. jit_subi (j->jit, walk, walk, sizeof (union scm_vm_stack_element));
  1396. jit_patch_there (j->jit, jit_bger (j->jit, walk, SP), head);
  1397. jit_patch_here (j->jit, done);
  1398. jit_addi (j->jit, SP, SP, offset);
  1399. emit_store_sp (j);
  1400. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1401. j->frame_size_min -= (from - to);
  1402. if (j->frame_size_max != INT32_MAX)
  1403. j->frame_size_max -= (from - to);
  1404. }
  1405. static void
  1406. compile_shuffle_down_slow (scm_jit_state *j, uint16_t from, uint16_t to)
  1407. {
  1408. }
  1409. static void
  1410. compile_return_values (scm_jit_state *j)
  1411. {
  1412. emit_pop_fp (j, OLD_FP_FOR_RETURN_TRAMPOLINE);
  1413. emit_load_mra (j, JIT_LR, OLD_FP_FOR_RETURN_TRAMPOLINE);
  1414. jit_push_link_register (j->jit);
  1415. jit_ret (j->jit);
  1416. j->frame_size_min = 0;
  1417. j->frame_size_max = INT32_MAX;
  1418. }
  1419. static void
  1420. compile_return_values_slow (scm_jit_state *j)
  1421. {
  1422. }
  1423. static void
  1424. emit_return_to_interpreter_trampoline (scm_jit_state *j)
  1425. {
  1426. jit_gpr_t ra = T1;
  1427. emit_load_vra (j, ra, OLD_FP_FOR_RETURN_TRAMPOLINE);
  1428. emit_store_ip (j, ra);
  1429. emit_exit (j);
  1430. }
  1431. static void
  1432. compile_subr_call (scm_jit_state *j, uint32_t idx)
  1433. {
  1434. jit_gpr_t t = T0, ret = T1;
  1435. void *subr;
  1436. jit_reloc_t immediate;
  1437. jit_operand_t args[10];
  1438. ASSERT (j->frame_size_min == j->frame_size_max);
  1439. size_t argc = j->frame_size_max - 1;
  1440. ASSERT (argc <= 10);
  1441. subr = scm_subr_function_by_index (idx);
  1442. emit_store_current_ip (j, t);
  1443. for (size_t i = 2; i <= j->frame_size_max; i++)
  1444. args[i - 2] = sp_scm_operand (j, (j->frame_size_max - i));
  1445. jit_calli (j->jit, subr, argc, args);
  1446. clear_scratch_register_state (j);
  1447. jit_retval (j->jit, ret);
  1448. immediate = emit_branch_if_immediate (j, ret);
  1449. add_slow_path_patch
  1450. (j, emit_branch_if_heap_object_has_tc7 (j, ret, t, scm_tc7_values));
  1451. jit_patch_here (j->jit, immediate);
  1452. emit_reload_fp (j);
  1453. emit_subtract_stack_slots (j, SP, FP, 1);
  1454. set_register_state (j, SP_IN_REGISTER);
  1455. emit_store_sp (j);
  1456. jit_str (j->jit, SP, ret);
  1457. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1458. j->frame_size_min = 0;
  1459. j->frame_size_max = INT32_MAX;
  1460. }
  1461. static void
  1462. compile_subr_call_slow (scm_jit_state *j, uint32_t idx)
  1463. {
  1464. jit_gpr_t ret = T1;
  1465. emit_call_2 (j, scm_vm_intrinsics.unpack_values_object, thread_operand (),
  1466. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, ret));
  1467. continue_after_slow_path (j, j->next_ip);
  1468. }
  1469. static void
  1470. compile_foreign_call (scm_jit_state *j, uint16_t cif_idx, uint16_t ptr_idx)
  1471. {
  1472. uint32_t saved_state;
  1473. ASSERT (j->frame_size_min == j->frame_size_max);
  1474. emit_store_current_ip (j, T0);
  1475. emit_sp_ref_scm (j, T0, j->frame_size_min - 1);
  1476. /* FIXME: Inline the foreign call. */
  1477. saved_state = save_reloadable_register_state (j);
  1478. emit_call_3 (j, scm_vm_intrinsics.foreign_call, thread_operand (),
  1479. free_variable_operand (j, T0, cif_idx),
  1480. free_variable_operand (j, T0, ptr_idx));
  1481. restore_reloadable_register_state (j, saved_state);
  1482. j->frame_size_min = j->frame_size_max = 2; /* Return value and errno. */
  1483. }
  1484. static void
  1485. compile_foreign_call_slow (scm_jit_state *j, uint16_t cif_idx, uint16_t ptr_idx)
  1486. {
  1487. }
  1488. static void
  1489. compile_continuation_call (scm_jit_state *j, uint32_t contregs_idx)
  1490. {
  1491. emit_reload_fp (j);
  1492. emit_store_current_ip (j, T0);
  1493. emit_fp_ref_scm (j, T0, 0);
  1494. emit_call_2 (j, scm_vm_intrinsics.reinstate_continuation_x,
  1495. thread_operand (), free_variable_operand (j, T0, contregs_idx));
  1496. /* Does not fall through. */
  1497. j->frame_size_min = 0;
  1498. j->frame_size_max = INT32_MAX;
  1499. }
  1500. static void
  1501. compile_continuation_call_slow (scm_jit_state *j, uint32_t contregs_idx)
  1502. {
  1503. }
  1504. static void
  1505. compile_compose_continuation (scm_jit_state *j, uint32_t cont_idx)
  1506. {
  1507. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  1508. emit_store_current_ip (j, T0);
  1509. emit_fp_ref_scm (j, T0, 0);
  1510. emit_call_2 (j, scm_vm_intrinsics.compose_continuation,
  1511. thread_operand (), free_variable_operand (j, T0, cont_idx));
  1512. jit_retval (j->jit, T0);
  1513. add_slow_path_patch (j, jit_beqi (j->jit, T0, 0));
  1514. emit_reload_sp (j);
  1515. emit_reload_fp (j);
  1516. jit_jmpr (j->jit, T0);
  1517. j->frame_size_min = 0;
  1518. j->frame_size_max = INT32_MAX;
  1519. }
  1520. static void
  1521. compile_compose_continuation_slow (scm_jit_state *j, uint32_t cont_idx)
  1522. {
  1523. emit_exit (j);
  1524. }
  1525. static void
  1526. compile_capture_continuation (scm_jit_state *j, uint32_t dst)
  1527. {
  1528. emit_store_current_ip (j, T0);
  1529. emit_call_1 (j, scm_vm_intrinsics.capture_continuation, thread_operand ());
  1530. jit_retval (j->jit, T0);
  1531. emit_reload_sp (j);
  1532. emit_reload_fp (j);
  1533. emit_sp_set_scm (j, dst, T0);
  1534. }
  1535. static void
  1536. compile_capture_continuation_slow (scm_jit_state *j, uint32_t dst)
  1537. {
  1538. }
  1539. static void
  1540. compile_abort (scm_jit_state *j)
  1541. {
  1542. jit_movi (j->jit, T0, (intptr_t) (j->ip + 1));
  1543. emit_store_ip (j, T0);
  1544. jit_reloc_t k = jit_mov_addr (j->jit, T0);
  1545. emit_call_2 (j, scm_vm_intrinsics.abort_to_prompt, thread_operand (),
  1546. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T0));
  1547. jit_retval (j->jit, T1_PRESERVED);
  1548. add_slow_path_patch(j, jit_beqi (j->jit, T1_PRESERVED, 0));
  1549. emit_reload_sp (j);
  1550. emit_reload_fp (j);
  1551. jit_jmpr (j->jit, T1_PRESERVED);
  1552. jit_patch_here (j->jit, k);
  1553. j->frame_size_min = 0;
  1554. j->frame_size_max = INT32_MAX;
  1555. }
  1556. static void
  1557. compile_abort_slow (scm_jit_state *j)
  1558. {
  1559. emit_exit (j);
  1560. }
  1561. static void
  1562. compile_builtin_ref (scm_jit_state *j, uint16_t dst, uint16_t idx)
  1563. {
  1564. SCM builtin = scm_vm_builtin_ref (idx);
  1565. emit_movi (j, T0, SCM_UNPACK (builtin));
  1566. emit_sp_set_scm (j, dst, T0);
  1567. }
  1568. static void
  1569. compile_builtin_ref_slow (scm_jit_state *j, uint16_t dst, uint16_t idx)
  1570. {
  1571. }
  1572. static void
  1573. compile_throw (scm_jit_state *j, uint16_t key, uint16_t args)
  1574. {
  1575. emit_store_current_ip (j, T0);
  1576. emit_call_2 (j, scm_vm_intrinsics.throw_, sp_scm_operand (j, key),
  1577. sp_scm_operand (j, args));
  1578. /* throw_ does not return. */
  1579. set_register_state (j, UNREACHABLE);
  1580. }
  1581. static void
  1582. compile_throw_slow (scm_jit_state *j, uint16_t key, uint16_t args)
  1583. {
  1584. }
  1585. static void
  1586. compile_throw_value (scm_jit_state *j, uint32_t val,
  1587. const void *key_subr_and_message)
  1588. {
  1589. emit_store_current_ip (j, T0);
  1590. emit_call_2 (j, scm_vm_intrinsics.throw_with_value, sp_scm_operand (j, val),
  1591. jit_operand_imm (JIT_OPERAND_ABI_POINTER,
  1592. (intptr_t) key_subr_and_message));
  1593. /* Like throw_, throw_with_value does not return. */
  1594. set_register_state (j, UNREACHABLE);
  1595. }
  1596. static void
  1597. compile_throw_value_slow (scm_jit_state *j, uint32_t val,
  1598. const void *key_subr_and_message)
  1599. {
  1600. }
  1601. static void
  1602. compile_throw_value_and_data (scm_jit_state *j, uint32_t val,
  1603. const void *key_subr_and_message)
  1604. {
  1605. emit_store_current_ip (j, T0);
  1606. emit_call_2 (j, scm_vm_intrinsics.throw_with_value_and_data,
  1607. sp_scm_operand (j, val),
  1608. jit_operand_imm (JIT_OPERAND_ABI_POINTER,
  1609. (intptr_t) key_subr_and_message));
  1610. /* Like throw_, throw_with_value_and_data does not return. */
  1611. set_register_state (j, UNREACHABLE);
  1612. }
  1613. static void
  1614. compile_throw_value_and_data_slow (scm_jit_state *j, uint32_t val,
  1615. const void *key_subr_and_message)
  1616. {
  1617. }
  1618. static void
  1619. compile_assert_nargs_ee (scm_jit_state *j, uint32_t nlocals)
  1620. {
  1621. add_slow_path_patch
  1622. (j, emit_branch_if_frame_locals_count_not_eq (j, T0, nlocals));
  1623. j->frame_size_min = j->frame_size_max = nlocals;
  1624. }
  1625. static void
  1626. compile_assert_nargs_ee_slow (scm_jit_state *j, uint32_t nlocals)
  1627. {
  1628. emit_store_current_ip (j, T0);
  1629. emit_call_1 (j, scm_vm_intrinsics.error_wrong_num_args,
  1630. thread_operand ());
  1631. }
  1632. static void
  1633. compile_assert_nargs_ge (scm_jit_state *j, uint32_t nlocals)
  1634. {
  1635. if (nlocals > 0)
  1636. add_slow_path_patch
  1637. (j, emit_branch_if_frame_locals_count_less_than (j, T0, nlocals));
  1638. j->frame_size_min = nlocals;
  1639. }
  1640. static void
  1641. compile_assert_nargs_ge_slow (scm_jit_state *j, uint32_t nlocals)
  1642. {
  1643. emit_store_current_ip (j, T0);
  1644. emit_call_1 (j, scm_vm_intrinsics.error_wrong_num_args,
  1645. thread_operand ());
  1646. }
  1647. static void
  1648. compile_assert_nargs_le (scm_jit_state *j, uint32_t nlocals)
  1649. {
  1650. add_slow_path_patch
  1651. (j, emit_branch_if_frame_locals_count_greater_than (j, T0, nlocals));
  1652. j->frame_size_max = nlocals;
  1653. }
  1654. static void
  1655. compile_assert_nargs_le_slow (scm_jit_state *j, uint32_t nlocals)
  1656. {
  1657. emit_store_current_ip (j, T0);
  1658. emit_call_1 (j, scm_vm_intrinsics.error_wrong_num_args,
  1659. thread_operand ());
  1660. }
  1661. static void
  1662. compile_alloc_frame (scm_jit_state *j, uint32_t nlocals)
  1663. {
  1664. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  1665. emit_subtract_stack_slots (j, SP, FP, nlocals);
  1666. set_register_state (j, SP_IN_REGISTER);
  1667. add_slow_path_patch (j, emit_alloc_frame_for_sp_fast (j, T0));
  1668. j->frame_size_min = j->frame_size_max = nlocals;
  1669. }
  1670. static void
  1671. compile_alloc_frame_slow (scm_jit_state *j, uint32_t nlocals)
  1672. {
  1673. emit_alloc_frame_for_sp_slow (j, T0);
  1674. continue_after_slow_path (j, j->next_ip);
  1675. }
  1676. static void
  1677. compile_reset_frame (scm_jit_state *j, uint32_t nlocals)
  1678. {
  1679. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1680. emit_reset_frame (j, nlocals);
  1681. j->frame_size_min = j->frame_size_max = nlocals;
  1682. }
  1683. static void
  1684. compile_reset_frame_slow (scm_jit_state *j, uint32_t nlocals)
  1685. {
  1686. }
  1687. static void
  1688. compile_push (scm_jit_state *j, uint32_t src)
  1689. {
  1690. jit_gpr_t t = T0;
  1691. jit_subi (j->jit, SP, SP, sizeof (union scm_vm_stack_element));
  1692. add_slow_path_patch (j, emit_alloc_frame_for_sp_fast (j, t));
  1693. emit_mov (j, 0, src + 1, t);
  1694. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1695. j->frame_size_min++;
  1696. if (j->frame_size_max != INT32_MAX)
  1697. j->frame_size_max++;
  1698. }
  1699. static void
  1700. compile_push_slow (scm_jit_state *j, uint32_t src)
  1701. {
  1702. jit_gpr_t t = T0;
  1703. emit_alloc_frame_for_sp_slow (j, t);
  1704. emit_mov (j, 0, src + 1, t);
  1705. continue_after_slow_path (j, j->next_ip);
  1706. }
  1707. static void
  1708. compile_pop (scm_jit_state *j, uint32_t dst)
  1709. {
  1710. emit_mov (j, dst + 1, 0, T0);
  1711. jit_addi (j->jit, SP, SP, sizeof (union scm_vm_stack_element));
  1712. emit_store_sp (j);
  1713. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1714. j->frame_size_min--;
  1715. if (j->frame_size_max != INT32_MAX)
  1716. j->frame_size_max--;
  1717. }
  1718. static void
  1719. compile_pop_slow (scm_jit_state *j, uint32_t dst)
  1720. {
  1721. }
  1722. static void
  1723. compile_drop (scm_jit_state *j, uint32_t nvalues)
  1724. {
  1725. jit_addi (j->jit, SP, SP, nvalues * sizeof (union scm_vm_stack_element));
  1726. emit_store_sp (j);
  1727. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1728. j->frame_size_min -= nvalues;
  1729. if (j->frame_size_max != INT32_MAX)
  1730. j->frame_size_max -= nvalues;
  1731. }
  1732. static void
  1733. compile_drop_slow (scm_jit_state *j, uint32_t nvalues)
  1734. {
  1735. }
  1736. static void
  1737. compile_assert_nargs_ee_locals (scm_jit_state *j, uint16_t expected,
  1738. uint16_t nlocals)
  1739. {
  1740. jit_gpr_t t = T0;
  1741. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER | SP_IN_REGISTER);
  1742. if (nlocals)
  1743. {
  1744. emit_subtract_stack_slots (j, SP, SP, nlocals);
  1745. set_register_state (j, SP_IN_REGISTER);
  1746. }
  1747. add_slow_path_patch
  1748. (j, emit_branch_if_frame_locals_count_not_eq (j, t, expected + nlocals));
  1749. if (nlocals)
  1750. add_slow_path_patch (j, emit_alloc_frame_for_sp_fast (j, t));
  1751. j->frame_size_min = j->frame_size_max = expected + nlocals;
  1752. }
  1753. static void
  1754. compile_assert_nargs_ee_locals_slow (scm_jit_state *j, uint16_t expected,
  1755. uint16_t nlocals)
  1756. {
  1757. jit_gpr_t t = T0;
  1758. reset_register_state (j, SP_IN_REGISTER | FP_IN_REGISTER);
  1759. jit_reloc_t args_ok =
  1760. emit_branch_if_frame_locals_count_eq (j, t, expected + nlocals);
  1761. emit_store_current_ip (j, t);
  1762. emit_call_1 (j, scm_vm_intrinsics.error_wrong_num_args,
  1763. thread_operand ());
  1764. jit_patch_here (j->jit, args_ok);
  1765. if (nlocals)
  1766. emit_alloc_frame_for_sp_slow (j, t);
  1767. continue_after_slow_path (j, j->next_ip);
  1768. }
  1769. static void
  1770. compile_expand_apply_argument (scm_jit_state *j)
  1771. {
  1772. emit_store_current_ip (j, T0);
  1773. emit_call_1 (j, scm_vm_intrinsics.expand_apply_argument, thread_operand ());
  1774. emit_reload_sp (j);
  1775. emit_reload_fp (j);
  1776. j->frame_size_min--;
  1777. j->frame_size_max = INT32_MAX;
  1778. }
  1779. static void
  1780. compile_expand_apply_argument_slow (scm_jit_state *j)
  1781. {
  1782. }
  1783. static void
  1784. compile_bind_kwargs (scm_jit_state *j, uint32_t nreq, uint8_t flags,
  1785. uint32_t nreq_and_opt, uint32_t ntotal, const void *kw)
  1786. {
  1787. uint8_t allow_other_keys = flags & 0x1, has_rest = flags & 0x2;
  1788. jit_gpr_t t = T0, npositional = T1;
  1789. emit_store_current_ip (j, t);
  1790. emit_call_3 (j, scm_vm_intrinsics.compute_kwargs_npositional,
  1791. thread_operand (),
  1792. jit_operand_imm (JIT_OPERAND_ABI_UINT32, nreq),
  1793. jit_operand_imm (JIT_OPERAND_ABI_UINT32, nreq_and_opt - nreq));
  1794. jit_retval_i (j->jit, npositional);
  1795. jit_operand_t args[] =
  1796. { jit_operand_gpr (JIT_OPERAND_ABI_POINTER, THREAD),
  1797. jit_operand_gpr (JIT_OPERAND_ABI_UINT32, npositional),
  1798. jit_operand_imm (JIT_OPERAND_ABI_UINT32, ntotal),
  1799. jit_operand_imm (JIT_OPERAND_ABI_POINTER, (intptr_t)kw),
  1800. jit_operand_imm (JIT_OPERAND_ABI_UINT8, !has_rest),
  1801. jit_operand_imm (JIT_OPERAND_ABI_UINT8, allow_other_keys) };
  1802. jit_calli (j->jit, scm_vm_intrinsics.bind_kwargs, 6, args);
  1803. clear_scratch_register_state (j);
  1804. if (has_rest)
  1805. {
  1806. emit_call_2 (j, scm_vm_intrinsics.cons_rest, thread_operand (),
  1807. jit_operand_imm (JIT_OPERAND_ABI_UINT32, ntotal));
  1808. jit_retval (j->jit, t);
  1809. emit_reload_fp (j);
  1810. emit_fp_set_scm (j, nreq_and_opt, t);
  1811. }
  1812. else
  1813. emit_reload_fp (j);
  1814. emit_reset_frame (j, ntotal);
  1815. j->frame_size_min = j->frame_size_max = ntotal;
  1816. }
  1817. static void
  1818. compile_bind_kwargs_slow (scm_jit_state *j, uint32_t nreq, uint8_t flags,
  1819. uint32_t nreq_and_opt, uint32_t ntotal, const void *kw)
  1820. {
  1821. }
  1822. static void
  1823. compile_bind_rest (scm_jit_state *j, uint32_t dst)
  1824. {
  1825. jit_reloc_t k, cons;
  1826. jit_gpr_t t = T1;
  1827. /* As with receive-values, although bind-rest is usually used after a
  1828. call returns, the baseline compiler will sometimes emit it
  1829. elsewhere. In that case ensure that FP is in a register for the
  1830. frame-locals-count branches. */
  1831. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1832. cons = emit_branch_if_frame_locals_count_greater_than (j, t, dst);
  1833. emit_alloc_frame (j, t, dst + 1);
  1834. emit_movi (j, t, SCM_UNPACK (SCM_EOL));
  1835. emit_sp_set_scm (j, 0, t);
  1836. k = jit_jmp (j->jit);
  1837. jit_patch_here (j->jit, cons);
  1838. emit_store_current_ip (j, t);
  1839. emit_call_2 (j, scm_vm_intrinsics.cons_rest, thread_operand (),
  1840. jit_operand_imm (JIT_OPERAND_ABI_UINT32, dst));
  1841. emit_retval (j, t);
  1842. compile_reset_frame (j, dst + 1);
  1843. emit_sp_set_scm (j, 0, t);
  1844. jit_patch_here (j->jit, k);
  1845. j->frame_size_min = dst + 1;
  1846. }
  1847. static void
  1848. compile_bind_rest_slow (scm_jit_state *j, uint32_t dst)
  1849. {
  1850. }
  1851. static void
  1852. compile_bind_optionals (scm_jit_state *j, uint32_t nlocals)
  1853. {
  1854. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER | SP_IN_REGISTER);
  1855. ASSERT(j->frame_size_min < nlocals);
  1856. ASSERT(j->frame_size_min < j->frame_size_max);
  1857. jit_gpr_t saved_frame_size = T1_PRESERVED;
  1858. jit_subr (j->jit, saved_frame_size, FP, SP);
  1859. jit_reloc_t no_optionals = jit_bgei
  1860. (j->jit, saved_frame_size, nlocals * sizeof (union scm_vm_stack_element));
  1861. emit_alloc_frame (j, T0, nlocals);
  1862. j->frame_size_min = nlocals;
  1863. jit_gpr_t walk = saved_frame_size;
  1864. jit_subr (j->jit, walk, FP, saved_frame_size);
  1865. jit_reloc_t done = jit_bler (j->jit, walk, SP);
  1866. jit_movi (j->jit, T0, SCM_UNPACK (SCM_UNDEFINED));
  1867. void *head = jit_address (j->jit);
  1868. jit_subi (j->jit, walk, walk, sizeof (union scm_vm_stack_element));
  1869. jit_str (j->jit, walk, T0);
  1870. jit_patch_there (j->jit, jit_bner (j->jit, walk, SP), head);
  1871. jit_patch_here (j->jit, done);
  1872. jit_patch_here (j->jit, no_optionals);
  1873. }
  1874. static void
  1875. compile_bind_optionals_slow (scm_jit_state *j, uint32_t nlocals)
  1876. {
  1877. }
  1878. static void
  1879. compile_allocate_words (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1880. {
  1881. jit_gpr_t t = T0;
  1882. emit_store_current_ip (j, t);
  1883. emit_call_2 (j, scm_vm_intrinsics.allocate_words, thread_operand (),
  1884. sp_sz_operand (j, nwords));
  1885. emit_retval (j, t);
  1886. record_gpr_clobber (j, t);
  1887. emit_reload_sp (j);
  1888. emit_sp_set_scm (j, dst, t);
  1889. }
  1890. static void
  1891. compile_allocate_words_slow (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1892. {
  1893. }
  1894. static void
  1895. compile_allocate_words_immediate (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1896. {
  1897. size_t bytes = nwords * sizeof(SCM);
  1898. size_t idx = scm_inline_gc_bytes_to_freelist_index (bytes);
  1899. if (SCM_UNLIKELY (idx >= SCM_INLINE_GC_FREELIST_COUNT))
  1900. {
  1901. jit_gpr_t t = T0;
  1902. emit_store_current_ip (j, t);
  1903. emit_call_1 (j, GC_malloc, jit_operand_imm (JIT_OPERAND_ABI_WORD, bytes));
  1904. emit_retval (j, t);
  1905. emit_reload_sp (j);
  1906. emit_sp_set_scm (j, dst, t);
  1907. }
  1908. else
  1909. {
  1910. jit_gpr_t res = T0;
  1911. ptrdiff_t offset = offsetof(struct scm_thread, freelists);
  1912. offset += idx * sizeof(void*);
  1913. emit_ldxi (j, res, THREAD, offset);
  1914. add_slow_path_patch (j, jit_beqi (j->jit, res, 0));
  1915. jit_gpr_t new_freelist = T1;
  1916. emit_ldr (j, new_freelist, res);
  1917. jit_stxi (j->jit, offset, THREAD, new_freelist);
  1918. emit_sp_set_scm (j, dst, res);
  1919. }
  1920. }
  1921. static void
  1922. compile_allocate_words_immediate_slow (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1923. {
  1924. size_t bytes = nwords * sizeof(SCM);
  1925. size_t idx = scm_inline_gc_bytes_to_freelist_index (bytes);
  1926. if (SCM_UNLIKELY (idx >= SCM_INLINE_GC_FREELIST_COUNT))
  1927. {
  1928. }
  1929. else
  1930. {
  1931. jit_gpr_t res = T0;
  1932. emit_store_current_ip (j, res);
  1933. emit_call_2 (j, scm_vm_intrinsics.allocate_words_with_freelist,
  1934. thread_operand (),
  1935. jit_operand_imm (JIT_OPERAND_ABI_WORD, idx));
  1936. emit_retval (j, res);
  1937. emit_reload_sp (j);
  1938. emit_sp_set_scm (j, dst, res);
  1939. continue_after_slow_path (j, j->next_ip);
  1940. }
  1941. }
  1942. static void
  1943. compile_allocate_pointerless_words (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1944. {
  1945. jit_gpr_t t = T0;
  1946. emit_store_current_ip (j, t);
  1947. emit_call_2 (j, scm_vm_intrinsics.allocate_pointerless_words, thread_operand (),
  1948. sp_sz_operand (j, nwords));
  1949. emit_retval (j, t);
  1950. record_gpr_clobber (j, t);
  1951. emit_reload_sp (j);
  1952. emit_sp_set_scm (j, dst, t);
  1953. }
  1954. static void
  1955. compile_allocate_pointerless_words_slow (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1956. {
  1957. }
  1958. static void
  1959. compile_allocate_pointerless_words_immediate (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1960. {
  1961. size_t bytes = nwords * sizeof(SCM);
  1962. size_t idx = scm_inline_gc_bytes_to_freelist_index (bytes);
  1963. if (SCM_UNLIKELY (idx >= SCM_INLINE_GC_FREELIST_COUNT))
  1964. {
  1965. jit_gpr_t t = T0;
  1966. emit_store_current_ip (j, t);
  1967. emit_call_1 (j, GC_malloc_atomic, jit_operand_imm (JIT_OPERAND_ABI_WORD, bytes));
  1968. emit_retval (j, t);
  1969. emit_reload_sp (j);
  1970. emit_sp_set_scm (j, dst, t);
  1971. }
  1972. else
  1973. {
  1974. jit_gpr_t res = T0;
  1975. ptrdiff_t offset = offsetof(struct scm_thread, pointerless_freelists);
  1976. offset += idx * sizeof(void*);
  1977. emit_ldxi (j, res, THREAD, offset);
  1978. add_slow_path_patch (j, jit_beqi (j->jit, res, 0));
  1979. jit_gpr_t new_freelist = T1;
  1980. emit_ldr (j, new_freelist, res);
  1981. jit_stxi (j->jit, offset, THREAD, new_freelist);
  1982. emit_sp_set_scm (j, dst, res);
  1983. }
  1984. }
  1985. static void
  1986. compile_allocate_pointerless_words_immediate_slow (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1987. {
  1988. size_t bytes = nwords * sizeof(SCM);
  1989. size_t idx = scm_inline_gc_bytes_to_freelist_index (bytes);
  1990. if (SCM_UNLIKELY (idx >= SCM_INLINE_GC_FREELIST_COUNT))
  1991. {
  1992. }
  1993. else
  1994. {
  1995. jit_gpr_t res = T0;
  1996. emit_store_current_ip (j, res);
  1997. emit_call_2 (j, scm_vm_intrinsics.allocate_pointerless_words_with_freelist,
  1998. thread_operand (),
  1999. jit_operand_imm (JIT_OPERAND_ABI_WORD, idx));
  2000. emit_retval (j, res);
  2001. emit_reload_sp (j);
  2002. emit_sp_set_scm (j, dst, res);
  2003. continue_after_slow_path (j, j->next_ip);
  2004. }
  2005. }
  2006. static void
  2007. compile_scm_ref (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2008. {
  2009. emit_sp_ref_scm (j, T0, obj);
  2010. emit_sp_ref_sz (j, T1, idx);
  2011. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  2012. emit_ldxr (j, T0, T0, T1);
  2013. emit_sp_set_scm (j, dst, T0);
  2014. }
  2015. static void
  2016. compile_scm_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2017. {
  2018. }
  2019. static void
  2020. compile_scm_set (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  2021. {
  2022. emit_sp_ref_scm (j, T0, obj);
  2023. emit_sp_ref_sz (j, T1, idx);
  2024. emit_sp_ref_scm (j, T2, val);
  2025. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  2026. jit_stxr (j->jit, T0, T1, T2);
  2027. }
  2028. static void
  2029. compile_scm_set_slow (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  2030. {
  2031. }
  2032. static void
  2033. compile_scm_ref_tag (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t tag)
  2034. {
  2035. emit_sp_ref_scm (j, T0, obj);
  2036. emit_ldr (j, T0, T0);
  2037. emit_subi (j, T0, T0, tag);
  2038. emit_sp_set_scm (j, dst, T0);
  2039. }
  2040. static void
  2041. compile_scm_ref_tag_slow (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t tag)
  2042. {
  2043. }
  2044. static void
  2045. compile_scm_set_tag (scm_jit_state *j, uint8_t obj, uint8_t tag, uint8_t val)
  2046. {
  2047. emit_sp_ref_scm (j, T0, obj);
  2048. emit_sp_ref_scm (j, T1, val);
  2049. emit_addi (j, T1, T1, tag);
  2050. jit_str (j->jit, T0, T1);
  2051. }
  2052. static void
  2053. compile_scm_set_tag_slow (scm_jit_state *j, uint8_t obj, uint8_t tag, uint8_t val)
  2054. {
  2055. }
  2056. static void
  2057. compile_scm_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2058. {
  2059. emit_sp_ref_scm (j, T0, obj);
  2060. emit_ldxi (j, T0, T0, idx * sizeof (SCM));
  2061. emit_sp_set_scm (j, dst, T0);
  2062. }
  2063. static void
  2064. compile_scm_ref_immediate_slow (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2065. {
  2066. }
  2067. static void
  2068. compile_scm_set_immediate (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  2069. {
  2070. emit_sp_ref_scm (j, T0, obj);
  2071. emit_sp_ref_scm (j, T1, val);
  2072. jit_stxi (j->jit, idx * sizeof (SCM), T0, T1);
  2073. }
  2074. static void
  2075. compile_scm_set_immediate_slow (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  2076. {
  2077. }
  2078. static void
  2079. compile_word_ref (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2080. {
  2081. emit_sp_ref_scm (j, T0, obj);
  2082. emit_sp_ref_sz (j, T1, idx);
  2083. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  2084. emit_ldxr (j, T0, T0, T1);
  2085. emit_sp_set_sz (j, dst, T0);
  2086. }
  2087. static void
  2088. compile_word_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2089. {
  2090. }
  2091. static void
  2092. compile_word_set (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  2093. {
  2094. emit_sp_ref_scm (j, T0, obj);
  2095. emit_sp_ref_sz (j, T1, idx);
  2096. emit_sp_ref_sz (j, T2, val);
  2097. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  2098. jit_stxr (j->jit, T0, T1, T2);
  2099. }
  2100. static void
  2101. compile_word_set_slow (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  2102. {
  2103. }
  2104. static void
  2105. compile_word_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2106. {
  2107. emit_sp_ref_scm (j, T0, obj);
  2108. emit_ldxi (j, T0, T0, idx * sizeof (SCM));
  2109. emit_sp_set_sz (j, dst, T0);
  2110. }
  2111. static void
  2112. compile_word_ref_immediate_slow (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2113. {
  2114. }
  2115. static void
  2116. compile_word_set_immediate (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  2117. {
  2118. emit_sp_ref_scm (j, T0, obj);
  2119. emit_sp_ref_sz (j, T1, val);
  2120. jit_stxi (j->jit, idx * sizeof (SCM), T0, T1);
  2121. }
  2122. static void
  2123. compile_word_set_immediate_slow (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  2124. {
  2125. }
  2126. static void
  2127. compile_pointer_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2128. {
  2129. emit_sp_ref_scm (j, T0, obj);
  2130. emit_ldxi (j, T0, T0, idx * sizeof (SCM));
  2131. emit_sp_set_scm (j, dst, T0);
  2132. }
  2133. static void
  2134. compile_pointer_ref_immediate_slow (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2135. {
  2136. }
  2137. static void
  2138. compile_pointer_set_immediate (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  2139. {
  2140. emit_sp_ref_scm (j, T0, obj);
  2141. emit_sp_ref_scm (j, T1, val);
  2142. jit_stxi (j->jit, idx * sizeof (SCM), T0, T1);
  2143. }
  2144. static void
  2145. compile_pointer_set_immediate_slow (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  2146. {
  2147. }
  2148. static void
  2149. compile_tail_pointer_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2150. {
  2151. emit_sp_ref_scm (j, T0, obj);
  2152. emit_addi (j, T0, T0, idx * sizeof (SCM));
  2153. emit_sp_set_scm (j, dst, T0);
  2154. }
  2155. static void
  2156. compile_tail_pointer_ref_immediate_slow (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  2157. {
  2158. }
  2159. static void
  2160. compile_mov (scm_jit_state *j, uint16_t dst, uint16_t src)
  2161. {
  2162. emit_mov (j, dst, src, T0);
  2163. }
  2164. static void
  2165. compile_mov_slow (scm_jit_state *j, uint16_t dst, uint16_t src)
  2166. {
  2167. }
  2168. static void
  2169. compile_long_mov (scm_jit_state *j, uint32_t dst, uint32_t src)
  2170. {
  2171. emit_mov (j, dst, src, T0);
  2172. }
  2173. static void
  2174. compile_long_mov_slow (scm_jit_state *j, uint32_t dst, uint32_t src)
  2175. {
  2176. }
  2177. static void
  2178. compile_long_fmov (scm_jit_state *j, uint32_t dst, uint32_t src)
  2179. {
  2180. jit_gpr_t t = T0;
  2181. restore_reloadable_register_state (j, FP_IN_REGISTER);
  2182. emit_fp_ref_scm (j, t, src);
  2183. emit_fp_set_scm (j, dst, t);
  2184. }
  2185. static void
  2186. compile_long_fmov_slow (scm_jit_state *j, uint32_t dst, uint32_t src)
  2187. {
  2188. }
  2189. static void
  2190. compile_call_scm_from_scm_scm (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  2191. {
  2192. switch ((enum scm_vm_intrinsic) idx)
  2193. {
  2194. case SCM_VM_INTRINSIC_ADD:
  2195. {
  2196. emit_sp_ref_scm (j, T0, a);
  2197. emit_sp_ref_scm (j, T1, b);
  2198. add_slow_path_patch (j, jit_bmci (j->jit, T0, scm_tc2_int));
  2199. add_slow_path_patch (j, jit_bmci (j->jit, T1, scm_tc2_int));
  2200. jit_subi (j->jit, T0, T0, scm_tc2_int);
  2201. add_slow_path_patch (j, jit_boaddr (j->jit, T0, T1));
  2202. break;
  2203. }
  2204. case SCM_VM_INTRINSIC_SUB:
  2205. {
  2206. emit_sp_ref_scm (j, T0, a);
  2207. emit_sp_ref_scm (j, T1, b);
  2208. add_slow_path_patch (j, jit_bmci (j->jit, T0, scm_tc2_int));
  2209. add_slow_path_patch (j, jit_bmci (j->jit, T1, scm_tc2_int));
  2210. jit_subi (j->jit, T1, T1, scm_tc2_int);
  2211. add_slow_path_patch (j, jit_bosubr (j->jit, T0, T1));
  2212. break;
  2213. }
  2214. default:
  2215. {
  2216. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2217. jit_operand_t op_a = sp_scm_operand (j, a);
  2218. jit_operand_t op_b = sp_scm_operand (j, b);
  2219. emit_store_current_ip (j, T2);
  2220. emit_call_2 (j, intrinsic, op_a, op_b);
  2221. emit_retval (j, T0);
  2222. emit_reload_sp (j);
  2223. }
  2224. }
  2225. emit_sp_set_scm (j, dst, T0);
  2226. }
  2227. static void
  2228. compile_call_scm_from_scm_scm_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  2229. {
  2230. switch ((enum scm_vm_intrinsic) idx)
  2231. {
  2232. case SCM_VM_INTRINSIC_ADD:
  2233. case SCM_VM_INTRINSIC_SUB:
  2234. {
  2235. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2236. jit_operand_t op_a = sp_scm_operand (j, a);
  2237. jit_operand_t op_b = sp_scm_operand (j, b);
  2238. emit_store_current_ip (j, T1);
  2239. emit_call_2 (j, intrinsic, op_a, op_b);
  2240. emit_retval (j, T0);
  2241. emit_reload_sp (j);
  2242. emit_sp_set_scm (j, dst, T0);
  2243. continue_after_slow_path (j, j->next_ip);
  2244. break;
  2245. }
  2246. default:
  2247. break;
  2248. }
  2249. }
  2250. static void
  2251. compile_call_scm_from_scm_uimm (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  2252. {
  2253. switch ((enum scm_vm_intrinsic) idx)
  2254. {
  2255. case SCM_VM_INTRINSIC_ADD_IMMEDIATE:
  2256. {
  2257. emit_sp_ref_scm (j, T0, a);
  2258. scm_t_bits addend = b << 2;
  2259. add_slow_path_patch (j, jit_bmci (j->jit, T0, 2));
  2260. add_slow_path_patch (j, jit_boaddi (j->jit, T0, addend));
  2261. break;
  2262. }
  2263. case SCM_VM_INTRINSIC_SUB_IMMEDIATE:
  2264. {
  2265. emit_sp_ref_scm (j, T0, a);
  2266. scm_t_bits subtrahend = b << 2;
  2267. add_slow_path_patch (j, jit_bmci (j->jit, T0, 2));
  2268. add_slow_path_patch (j, jit_bosubi (j->jit, T0, subtrahend));
  2269. break;
  2270. }
  2271. default:
  2272. {
  2273. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2274. jit_operand_t op_a = sp_scm_operand (j, a);
  2275. jit_operand_t op_b = jit_operand_imm (JIT_OPERAND_ABI_UINT8, b);
  2276. emit_store_current_ip (j, T1);
  2277. emit_call_2 (j, intrinsic, op_a, op_b);
  2278. emit_retval (j, T0);
  2279. emit_reload_sp (j);
  2280. break;
  2281. }
  2282. }
  2283. emit_sp_set_scm (j, dst, T0);
  2284. }
  2285. static void
  2286. compile_call_scm_from_scm_uimm_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  2287. {
  2288. switch ((enum scm_vm_intrinsic) idx)
  2289. {
  2290. case SCM_VM_INTRINSIC_ADD_IMMEDIATE:
  2291. case SCM_VM_INTRINSIC_SUB_IMMEDIATE:
  2292. {
  2293. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2294. jit_operand_t op_a = sp_scm_operand (j, a);
  2295. jit_operand_t op_b = jit_operand_imm (JIT_OPERAND_ABI_UINT8, b);
  2296. emit_store_current_ip (j, T1);
  2297. emit_call_2 (j, intrinsic, op_a, op_b);
  2298. emit_retval (j, T0);
  2299. emit_reload_sp (j);
  2300. emit_sp_set_scm (j, dst, T0);
  2301. continue_after_slow_path (j, j->next_ip);
  2302. break;
  2303. }
  2304. default:
  2305. break;
  2306. }
  2307. }
  2308. static void
  2309. compile_call_scm_sz_u32 (scm_jit_state *j, uint8_t a, uint8_t b, uint8_t c, uint32_t idx)
  2310. {
  2311. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2312. emit_store_current_ip (j, T0);
  2313. emit_call_3 (j, intrinsic, sp_scm_operand (j, a), sp_sz_operand (j, b),
  2314. sp_sz_operand (j, c));
  2315. emit_reload_sp (j);
  2316. }
  2317. static void
  2318. compile_call_scm_sz_u32_slow (scm_jit_state *j, uint8_t a, uint8_t b, uint8_t c, uint32_t idx)
  2319. {
  2320. }
  2321. static void
  2322. compile_call_scm_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2323. {
  2324. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2325. emit_store_current_ip (j, T0);
  2326. emit_call_1 (j, intrinsic, sp_scm_operand (j, a));
  2327. emit_retval (j, T0);
  2328. emit_reload_sp (j);
  2329. emit_sp_set_scm (j, dst, T0);
  2330. }
  2331. static void
  2332. compile_call_scm_from_scm_slow (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2333. {
  2334. }
  2335. static void
  2336. compile_call_f64_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2337. {
  2338. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2339. emit_store_current_ip (j, T0);
  2340. emit_call_1 (j, intrinsic, sp_scm_operand (j, a));
  2341. emit_retval_d (j, JIT_F0);
  2342. emit_reload_sp (j);
  2343. emit_sp_set_f64 (j, dst, JIT_F0);
  2344. }
  2345. static void
  2346. compile_call_f64_from_scm_slow (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2347. {
  2348. }
  2349. static void
  2350. compile_call_f64_from_f64 (scm_jit_state *j, uint16_t dst, uint16_t src, uint32_t idx)
  2351. {
  2352. switch ((enum scm_vm_intrinsic) idx)
  2353. {
  2354. case SCM_VM_INTRINSIC_FABS:
  2355. {
  2356. emit_sp_ref_f64 (j, JIT_F0, src);
  2357. emit_absr_d (j, JIT_F0, JIT_F0);
  2358. emit_sp_set_f64 (j, dst, JIT_F0);
  2359. break;
  2360. }
  2361. case SCM_VM_INTRINSIC_FSQRT:
  2362. {
  2363. emit_sp_ref_f64 (j, JIT_F0, src);
  2364. emit_sqrtr_d (j, JIT_F0, JIT_F0);
  2365. emit_sp_set_f64 (j, dst, JIT_F0);
  2366. break;
  2367. }
  2368. default:
  2369. {
  2370. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2371. emit_call_1 (j, intrinsic, sp_f64_operand (j, src));
  2372. emit_retval_d (j, JIT_F0);
  2373. emit_reload_sp (j);
  2374. emit_sp_set_f64 (j, dst, JIT_F0);
  2375. break;
  2376. }
  2377. }
  2378. }
  2379. static void
  2380. compile_call_f64_from_f64_slow (scm_jit_state *j, uint16_t dst, uint16_t src, uint32_t idx)
  2381. {
  2382. }
  2383. static void
  2384. compile_call_f64_from_f64_f64 (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  2385. {
  2386. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2387. emit_call_2 (j, intrinsic, sp_f64_operand (j, a), sp_f64_operand (j, b));
  2388. emit_retval_d (j, JIT_F0);
  2389. emit_reload_sp (j);
  2390. emit_sp_set_f64 (j, dst, JIT_F0);
  2391. }
  2392. static void
  2393. compile_call_f64_from_f64_f64_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  2394. {
  2395. }
  2396. static void
  2397. compile_call_u64_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2398. {
  2399. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2400. emit_store_current_ip (j, T0);
  2401. #if INDIRECT_INT64_INTRINSICS
  2402. emit_call_2 (j, intrinsic, sp_slot_operand (j, dst), sp_scm_operand (j, a));
  2403. emit_reload_sp (j);
  2404. #else
  2405. emit_call_1 (j, intrinsic, sp_scm_operand (j, a));
  2406. emit_retval (j, T0);
  2407. emit_reload_sp (j);
  2408. emit_sp_set_u64 (j, dst, T0);
  2409. #endif
  2410. }
  2411. static void
  2412. compile_call_u64_from_scm_slow (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2413. {
  2414. }
  2415. static void
  2416. compile_make_immediate (scm_jit_state *j, uint8_t dst, SCM a)
  2417. {
  2418. emit_movi (j, T0, SCM_UNPACK (a));
  2419. emit_sp_set_scm (j, dst, T0);
  2420. }
  2421. static void
  2422. compile_make_immediate_slow (scm_jit_state *j, uint8_t dst, SCM a)
  2423. {
  2424. }
  2425. static void
  2426. compile_make_short_immediate (scm_jit_state *j, uint8_t dst, SCM a)
  2427. {
  2428. emit_movi (j, T0, SCM_UNPACK (a));
  2429. emit_sp_set_scm (j, dst, T0);
  2430. }
  2431. static void
  2432. compile_make_short_immediate_slow (scm_jit_state *j, uint8_t dst, SCM a)
  2433. {
  2434. }
  2435. static void
  2436. compile_make_long_immediate (scm_jit_state *j, uint32_t dst, SCM a)
  2437. {
  2438. emit_movi (j, T0, SCM_UNPACK (a));
  2439. emit_sp_set_scm (j, dst, T0);
  2440. }
  2441. static void
  2442. compile_make_long_immediate_slow (scm_jit_state *j, uint32_t dst, SCM a)
  2443. {
  2444. }
  2445. static void
  2446. compile_make_long_long_immediate (scm_jit_state *j, uint32_t dst, SCM a)
  2447. {
  2448. emit_movi (j, T0, SCM_UNPACK (a));
  2449. emit_sp_set_scm (j, dst, T0);
  2450. }
  2451. static void
  2452. compile_make_long_long_immediate_slow (scm_jit_state *j, uint32_t dst, SCM a)
  2453. {
  2454. }
  2455. static void
  2456. compile_make_non_immediate (scm_jit_state *j, uint32_t dst, const void *data)
  2457. {
  2458. emit_movi (j, T0, (uintptr_t)data);
  2459. emit_sp_set_scm (j, dst, T0);
  2460. }
  2461. static void
  2462. compile_make_non_immediate_slow (scm_jit_state *j, uint32_t dst, const void *data)
  2463. {
  2464. }
  2465. static void
  2466. compile_static_ref (scm_jit_state *j, uint32_t dst, void *loc)
  2467. {
  2468. emit_ldi (j, T0, loc);
  2469. emit_sp_set_scm (j, dst, T0);
  2470. }
  2471. static void
  2472. compile_static_ref_slow (scm_jit_state *j, uint32_t dst, void *loc)
  2473. {
  2474. }
  2475. static void
  2476. compile_static_set (scm_jit_state *j, uint32_t obj, void *loc)
  2477. {
  2478. emit_sp_ref_scm (j, T0, obj);
  2479. jit_sti (j->jit, loc, T0);
  2480. }
  2481. static void
  2482. compile_static_set_slow (scm_jit_state *j, uint32_t obj, void *loc)
  2483. {
  2484. }
  2485. static void
  2486. compile_static_patch (scm_jit_state *j, void *dst, const void *src)
  2487. {
  2488. emit_movi (j, T0, (uintptr_t) src);
  2489. jit_sti (j->jit, dst, T0);
  2490. }
  2491. static void
  2492. compile_static_patch_slow (scm_jit_state *j, void *dst, const void *src)
  2493. {
  2494. }
  2495. static void
  2496. compile_prompt (scm_jit_state *j, uint32_t tag, uint8_t escape_only_p,
  2497. uint32_t proc_slot, const uint32_t *vcode)
  2498. {
  2499. emit_store_current_ip (j, T0);
  2500. emit_reload_fp (j);
  2501. jit_subi (j->jit, FP, FP, proc_slot * sizeof (union scm_vm_stack_element));
  2502. jit_reloc_t mra = emit_mov_addr (j, T2);
  2503. jit_operand_t args[] =
  2504. { thread_operand (),
  2505. jit_operand_imm (JIT_OPERAND_ABI_UINT8, escape_only_p),
  2506. sp_scm_operand (j, tag),
  2507. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, FP),
  2508. jit_operand_imm (JIT_OPERAND_ABI_POINTER, (uintptr_t)vcode),
  2509. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T2) };
  2510. jit_calli (j->jit, scm_vm_intrinsics.push_prompt, 6, args);
  2511. clear_scratch_register_state (j);
  2512. emit_reload_sp (j);
  2513. emit_reload_fp (j);
  2514. add_inter_instruction_patch (j, mra, vcode);
  2515. }
  2516. static void
  2517. compile_prompt_slow (scm_jit_state *j, uint32_t tag, uint8_t escape_only_p,
  2518. uint32_t proc_slot, const uint32_t *vcode)
  2519. {
  2520. }
  2521. static void
  2522. compile_load_label (scm_jit_state *j, uint32_t dst, const uint32_t *vcode)
  2523. {
  2524. emit_movi (j, T0, (uintptr_t) vcode);
  2525. #if SIZEOF_UINTPTR_T >= 8
  2526. emit_sp_set_u64 (j, dst, T0);
  2527. #else
  2528. emit_movi (j, T1, 0);
  2529. emit_sp_set_u64 (j, dst, T0, T1);
  2530. #endif
  2531. }
  2532. static void
  2533. compile_load_label_slow (scm_jit_state *j, uint32_t dst, const uint32_t *vcode)
  2534. {
  2535. }
  2536. static void
  2537. compile_call_s64_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2538. {
  2539. compile_call_u64_from_scm (j, dst, a, idx);
  2540. }
  2541. static void
  2542. compile_call_s64_from_scm_slow (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2543. {
  2544. }
  2545. static void
  2546. compile_call_scm_from_u64 (scm_jit_state *j, uint16_t dst, uint16_t src, uint32_t idx)
  2547. {
  2548. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2549. emit_store_current_ip (j, T0);
  2550. #if INDIRECT_INT64_INTRINSICS
  2551. emit_call_1 (j, intrinsic, sp_slot_operand (j, src));
  2552. #else
  2553. emit_call_1 (j, intrinsic, sp_u64_operand (j, src));
  2554. #endif
  2555. emit_retval (j, T0);
  2556. emit_reload_sp (j);
  2557. emit_sp_set_scm (j, dst, T0);
  2558. }
  2559. static void
  2560. compile_call_scm_from_u64_slow (scm_jit_state *j, uint16_t dst, uint16_t src, uint32_t idx)
  2561. {
  2562. }
  2563. static void
  2564. compile_call_scm_from_s64 (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t b)
  2565. {
  2566. compile_call_scm_from_u64 (j, dst, a, b);
  2567. }
  2568. static void
  2569. compile_call_scm_from_s64_slow (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t b)
  2570. {
  2571. }
  2572. static void
  2573. compile_tag_char (scm_jit_state *j, uint16_t dst, uint16_t src)
  2574. {
  2575. #if SIZEOF_UINTPTR_T >= 8
  2576. emit_sp_ref_u64 (j, T0, src);
  2577. #else
  2578. emit_sp_ref_u64_lower_half (j, T0, src);
  2579. #endif
  2580. emit_lshi (j, T0, T0, 8);
  2581. emit_addi (j, T0, T0, scm_tc8_char);
  2582. emit_sp_set_scm (j, dst, T0);
  2583. }
  2584. static void
  2585. compile_tag_char_slow (scm_jit_state *j, uint16_t dst, uint16_t src)
  2586. {
  2587. }
  2588. static void
  2589. compile_untag_char (scm_jit_state *j, uint16_t dst, uint16_t src)
  2590. {
  2591. emit_sp_ref_scm (j, T0, src);
  2592. emit_rshi (j, T0, T0, 8);
  2593. #if SIZEOF_UINTPTR_T >= 8
  2594. emit_sp_set_u64 (j, dst, T0);
  2595. #else
  2596. emit_movi (j, T1, 0);
  2597. emit_sp_set_u64 (j, dst, T0, T1);
  2598. #endif
  2599. }
  2600. static void
  2601. compile_untag_char_slow (scm_jit_state *j, uint16_t dst, uint16_t src)
  2602. {
  2603. }
  2604. static void
  2605. compile_atomic_scm_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t offset)
  2606. {
  2607. emit_sp_ref_scm (j, T0, obj);
  2608. emit_addi (j, T0, T0, offset * sizeof (SCM));
  2609. jit_ldr_atomic (j->jit, T0, T0);
  2610. record_gpr_clobber (j, T0);
  2611. emit_sp_set_scm (j, dst, T0);
  2612. }
  2613. static void
  2614. compile_atomic_scm_ref_immediate_slow (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t offset)
  2615. {
  2616. }
  2617. static void
  2618. compile_atomic_scm_set_immediate (scm_jit_state *j, uint8_t obj, uint8_t offset, uint8_t val)
  2619. {
  2620. emit_sp_ref_scm (j, T0, obj);
  2621. emit_sp_ref_scm (j, T1, val);
  2622. emit_addi (j, T0, T0, offset * sizeof (SCM));
  2623. jit_str_atomic (j->jit, T0, T1);
  2624. }
  2625. static void
  2626. compile_atomic_scm_set_immediate_slow (scm_jit_state *j, uint8_t obj, uint8_t offset, uint8_t val)
  2627. {
  2628. }
  2629. static void
  2630. compile_atomic_scm_swap_immediate (scm_jit_state *j, uint32_t dst, uint32_t obj, uint8_t offset, uint32_t val)
  2631. {
  2632. emit_sp_ref_scm (j, T0, obj);
  2633. emit_sp_ref_scm (j, T1, val);
  2634. emit_addi (j, T0, T0, offset * sizeof (SCM));
  2635. jit_swap_atomic (j->jit, T1, T0, T1);
  2636. record_gpr_clobber (j, T1);
  2637. emit_sp_set_scm (j, dst, T1);
  2638. }
  2639. static void
  2640. compile_atomic_scm_swap_immediate_slow (scm_jit_state *j, uint32_t dst, uint32_t obj, uint8_t offset, uint32_t val)
  2641. {
  2642. }
  2643. static void
  2644. compile_atomic_scm_compare_and_swap_immediate (scm_jit_state *j, uint32_t dst,
  2645. uint32_t obj, uint8_t offset,
  2646. uint32_t expected, uint32_t desired)
  2647. {
  2648. emit_sp_ref_scm (j, T0, obj);
  2649. emit_sp_ref_scm (j, T1, expected);
  2650. emit_sp_ref_scm (j, T2, desired);
  2651. emit_addi (j, T0, T0, offset * sizeof (SCM));
  2652. jit_cas_atomic (j->jit, T1, T0, T1, T2);
  2653. record_gpr_clobber (j, T1);
  2654. emit_sp_set_scm (j, dst, T1);
  2655. }
  2656. static void
  2657. compile_atomic_scm_compare_and_swap_immediate_slow (scm_jit_state *j, uint32_t dst,
  2658. uint32_t obj, uint8_t offset,
  2659. uint32_t expected, uint32_t desired)
  2660. {
  2661. }
  2662. static void
  2663. compile_call_thread_scm_scm (scm_jit_state *j, uint16_t a, uint16_t b, uint32_t idx)
  2664. {
  2665. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2666. emit_store_current_ip (j, T0);
  2667. emit_call_3 (j, intrinsic, thread_operand (), sp_scm_operand (j, a),
  2668. sp_scm_operand (j, b));
  2669. emit_reload_sp (j);
  2670. }
  2671. static void
  2672. compile_call_thread_scm_scm_slow (scm_jit_state *j, uint16_t a, uint16_t b, uint32_t idx)
  2673. {
  2674. }
  2675. static void
  2676. compile_call_thread (scm_jit_state *j, uint32_t idx)
  2677. {
  2678. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2679. emit_store_current_ip (j, T0);
  2680. emit_call_1 (j, intrinsic, thread_operand ());
  2681. emit_reload_sp (j);
  2682. }
  2683. static void
  2684. compile_call_thread_slow (scm_jit_state *j, uint32_t idx)
  2685. {
  2686. }
  2687. static void
  2688. compile_call_scm_from_thread_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2689. {
  2690. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2691. emit_store_current_ip (j, T0);
  2692. emit_call_2 (j, intrinsic, thread_operand (), sp_scm_operand (j, a));
  2693. emit_retval (j, T0);
  2694. emit_reload_sp (j);
  2695. emit_sp_set_scm (j, dst, T0);
  2696. }
  2697. static void
  2698. compile_call_scm_from_thread_scm_slow (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2699. {
  2700. }
  2701. static void
  2702. compile_call_thread_scm (scm_jit_state *j, uint32_t a, uint32_t idx)
  2703. {
  2704. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2705. emit_store_current_ip (j, T0);
  2706. emit_call_2 (j, intrinsic, thread_operand (), sp_scm_operand (j, a));
  2707. emit_reload_sp (j);
  2708. }
  2709. static void
  2710. compile_call_thread_scm_slow (scm_jit_state *j, uint32_t a, uint32_t idx)
  2711. {
  2712. }
  2713. static void
  2714. compile_call_scm_from_scm_u64 (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  2715. {
  2716. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2717. emit_store_current_ip (j, T0);
  2718. #if INDIRECT_INT64_INTRINSICS
  2719. emit_call_2 (j, intrinsic, sp_scm_operand (j, a), sp_slot_operand (j, b));
  2720. #else
  2721. emit_call_2 (j, intrinsic, sp_scm_operand (j, a), sp_u64_operand (j, b));
  2722. #endif
  2723. emit_retval (j, T0);
  2724. emit_reload_sp (j);
  2725. emit_sp_set_scm (j, dst, T0);
  2726. }
  2727. static void
  2728. compile_call_scm_from_scm_u64_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  2729. {
  2730. }
  2731. static void
  2732. compile_call_scm_from_thread (scm_jit_state *j, uint32_t dst, uint32_t idx)
  2733. {
  2734. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2735. emit_store_current_ip (j, T0);
  2736. emit_call_1 (j, intrinsic, thread_operand ());
  2737. emit_retval (j, T0);
  2738. emit_reload_sp (j);
  2739. emit_sp_set_scm (j, dst, T0);
  2740. }
  2741. static void
  2742. compile_call_scm_from_thread_slow (scm_jit_state *j, uint32_t dst, uint32_t idx)
  2743. {
  2744. }
  2745. static void
  2746. compile_call_scm_scm (scm_jit_state *j, uint16_t a, uint16_t b, uint32_t idx)
  2747. {
  2748. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2749. emit_store_current_ip (j, T0);
  2750. emit_call_2 (j, intrinsic, sp_scm_operand (j, a), sp_scm_operand (j, b));
  2751. emit_reload_sp (j);
  2752. }
  2753. static void
  2754. compile_call_scm_scm_slow (scm_jit_state *j, uint16_t a, uint16_t b,
  2755. uint32_t idx)
  2756. {
  2757. }
  2758. static void
  2759. compile_call_scm_scm_scm (scm_jit_state *j, uint8_t a, uint8_t b, uint8_t c,
  2760. uint32_t idx)
  2761. {
  2762. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2763. emit_store_current_ip (j, T0);
  2764. emit_call_3 (j, intrinsic, sp_scm_operand (j, a), sp_scm_operand (j, b),
  2765. sp_scm_operand (j, c));
  2766. emit_reload_sp (j);
  2767. }
  2768. static void
  2769. compile_call_scm_scm_scm_slow (scm_jit_state *j, uint8_t a, uint8_t b,
  2770. uint8_t c, uint32_t idx)
  2771. {
  2772. }
  2773. static void
  2774. compile_call_scm_uimm_scm (scm_jit_state *j, uint8_t a, uint8_t b, uint8_t c,
  2775. uint32_t idx)
  2776. {
  2777. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2778. emit_store_current_ip (j, T0);
  2779. emit_call_3 (j, intrinsic, sp_scm_operand (j, a),
  2780. jit_operand_imm (JIT_OPERAND_ABI_UINT8, b),
  2781. sp_scm_operand (j, c));
  2782. emit_reload_sp (j);
  2783. }
  2784. static void
  2785. compile_call_scm_uimm_scm_slow (scm_jit_state *j, uint8_t a, uint8_t b,
  2786. uint8_t c, uint32_t idx)
  2787. {
  2788. }
  2789. static void
  2790. compile_fadd (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2791. {
  2792. emit_sp_ref_f64 (j, JIT_F0, a);
  2793. emit_sp_ref_f64 (j, JIT_F1, b);
  2794. emit_addr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2795. emit_sp_set_f64 (j, dst, JIT_F0);
  2796. }
  2797. static void
  2798. compile_fadd_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2799. {
  2800. }
  2801. static void
  2802. compile_fsub (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2803. {
  2804. emit_sp_ref_f64 (j, JIT_F0, a);
  2805. emit_sp_ref_f64 (j, JIT_F1, b);
  2806. emit_subr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2807. emit_sp_set_f64 (j, dst, JIT_F0);
  2808. }
  2809. static void
  2810. compile_fsub_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2811. {
  2812. }
  2813. static void
  2814. compile_fmul (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2815. {
  2816. emit_sp_ref_f64 (j, JIT_F0, a);
  2817. emit_sp_ref_f64 (j, JIT_F1, b);
  2818. emit_mulr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2819. emit_sp_set_f64 (j, dst, JIT_F0);
  2820. }
  2821. static void
  2822. compile_fmul_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2823. {
  2824. }
  2825. static void
  2826. compile_fdiv (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2827. {
  2828. emit_sp_ref_f64 (j, JIT_F0, a);
  2829. emit_sp_ref_f64 (j, JIT_F1, b);
  2830. emit_divr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2831. emit_sp_set_f64 (j, dst, JIT_F0);
  2832. }
  2833. static void
  2834. compile_fdiv_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2835. {
  2836. }
  2837. static void
  2838. compile_uadd (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2839. {
  2840. #if SIZEOF_UINTPTR_T >= 8
  2841. emit_sp_ref_u64 (j, T0, a);
  2842. emit_sp_ref_u64 (j, T1, b);
  2843. emit_addr (j, T0, T0, T1);
  2844. emit_sp_set_u64 (j, dst, T0);
  2845. #else
  2846. emit_sp_ref_u64 (j, T0, T1, a);
  2847. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2848. emit_addcr (j, T0, T0, T2);
  2849. emit_addxr (j, T1, T1, T3_OR_FP);
  2850. emit_sp_set_u64 (j, dst, T0, T1);
  2851. #endif
  2852. }
  2853. static void
  2854. compile_uadd_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2855. {
  2856. }
  2857. static void
  2858. compile_usub (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2859. {
  2860. #if SIZEOF_UINTPTR_T >= 8
  2861. emit_sp_ref_u64 (j, T0, a);
  2862. emit_sp_ref_u64 (j, T1, b);
  2863. emit_subr (j, T0, T0, T1);
  2864. emit_sp_set_u64 (j, dst, T0);
  2865. #else
  2866. emit_sp_ref_u64 (j, T0, T1, a);
  2867. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2868. emit_subcr (j, T0, T0, T2);
  2869. emit_subxr (j, T1, T1, T3_OR_FP);
  2870. emit_sp_set_u64 (j, dst, T0, T1);
  2871. #endif
  2872. }
  2873. static void
  2874. compile_usub_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2875. {
  2876. }
  2877. static void
  2878. compile_umul (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2879. {
  2880. #if SIZEOF_UINTPTR_T >= 8
  2881. emit_sp_ref_u64 (j, T0, a);
  2882. emit_sp_ref_u64 (j, T1, b);
  2883. emit_mulr (j, T0, T0, T1);
  2884. emit_sp_set_u64 (j, dst, T0);
  2885. #else
  2886. /* FIXME: This is untested! */
  2887. emit_sp_ref_u64 (j, T0, T1, a);
  2888. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2889. emit_mulr (j, T1, T1, T2); /* High A times low B */
  2890. emit_mulr (j, T3_OR_FP, T3_OR_FP, T0); /* High B times low A */
  2891. emit_addr (j, T1, T1, T3_OR_FP); /* Add high results, throw away overflow */
  2892. emit_qmulr_u (j, T0, T2, T0, T2); /* Low A times low B */
  2893. emit_addr (j, T1, T1, T2); /* Add high result of low product */
  2894. emit_sp_set_u64 (j, dst, T0, T1);
  2895. #endif
  2896. }
  2897. static void
  2898. compile_umul_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2899. {
  2900. }
  2901. static void
  2902. compile_uadd_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2903. {
  2904. #if SIZEOF_UINTPTR_T >= 8
  2905. emit_sp_ref_u64 (j, T0, a);
  2906. emit_addi (j, T0, T0, b);
  2907. emit_sp_set_u64 (j, dst, T0);
  2908. #else
  2909. emit_sp_ref_u64 (j, T0, T1, a);
  2910. emit_addci (j, T0, T0, b);
  2911. emit_addxi (j, T1, T1, 0);
  2912. emit_sp_set_u64 (j, dst, T0, T1);
  2913. #endif
  2914. }
  2915. static void
  2916. compile_uadd_immediate_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2917. {
  2918. }
  2919. static void
  2920. compile_usub_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2921. {
  2922. #if SIZEOF_UINTPTR_T >= 8
  2923. emit_sp_ref_u64 (j, T0, a);
  2924. emit_subi (j, T0, T0, b);
  2925. emit_sp_set_u64 (j, dst, T0);
  2926. #else
  2927. emit_sp_ref_u64 (j, T0, T1, a);
  2928. emit_subci (j, T0, T0, b);
  2929. emit_subxi (j, T1, T1, 0);
  2930. emit_sp_set_u64 (j, dst, T0, T1);
  2931. #endif
  2932. }
  2933. static void
  2934. compile_usub_immediate_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2935. {
  2936. }
  2937. static void
  2938. compile_umul_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2939. {
  2940. #if SIZEOF_UINTPTR_T >= 8
  2941. emit_sp_ref_u64 (j, T0, a);
  2942. emit_muli (j, T0, T0, b);
  2943. emit_sp_set_u64 (j, dst, T0);
  2944. #else
  2945. /* FIXME: This is untested! */
  2946. emit_sp_ref_u64 (j, T0, T1, a);
  2947. emit_muli (j, T1, T1, b); /* High A times low B */
  2948. /* High B times low A is 0. */
  2949. emit_movi (j, T2, b);
  2950. emit_qmulr_u (j, T0, T2, T0, T2); /* Low A times low B */
  2951. emit_addr (j, T1, T1, T2); /* Add high result of low product */
  2952. emit_sp_set_u64 (j, dst, T0, T1);
  2953. #endif
  2954. }
  2955. static void
  2956. compile_umul_immediate_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2957. {
  2958. }
  2959. static void
  2960. compile_load_f64 (scm_jit_state *j, uint32_t dst, double a)
  2961. {
  2962. jit_movi_d (j->jit, JIT_F0, a);
  2963. record_fpr_clobber (j, JIT_F0);
  2964. emit_sp_set_f64 (j, dst, JIT_F0);
  2965. }
  2966. static void
  2967. compile_load_f64_slow (scm_jit_state *j, uint32_t dst, double a)
  2968. {
  2969. }
  2970. static void
  2971. compile_load_u64 (scm_jit_state *j, uint32_t dst, uint64_t a)
  2972. {
  2973. #if SIZEOF_UINTPTR_T >= 8
  2974. emit_movi (j, T0, a);
  2975. emit_sp_set_u64 (j, dst, T0);
  2976. #else
  2977. emit_movi (j, T0, a & 0xffffffff);
  2978. emit_movi (j, T1, a >> 32);
  2979. emit_sp_set_u64 (j, dst, T0, T1);
  2980. #endif
  2981. }
  2982. static void
  2983. compile_load_u64_slow (scm_jit_state *j, uint32_t dst, uint64_t a)
  2984. {
  2985. }
  2986. static void
  2987. compile_load_s64 (scm_jit_state *j, uint32_t dst, int64_t a)
  2988. {
  2989. compile_load_u64 (j, dst, a);
  2990. }
  2991. static void
  2992. compile_load_s64_slow (scm_jit_state *j, uint32_t dst, int64_t a)
  2993. {
  2994. }
  2995. static void
  2996. compile_current_thread (scm_jit_state *j, uint32_t dst)
  2997. {
  2998. emit_ldxi (j, T0, THREAD, thread_offset_handle);
  2999. emit_sp_set_scm (j, dst, T0);
  3000. }
  3001. static void
  3002. compile_current_thread_slow (scm_jit_state *j, uint32_t dst)
  3003. {
  3004. }
  3005. static void
  3006. compile_ulogand (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3007. {
  3008. #if SIZEOF_UINTPTR_T >= 8
  3009. emit_sp_ref_u64 (j, T0, a);
  3010. emit_sp_ref_u64 (j, T1, b);
  3011. emit_andr (j, T0, T0, T1);
  3012. emit_sp_set_u64 (j, dst, T0);
  3013. #else
  3014. emit_sp_ref_u64 (j, T0, T1, a);
  3015. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  3016. emit_andr (j, T0, T0, T2);
  3017. emit_andr (j, T1, T1, T3_OR_FP);
  3018. emit_sp_set_u64 (j, dst, T0, T1);
  3019. #endif
  3020. }
  3021. static void
  3022. compile_ulogand_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3023. {
  3024. }
  3025. static void
  3026. compile_ulogior (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3027. {
  3028. #if SIZEOF_UINTPTR_T >= 8
  3029. emit_sp_ref_u64 (j, T0, a);
  3030. emit_sp_ref_u64 (j, T1, b);
  3031. emit_orr (j, T0, T0, T1);
  3032. emit_sp_set_u64 (j, dst, T0);
  3033. #else
  3034. emit_sp_ref_u64 (j, T0, T1, a);
  3035. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  3036. emit_orr (j, T0, T0, T2);
  3037. emit_orr (j, T1, T1, T3_OR_FP);
  3038. emit_sp_set_u64 (j, dst, T0, T1);
  3039. #endif
  3040. }
  3041. static void
  3042. compile_ulogior_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3043. {
  3044. }
  3045. static void
  3046. compile_ulogsub (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3047. {
  3048. #if SIZEOF_UINTPTR_T >= 8
  3049. emit_sp_ref_u64 (j, T0, a);
  3050. emit_sp_ref_u64 (j, T1, b);
  3051. emit_comr (j, T1, T1);
  3052. emit_andr (j, T0, T0, T1);
  3053. emit_sp_set_u64 (j, dst, T0);
  3054. #else
  3055. emit_sp_ref_u64 (j, T0, T1, a);
  3056. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  3057. emit_comr (j, T2, T2);
  3058. emit_comr (j, T3_OR_FP, T3_OR_FP);
  3059. emit_andr (j, T0, T0, T2);
  3060. emit_andr (j, T1, T1, T3_OR_FP);
  3061. emit_sp_set_u64 (j, dst, T0, T1);
  3062. #endif
  3063. }
  3064. static void
  3065. compile_ulogsub_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3066. {
  3067. }
  3068. static void
  3069. compile_ursh (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3070. {
  3071. #if SIZEOF_UINTPTR_T >= 8
  3072. emit_sp_ref_u64 (j, T0, a);
  3073. emit_sp_ref_u64 (j, T1, b);
  3074. emit_andi (j, T1, T1, 63);
  3075. emit_rshr_u (j, T0, T0, T1);
  3076. emit_sp_set_u64 (j, dst, T0);
  3077. #else
  3078. /* FIXME: Not tested. */
  3079. jit_reloc_t zero, both, done;
  3080. emit_sp_ref_u64 (j, T0, T1, a);
  3081. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  3082. emit_andi (j, T2, T2, 63);
  3083. zero = jit_beqi (j->jit, T2, 0);
  3084. both = jit_blti (j->jit, T2, 32);
  3085. /* 32 <= s < 64: hi = 0, lo = hi >> (s-32) */
  3086. emit_subi (j, T2, T2, 32);
  3087. emit_rshr_u (j, T0, T1, T2);
  3088. emit_movi (j, T1, 0);
  3089. done = jit_jmp (j->jit);
  3090. jit_patch_here (j->jit, both);
  3091. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  3092. emit_negr (j, T3_OR_FP, T2);
  3093. emit_addi (j, T3_OR_FP, T3_OR_FP, 32);
  3094. emit_lshr (j, T3_OR_FP, T1, T3_OR_FP);
  3095. emit_rshr_u (j, T1, T1, T2);
  3096. emit_rshr_u (j, T0, T0, T2);
  3097. emit_addr (j, T0, T0, T3_OR_FP);
  3098. jit_patch_here (j->jit, done);
  3099. jit_patch_here (j->jit, zero);
  3100. emit_sp_set_u64 (j, dst, T0, T1);
  3101. #endif
  3102. }
  3103. static void
  3104. compile_ursh_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3105. {
  3106. }
  3107. static void
  3108. compile_ulsh (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3109. {
  3110. #if SIZEOF_UINTPTR_T >= 8
  3111. emit_sp_ref_u64 (j, T0, a);
  3112. emit_sp_ref_u64 (j, T1, b);
  3113. emit_andi (j, T1, T1, 63);
  3114. emit_lshr (j, T0, T0, T1);
  3115. emit_sp_set_u64 (j, dst, T0);
  3116. #else
  3117. /* FIXME: Not tested. */
  3118. jit_reloc_t zero, both, done;
  3119. emit_sp_ref_u64 (j, T0, T1, a);
  3120. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  3121. emit_andi (j, T2, T2, 63);
  3122. zero = jit_beqi (j->jit, T2, 0);
  3123. both = jit_blti (j->jit, T2, 32);
  3124. /* 32 <= s < 64: hi = lo << (s-32), lo = 0 */
  3125. emit_subi (j, T2, T2, 32);
  3126. emit_lshr (j, T1, T0, T2);
  3127. emit_movi (j, T0, 0);
  3128. done = jit_jmp (j->jit);
  3129. jit_patch_here (j->jit, both);
  3130. /* 0 < s < 32: hi = hi << s + lo >> (32-s), lo = lo << s */
  3131. emit_negr (j, T3_OR_FP, T2);
  3132. emit_addi (j, T3_OR_FP, T3_OR_FP, 32);
  3133. emit_rshr_u (j, T3_OR_FP, T0, T3_OR_FP);
  3134. emit_lshr (j, T1, T1, T2);
  3135. emit_lshr (j, T0, T0, T2);
  3136. emit_addr (j, T1, T1, T3_OR_FP);
  3137. jit_patch_here (j->jit, done);
  3138. jit_patch_here (j->jit, zero);
  3139. emit_sp_set_u64 (j, dst, T0, T1);
  3140. #endif
  3141. }
  3142. static void
  3143. compile_ulsh_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3144. {
  3145. }
  3146. static void
  3147. compile_ursh_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3148. {
  3149. b &= 63;
  3150. #if SIZEOF_UINTPTR_T >= 8
  3151. emit_sp_ref_u64 (j, T0, a);
  3152. emit_rshi_u (j, T0, T0, b);
  3153. emit_sp_set_u64 (j, dst, T0);
  3154. #else
  3155. /* FIXME: Not tested. */
  3156. emit_sp_ref_u64 (j, T0, T1, a);
  3157. if (b == 0)
  3158. {
  3159. /* Nothing to do. */
  3160. }
  3161. else if (b < 32)
  3162. {
  3163. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  3164. emit_lshi (j, T2, T1, 32 - b);
  3165. emit_rshi_u (j, T1, T1, b);
  3166. emit_rshi_u (j, T0, T0, b);
  3167. emit_addr (j, T0, T0, T2);
  3168. }
  3169. else if (b == 32)
  3170. {
  3171. /* hi = 0, lo = hi */
  3172. emit_movr (j, T0, T1);
  3173. emit_movi (j, T1, 0);
  3174. }
  3175. else /* b > 32 */
  3176. {
  3177. /* hi = 0, lo = hi >> (s-32) */
  3178. emit_rshi_u (j, T0, T1, b - 32);
  3179. emit_movi (j, T1, 0);
  3180. }
  3181. emit_sp_set_u64 (j, dst, T0, T1);
  3182. #endif
  3183. }
  3184. static void
  3185. compile_ursh_immediate_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3186. {
  3187. }
  3188. static void
  3189. compile_ulsh_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3190. {
  3191. b &= 63;
  3192. #if SIZEOF_UINTPTR_T >= 8
  3193. emit_sp_ref_u64 (j, T0, a);
  3194. emit_lshi (j, T0, T0, b);
  3195. emit_sp_set_u64 (j, dst, T0);
  3196. #else
  3197. /* FIXME: Not tested. */
  3198. emit_sp_ref_u64 (j, T0, T1, a);
  3199. if (b == 0)
  3200. {
  3201. /* Nothing to do. */
  3202. }
  3203. else if (b < 32)
  3204. {
  3205. /* hi = hi << s + lo >> (32-s), lo = lo << s */
  3206. emit_rshi_u (j, T2, T0, 32 - b);
  3207. emit_lshi (j, T1, T1, b);
  3208. emit_lshi (j, T0, T0, b);
  3209. emit_addr (j, T1, T1, T2);
  3210. }
  3211. else if (b == 32)
  3212. {
  3213. /* hi = lo, lo = 0 */
  3214. emit_movr (j, T1, T0);
  3215. emit_movi (j, T0, 0);
  3216. }
  3217. else /* b > 32 */
  3218. {
  3219. /* hi = lo << (s-32), lo = 0 */
  3220. emit_lshi (j, T1, T0, b - 32);
  3221. emit_movi (j, T0, 0);
  3222. }
  3223. emit_sp_set_u64 (j, dst, T0, T1);
  3224. #endif
  3225. }
  3226. static void
  3227. compile_ulsh_immediate_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3228. {
  3229. }
  3230. static void
  3231. compile_ulogxor (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3232. {
  3233. #if SIZEOF_UINTPTR_T >= 8
  3234. emit_sp_ref_u64 (j, T0, a);
  3235. emit_sp_ref_u64 (j, T1, b);
  3236. emit_xorr (j, T0, T0, T1);
  3237. emit_sp_set_u64 (j, dst, T0);
  3238. #else
  3239. emit_sp_ref_u64 (j, T0, T1, a);
  3240. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  3241. emit_xorr (j, T0, T0, T2);
  3242. emit_xorr (j, T1, T1, T3_OR_FP);
  3243. emit_sp_set_u64 (j, dst, T0, T1);
  3244. #endif
  3245. }
  3246. static void
  3247. compile_ulogxor_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3248. {
  3249. }
  3250. static void
  3251. compile_handle_interrupts (scm_jit_state *j)
  3252. {
  3253. jit_addi (j->jit, T0, THREAD, thread_offset_pending_asyncs);
  3254. jit_ldr_atomic (j->jit, T0, T0);
  3255. add_slow_path_patch (j, jit_bnei (j->jit, T0, SCM_UNPACK (SCM_EOL)));
  3256. }
  3257. static void
  3258. compile_handle_interrupts_slow (scm_jit_state *j)
  3259. {
  3260. jit_ldxi_i (j->jit, T0, THREAD, thread_offset_block_asyncs);
  3261. add_inter_instruction_patch (j,
  3262. jit_bnei (j->jit, T0, 0),
  3263. j->next_ip);
  3264. emit_store_current_ip (j, T0);
  3265. jit_jmpi_with_link (j->jit, handle_interrupts_trampoline);
  3266. continue_after_slow_path (j, j->ip);
  3267. }
  3268. static void
  3269. compile_return_from_interrupt (scm_jit_state *j)
  3270. {
  3271. jit_gpr_t old_fp = T0, ra = T1;
  3272. jit_reloc_t interp;
  3273. emit_pop_fp (j, old_fp);
  3274. emit_load_mra (j, ra, old_fp);
  3275. interp = jit_beqi (j->jit, ra, 0);
  3276. jit_addi (j->jit, SP, old_fp, frame_overhead_slots * sizeof (union scm_vm_stack_element));
  3277. set_register_state (j, SP_IN_REGISTER);
  3278. emit_store_sp (j);
  3279. jit_jmpr (j->jit, ra);
  3280. jit_patch_here (j->jit, interp);
  3281. emit_load_vra (j, ra, old_fp);
  3282. emit_store_ip (j, ra);
  3283. jit_addi (j->jit, SP, old_fp, frame_overhead_slots * sizeof (union scm_vm_stack_element));
  3284. set_register_state (j, SP_IN_REGISTER);
  3285. emit_store_sp (j);
  3286. emit_exit (j);
  3287. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  3288. }
  3289. static void
  3290. compile_return_from_interrupt_slow (scm_jit_state *j)
  3291. {
  3292. }
  3293. static enum scm_opcode
  3294. fuse_conditional_branch (scm_jit_state *j, uint32_t **target)
  3295. {
  3296. uint8_t next = j->next_ip[0] & 0xff;
  3297. switch (next)
  3298. {
  3299. case scm_op_jl:
  3300. case scm_op_je:
  3301. case scm_op_jnl:
  3302. case scm_op_jne:
  3303. case scm_op_jge:
  3304. case scm_op_jnge:
  3305. *target = j->next_ip + (((int32_t) j->next_ip[0]) >> 8);
  3306. j->next_ip += op_lengths[next];
  3307. return next;
  3308. default:
  3309. ASSERT (0);
  3310. }
  3311. }
  3312. static void
  3313. compile_u64_numerically_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  3314. {
  3315. uint32_t *target;
  3316. #if SIZEOF_UINTPTR_T >= 8
  3317. jit_reloc_t k;
  3318. emit_sp_ref_u64 (j, T0, a);
  3319. emit_sp_ref_u64 (j, T1, b);
  3320. switch (fuse_conditional_branch (j, &target))
  3321. {
  3322. case scm_op_je:
  3323. k = jit_beqr (j->jit, T0, T1);
  3324. break;
  3325. case scm_op_jne:
  3326. k = jit_bner (j->jit, T0, T1);
  3327. break;
  3328. default:
  3329. UNREACHABLE ();
  3330. }
  3331. add_inter_instruction_patch (j, k, target);
  3332. #else
  3333. jit_reloc_t k1, k2;
  3334. emit_sp_ref_u64 (j, T0, T1, a);
  3335. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  3336. switch (fuse_conditional_branch (j, &target))
  3337. {
  3338. case scm_op_je:
  3339. k1 = jit_bner (j->jit, T0, T2);
  3340. k2 = jit_beqr (j->jit, T1, T3_OR_FP);
  3341. jit_patch_here (j->jit, k1);
  3342. add_inter_instruction_patch (j, k2, target);
  3343. break;
  3344. case scm_op_jne:
  3345. k1 = jit_bner (j->jit, T0, T2);
  3346. k2 = jit_bner (j->jit, T1, T3_OR_FP);
  3347. add_inter_instruction_patch (j, k1, target);
  3348. add_inter_instruction_patch (j, k2, target);
  3349. break;
  3350. default:
  3351. UNREACHABLE ();
  3352. }
  3353. #endif
  3354. }
  3355. static void
  3356. compile_u64_numerically_equal_slow (scm_jit_state *j, uint16_t a, uint16_t b)
  3357. {
  3358. }
  3359. static void
  3360. compile_u64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  3361. {
  3362. uint32_t *target;
  3363. #if SIZEOF_UINTPTR_T >= 8
  3364. jit_reloc_t k;
  3365. emit_sp_ref_u64 (j, T0, a);
  3366. emit_sp_ref_u64 (j, T1, b);
  3367. switch (fuse_conditional_branch (j, &target))
  3368. {
  3369. case scm_op_jl:
  3370. k = jit_bltr_u (j->jit, T0, T1);
  3371. break;
  3372. case scm_op_jnl:
  3373. k = jit_bger_u (j->jit, T0, T1);
  3374. break;
  3375. default:
  3376. UNREACHABLE ();
  3377. }
  3378. add_inter_instruction_patch (j, k, target);
  3379. #else
  3380. jit_reloc_t k1, k2, k3;
  3381. emit_sp_ref_u64 (j, T0, T1, a);
  3382. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  3383. k1 = jit_bltr_u (j->jit, T1, T3_OR_FP);
  3384. k2 = jit_bner (j->jit, T1, T3_OR_FP);
  3385. switch (fuse_conditional_branch (j, &target))
  3386. {
  3387. case scm_op_jl:
  3388. k3 = jit_bltr_u (j->jit, T0, T2);
  3389. jit_patch_here (j->jit, k2);
  3390. add_inter_instruction_patch (j, k1, target);
  3391. add_inter_instruction_patch (j, k3, target);
  3392. break;
  3393. case scm_op_jnl:
  3394. k3 = jit_bger_u (j->jit, T0, T2);
  3395. jit_patch_here (j->jit, k1);
  3396. add_inter_instruction_patch (j, k2, target);
  3397. add_inter_instruction_patch (j, k3, target);
  3398. break;
  3399. default:
  3400. UNREACHABLE ();
  3401. }
  3402. #endif
  3403. }
  3404. static void
  3405. compile_u64_less_slow (scm_jit_state *j, uint16_t a, uint16_t b)
  3406. {
  3407. }
  3408. static void
  3409. compile_s64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  3410. {
  3411. uint32_t *target;
  3412. #if SIZEOF_UINTPTR_T >= 8
  3413. jit_reloc_t k;
  3414. emit_sp_ref_s64 (j, T0, a);
  3415. emit_sp_ref_s64 (j, T1, b);
  3416. switch (fuse_conditional_branch (j, &target))
  3417. {
  3418. case scm_op_jl:
  3419. k = jit_bltr (j->jit, T0, T1);
  3420. break;
  3421. case scm_op_jnl:
  3422. k = jit_bger (j->jit, T0, T1);
  3423. break;
  3424. default:
  3425. UNREACHABLE ();
  3426. }
  3427. add_inter_instruction_patch (j, k, target);
  3428. #else
  3429. jit_reloc_t k1, k2, k3;
  3430. emit_sp_ref_s64 (j, T0, T1, a);
  3431. emit_sp_ref_s64 (j, T2, T3_OR_FP, b);
  3432. k1 = jit_bltr (j->jit, T1, T3_OR_FP);
  3433. k2 = jit_bner (j->jit, T1, T3_OR_FP);
  3434. switch (fuse_conditional_branch (j, &target))
  3435. {
  3436. case scm_op_jl:
  3437. k3 = jit_bltr (j->jit, T0, T2);
  3438. jit_patch_here (j->jit, k2);
  3439. add_inter_instruction_patch (j, k1, target);
  3440. add_inter_instruction_patch (j, k3, target);
  3441. break;
  3442. case scm_op_jnl:
  3443. k3 = jit_bger (j->jit, T0, T2);
  3444. jit_patch_here (j->jit, k1);
  3445. add_inter_instruction_patch (j, k2, target);
  3446. add_inter_instruction_patch (j, k3, target);
  3447. break;
  3448. default:
  3449. UNREACHABLE ();
  3450. }
  3451. #endif
  3452. }
  3453. static void
  3454. compile_s64_less_slow (scm_jit_state *j, uint16_t a, uint16_t b)
  3455. {
  3456. }
  3457. static void
  3458. compile_f64_numerically_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  3459. {
  3460. jit_reloc_t k;
  3461. uint32_t *target;
  3462. emit_sp_ref_f64 (j, JIT_F0, a);
  3463. emit_sp_ref_f64 (j, JIT_F1, b);
  3464. switch (fuse_conditional_branch (j, &target))
  3465. {
  3466. case scm_op_je:
  3467. k = jit_beqr_d (j->jit, JIT_F0, JIT_F1);
  3468. break;
  3469. case scm_op_jne:
  3470. k = jit_bner_d (j->jit, JIT_F0, JIT_F1);
  3471. break;
  3472. default:
  3473. UNREACHABLE ();
  3474. }
  3475. add_inter_instruction_patch (j, k, target);
  3476. }
  3477. static void
  3478. compile_f64_numerically_equal_slow (scm_jit_state *j, uint16_t a, uint16_t b)
  3479. {
  3480. }
  3481. static void
  3482. compile_f64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  3483. {
  3484. jit_reloc_t k;
  3485. uint32_t *target;
  3486. emit_sp_ref_f64 (j, JIT_F0, a);
  3487. emit_sp_ref_f64 (j, JIT_F1, b);
  3488. switch (fuse_conditional_branch (j, &target))
  3489. {
  3490. case scm_op_jl:
  3491. k = jit_bltr_d (j->jit, JIT_F0, JIT_F1);
  3492. break;
  3493. case scm_op_jnl:
  3494. k = jit_bunger_d (j->jit, JIT_F0, JIT_F1);
  3495. break;
  3496. case scm_op_jge:
  3497. k = jit_bger_d (j->jit, JIT_F0, JIT_F1);
  3498. break;
  3499. case scm_op_jnge:
  3500. k = jit_bunltr_d (j->jit, JIT_F0, JIT_F1);
  3501. break;
  3502. default:
  3503. UNREACHABLE ();
  3504. }
  3505. add_inter_instruction_patch (j, k, target);
  3506. }
  3507. static void
  3508. compile_f64_less_slow (scm_jit_state *j, uint16_t a, uint16_t b)
  3509. {
  3510. }
  3511. static void
  3512. compile_numerically_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  3513. {
  3514. jit_reloc_t k;
  3515. uint32_t *target;
  3516. emit_sp_ref_scm (j, T0, a);
  3517. emit_sp_ref_scm (j, T1, b);
  3518. emit_andr (j, T2, T0, T1);
  3519. add_slow_path_patch (j, jit_bmci (j->jit, T2, scm_tc2_int));
  3520. switch (fuse_conditional_branch (j, &target))
  3521. {
  3522. case scm_op_je:
  3523. k = jit_beqr (j->jit, T0, T1);
  3524. break;
  3525. case scm_op_jne:
  3526. k = jit_bner (j->jit, T0, T1);
  3527. break;
  3528. default:
  3529. UNREACHABLE ();
  3530. }
  3531. add_inter_instruction_patch (j, k, target);
  3532. }
  3533. static void
  3534. compile_numerically_equal_slow (scm_jit_state *j, uint16_t a, uint16_t b)
  3535. {
  3536. jit_reloc_t k;
  3537. uint32_t *target;
  3538. emit_store_current_ip (j, T2);
  3539. emit_call_2 (j, scm_vm_intrinsics.numerically_equal_p,
  3540. jit_operand_gpr (JIT_OPERAND_ABI_WORD, T0),
  3541. jit_operand_gpr (JIT_OPERAND_ABI_WORD, T1));
  3542. emit_retval (j, T0);
  3543. emit_reload_sp (j);
  3544. switch (fuse_conditional_branch (j, &target))
  3545. {
  3546. case scm_op_je:
  3547. k = jit_bnei (j->jit, T0, 0);
  3548. break;
  3549. case scm_op_jne:
  3550. k = jit_beqi (j->jit, T0, 0);
  3551. break;
  3552. default:
  3553. UNREACHABLE ();
  3554. }
  3555. add_inter_instruction_patch (j, k, target);
  3556. continue_after_slow_path (j, j->next_ip);
  3557. }
  3558. static void
  3559. compile_less (scm_jit_state *j, uint16_t a, uint16_t b)
  3560. {
  3561. jit_reloc_t k;
  3562. uint32_t *target;
  3563. emit_sp_ref_scm (j, T0, a);
  3564. emit_sp_ref_scm (j, T1, b);
  3565. emit_andr (j, T2, T0, T1);
  3566. add_slow_path_patch (j, jit_bmci (j->jit, T2, scm_tc2_int));
  3567. switch (fuse_conditional_branch (j, &target))
  3568. {
  3569. case scm_op_jl:
  3570. case scm_op_jnge:
  3571. k = jit_bltr (j->jit, T0, T1);
  3572. break;
  3573. case scm_op_jnl:
  3574. case scm_op_jge:
  3575. k = jit_bger (j->jit, T0, T1);
  3576. break;
  3577. default:
  3578. UNREACHABLE ();
  3579. }
  3580. add_inter_instruction_patch (j, k, target);
  3581. }
  3582. static void
  3583. compile_less_slow (scm_jit_state *j, uint16_t a, uint16_t b)
  3584. {
  3585. jit_reloc_t k;
  3586. uint32_t *target;
  3587. emit_store_current_ip (j, T2);
  3588. emit_call_2 (j, scm_vm_intrinsics.less_p,
  3589. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T0),
  3590. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T1));
  3591. emit_retval (j, T0);
  3592. emit_reload_sp (j);
  3593. switch (fuse_conditional_branch (j, &target))
  3594. {
  3595. case scm_op_jl:
  3596. k = jit_beqi (j->jit, T0, SCM_F_COMPARE_LESS_THAN);
  3597. break;
  3598. case scm_op_jnl:
  3599. k = jit_bnei (j->jit, T0, SCM_F_COMPARE_LESS_THAN);
  3600. break;
  3601. case scm_op_jge:
  3602. k = jit_beqi (j->jit, T0, SCM_F_COMPARE_NONE);
  3603. break;
  3604. case scm_op_jnge:
  3605. k = jit_bnei (j->jit, T0, SCM_F_COMPARE_NONE);
  3606. break;
  3607. default:
  3608. UNREACHABLE ();
  3609. }
  3610. add_inter_instruction_patch (j, k, target);
  3611. continue_after_slow_path (j, j->next_ip);
  3612. }
  3613. static void
  3614. compile_check_arguments (scm_jit_state *j, uint32_t expected)
  3615. {
  3616. jit_reloc_t k;
  3617. uint32_t *target;
  3618. jit_gpr_t t = T0;
  3619. emit_reload_fp (j);
  3620. switch (fuse_conditional_branch (j, &target))
  3621. {
  3622. case scm_op_jne:
  3623. k = emit_branch_if_frame_locals_count_not_eq (j, t, expected);
  3624. break;
  3625. case scm_op_jl:
  3626. k = emit_branch_if_frame_locals_count_less_than (j, t, expected);
  3627. break;
  3628. case scm_op_jge:
  3629. /* The arguments<=? instruction sets NONE to indicate
  3630. greater-than, whereas for <, NONE usually indicates
  3631. greater-than-or-equal, hence the name jge. So we need to fuse
  3632. to greater-than, not greater-than-or-equal. Perhaps we just
  3633. need to rename jge to br-if-none. */
  3634. k = emit_branch_if_frame_locals_count_greater_than (j, t, expected);
  3635. break;
  3636. default:
  3637. UNREACHABLE ();
  3638. }
  3639. add_inter_instruction_patch (j, k, target);
  3640. }
  3641. static void
  3642. compile_check_arguments_slow (scm_jit_state *j, uint32_t expected)
  3643. {
  3644. }
  3645. static void
  3646. compile_check_positional_arguments (scm_jit_state *j, uint32_t nreq, uint32_t expected)
  3647. {
  3648. uint32_t *target;
  3649. jit_reloc_t lt, gt;
  3650. jit_gpr_t walk = T0, min = T1, obj = T2;
  3651. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER | SP_IN_REGISTER);
  3652. switch (fuse_conditional_branch (j, &target))
  3653. {
  3654. case scm_op_jge:
  3655. /* Like arguments<=?, this instruction sets NONE to indicate
  3656. greater-than, whereas for <, NONE usually indicates
  3657. greater-than-or-equal, hence the name jge. So we need to fuse
  3658. to greater-than, not greater-than-or-equal. Perhaps we just
  3659. need to rename jge to br-if-none. */
  3660. /* Break to target if npos > expected. */
  3661. break;
  3662. default:
  3663. UNREACHABLE ();
  3664. }
  3665. emit_subtract_stack_slots (j, min, FP, expected);
  3666. emit_subtract_stack_slots (j, walk, FP, nreq);
  3667. void *head = jit_address (j->jit);
  3668. /* npos > expected if walk < min. */
  3669. gt = jit_bltr (j->jit, walk, min);
  3670. emit_subtract_stack_slots (j, walk, walk, 1);
  3671. lt = jit_bltr (j->jit, walk, SP);
  3672. emit_ldr (j, obj, walk);
  3673. jit_patch_there
  3674. (j->jit,
  3675. emit_branch_if_immediate (j, obj),
  3676. head);
  3677. jit_patch_there
  3678. (j->jit,
  3679. emit_branch_if_heap_object_not_tc7 (j, obj, obj, scm_tc7_keyword),
  3680. head);
  3681. jit_patch_here (j->jit, lt);
  3682. add_inter_instruction_patch (j, gt, target);
  3683. }
  3684. static void
  3685. compile_check_positional_arguments_slow (scm_jit_state *j, uint32_t nreq, uint32_t expected)
  3686. {
  3687. }
  3688. static void
  3689. compile_immediate_tag_equals (scm_jit_state *j, uint32_t a, uint16_t mask,
  3690. uint16_t expected)
  3691. {
  3692. jit_reloc_t k;
  3693. uint32_t *target;
  3694. emit_sp_ref_scm (j, T0, a);
  3695. emit_andi (j, T0, T0, mask);
  3696. switch (fuse_conditional_branch (j, &target))
  3697. {
  3698. case scm_op_je:
  3699. k = jit_beqi (j->jit, T0, expected);
  3700. break;
  3701. case scm_op_jne:
  3702. k = jit_bnei (j->jit, T0, expected);
  3703. break;
  3704. default:
  3705. UNREACHABLE ();
  3706. }
  3707. add_inter_instruction_patch (j, k, target);
  3708. }
  3709. static void
  3710. compile_immediate_tag_equals_slow (scm_jit_state *j, uint32_t a, uint16_t mask,
  3711. uint16_t expected)
  3712. {
  3713. }
  3714. static void
  3715. compile_heap_tag_equals (scm_jit_state *j, uint32_t obj,
  3716. uint16_t mask, uint16_t expected)
  3717. {
  3718. jit_reloc_t k;
  3719. uint32_t *target;
  3720. emit_sp_ref_scm (j, T0, obj);
  3721. switch (fuse_conditional_branch (j, &target))
  3722. {
  3723. case scm_op_je:
  3724. k = emit_branch_if_heap_object_has_tc (j, T0, T0, mask, expected);
  3725. break;
  3726. case scm_op_jne:
  3727. k = emit_branch_if_heap_object_not_tc (j, T0, T0, mask, expected);
  3728. break;
  3729. default:
  3730. UNREACHABLE ();
  3731. }
  3732. add_inter_instruction_patch (j, k, target);
  3733. }
  3734. static void
  3735. compile_heap_tag_equals_slow (scm_jit_state *j, uint32_t obj,
  3736. uint16_t mask, uint16_t expected)
  3737. {
  3738. }
  3739. static void
  3740. compile_eq (scm_jit_state *j, uint16_t a, uint16_t b)
  3741. {
  3742. jit_reloc_t k;
  3743. uint32_t *target;
  3744. emit_sp_ref_scm (j, T0, a);
  3745. emit_sp_ref_scm (j, T1, b);
  3746. switch (fuse_conditional_branch (j, &target))
  3747. {
  3748. case scm_op_je:
  3749. k = jit_beqr (j->jit, T0, T1);
  3750. break;
  3751. case scm_op_jne:
  3752. k = jit_bner (j->jit, T0, T1);
  3753. break;
  3754. default:
  3755. UNREACHABLE ();
  3756. }
  3757. add_inter_instruction_patch (j, k, target);
  3758. }
  3759. static void
  3760. compile_eq_slow (scm_jit_state *j, uint16_t a, uint16_t b)
  3761. {
  3762. }
  3763. static void
  3764. compile_eq_immediate (scm_jit_state *j, uint16_t a, SCM b)
  3765. {
  3766. jit_reloc_t k;
  3767. uint32_t *target;
  3768. emit_sp_ref_scm (j, T0, a);
  3769. switch (fuse_conditional_branch (j, &target))
  3770. {
  3771. case scm_op_je:
  3772. k = jit_beqi (j->jit, T0, SCM_UNPACK (b));
  3773. break;
  3774. case scm_op_jne:
  3775. k = jit_bnei (j->jit, T0, SCM_UNPACK (b));
  3776. break;
  3777. default:
  3778. UNREACHABLE ();
  3779. }
  3780. add_inter_instruction_patch (j, k, target);
  3781. }
  3782. static void
  3783. compile_eq_immediate_slow (scm_jit_state *j, uint16_t a, SCM b)
  3784. {
  3785. }
  3786. static void
  3787. compile_j (scm_jit_state *j, const uint32_t *vcode)
  3788. {
  3789. jit_reloc_t jmp;
  3790. jmp = jit_jmp (j->jit);
  3791. add_inter_instruction_patch (j, jmp, vcode);
  3792. }
  3793. static void
  3794. compile_j_slow (scm_jit_state *j, const uint32_t *vcode)
  3795. {
  3796. }
  3797. static void
  3798. compile_jl (scm_jit_state *j, const uint32_t *vcode)
  3799. {
  3800. UNREACHABLE (); /* All tests should fuse their following branches. */
  3801. }
  3802. static void
  3803. compile_jl_slow (scm_jit_state *j, const uint32_t *vcode)
  3804. {
  3805. }
  3806. static void
  3807. compile_je (scm_jit_state *j, const uint32_t *vcode)
  3808. {
  3809. UNREACHABLE (); /* All tests should fuse their following branches. */
  3810. }
  3811. static void
  3812. compile_je_slow (scm_jit_state *j, const uint32_t *vcode)
  3813. {
  3814. }
  3815. static void
  3816. compile_jnl (scm_jit_state *j, const uint32_t *vcode)
  3817. {
  3818. UNREACHABLE (); /* All tests should fuse their following branches. */
  3819. }
  3820. static void
  3821. compile_jnl_slow (scm_jit_state *j, const uint32_t *vcode)
  3822. {
  3823. }
  3824. static void
  3825. compile_jne (scm_jit_state *j, const uint32_t *vcode)
  3826. {
  3827. UNREACHABLE (); /* All tests should fuse their following branches. */
  3828. }
  3829. static void
  3830. compile_jne_slow (scm_jit_state *j, const uint32_t *vcode)
  3831. {
  3832. }
  3833. static void
  3834. compile_jge (scm_jit_state *j, const uint32_t *vcode)
  3835. {
  3836. UNREACHABLE (); /* All tests should fuse their following branches. */
  3837. }
  3838. static void
  3839. compile_jge_slow (scm_jit_state *j, const uint32_t *vcode)
  3840. {
  3841. }
  3842. static void
  3843. compile_jnge (scm_jit_state *j, const uint32_t *vcode)
  3844. {
  3845. UNREACHABLE (); /* All tests should fuse their following branches. */
  3846. }
  3847. static void
  3848. compile_jnge_slow (scm_jit_state *j, const uint32_t *vcode)
  3849. {
  3850. }
  3851. static void
  3852. compile_jtable (scm_jit_state *j, uint32_t idx, uint32_t len,
  3853. const uint32_t *offsets)
  3854. {
  3855. ASSERT (len > 0);
  3856. int32_t default_offset = offsets[len - 1];
  3857. default_offset >>= 8; /* Sign-extending shift. */
  3858. uint32_t *default_target = j->ip + default_offset;
  3859. #if SIZEOF_UINTPTR_T >= 8
  3860. emit_sp_ref_u64 (j, T0, idx);
  3861. #else
  3862. emit_sp_ref_u64 (j, T0, T1, idx);
  3863. jit_reloc_t high_word_nonzero = jit_bnei (j->jit, T1, 0);
  3864. add_inter_instruction_patch (j, high_word_nonzero, default_target);
  3865. #endif
  3866. jit_reloc_t out_of_range = jit_bgei_u (j->jit, T0, len - 1);
  3867. add_inter_instruction_patch (j, out_of_range, default_target);
  3868. /* Now that we know that the u64 at IDX is in the table, load the
  3869. table address, look up the target, and branch. */
  3870. emit_lshi (j, T0, T0, log2_sizeof_uintptr_t);
  3871. jit_reloc_t table = emit_mov_addr (j, T1);
  3872. jit_ldxr (j->jit, T0, T1, T0);
  3873. jit_jmpr (j->jit, T0);
  3874. /* Here's the table itself. */
  3875. jit_begin_data (j->jit, sizeof(intptr_t) * len);
  3876. jit_align (j->jit, sizeof(intptr_t));
  3877. jit_patch_here (j->jit, table);
  3878. for (size_t i = 0; i + 1 < len; i++) {
  3879. int32_t offset = offsets[i];
  3880. offset >>= 8; /* Sign-extending shift. */
  3881. uint32_t *target = j->ip + offset;
  3882. jit_reloc_t addr = jit_emit_addr (j->jit);
  3883. add_inter_instruction_patch (j, addr, target);
  3884. }
  3885. jit_end_data (j->jit);
  3886. }
  3887. static void
  3888. compile_jtable_slow (scm_jit_state *j, uint32_t idx, uint32_t len,
  3889. const uint32_t *offsets)
  3890. {
  3891. }
  3892. static void
  3893. compile_heap_numbers_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  3894. {
  3895. jit_reloc_t k;
  3896. uint32_t *target;
  3897. emit_store_current_ip (j, T0);
  3898. emit_call_2 (j, scm_vm_intrinsics.heap_numbers_equal_p, sp_scm_operand (j, a),
  3899. sp_scm_operand (j, b));
  3900. emit_retval (j, T0);
  3901. emit_reload_sp (j);
  3902. switch (fuse_conditional_branch (j, &target))
  3903. {
  3904. case scm_op_je:
  3905. k = jit_bnei (j->jit, T0, 0);
  3906. break;
  3907. case scm_op_jne:
  3908. k = jit_beqi (j->jit, T0, 0);
  3909. break;
  3910. default:
  3911. UNREACHABLE ();
  3912. }
  3913. add_inter_instruction_patch (j, k, target);
  3914. }
  3915. static void
  3916. compile_heap_numbers_equal_slow (scm_jit_state *j, uint16_t a, uint16_t b)
  3917. {
  3918. }
  3919. static void
  3920. compile_untag_fixnum (scm_jit_state *j, uint16_t dst, uint16_t a)
  3921. {
  3922. emit_sp_ref_scm (j, T0, a);
  3923. emit_rshi (j, T0, T0, 2);
  3924. #if SIZEOF_UINTPTR_T >= 8
  3925. emit_sp_set_s64 (j, dst, T0);
  3926. #else
  3927. /* FIXME: Untested! */
  3928. emit_rshi (j, T1, T0, 31);
  3929. emit_sp_set_s64 (j, dst, T0, T1);
  3930. #endif
  3931. }
  3932. static void
  3933. compile_untag_fixnum_slow (scm_jit_state *j, uint16_t dst, uint16_t a)
  3934. {
  3935. }
  3936. static void
  3937. compile_tag_fixnum (scm_jit_state *j, uint16_t dst, uint16_t a)
  3938. {
  3939. #if SIZEOF_UINTPTR_T >= 8
  3940. emit_sp_ref_s64 (j, T0, a);
  3941. #else
  3942. emit_sp_ref_s32 (j, T0, a);
  3943. #endif
  3944. emit_lshi (j, T0, T0, 2);
  3945. emit_addi (j, T0, T0, scm_tc2_int);
  3946. emit_sp_set_scm (j, dst, T0);
  3947. }
  3948. static void
  3949. compile_tag_fixnum_slow (scm_jit_state *j, uint16_t dst, uint16_t a)
  3950. {
  3951. }
  3952. static void
  3953. compile_srsh (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3954. {
  3955. #if SIZEOF_UINTPTR_T >= 8
  3956. emit_sp_ref_s64 (j, T0, a);
  3957. emit_sp_ref_s64 (j, T1, b);
  3958. emit_andi (j, T1, T1, 63);
  3959. emit_rshr (j, T0, T0, T1);
  3960. emit_sp_set_s64 (j, dst, T0);
  3961. #else
  3962. /* FIXME: Not tested. */
  3963. jit_reloc_t zero, both, done;
  3964. emit_sp_ref_s64 (j, T0, T1, a);
  3965. emit_sp_ref_s64 (j, T2, T3_OR_FP, b);
  3966. emit_andi (j, T2, T2, 63);
  3967. zero = jit_beqi (j->jit, T2, 0);
  3968. both = jit_blti (j->jit, T2, 32);
  3969. /* 32 <= s < 64: hi = hi >> 31, lo = hi >> (s-32) */
  3970. emit_subi (j, T2, T2, 32);
  3971. emit_rshr (j, T0, T1, T2);
  3972. emit_rshi (j, T1, T1, 31);
  3973. done = jit_jmp (j->jit);
  3974. jit_patch_here (j->jit, both);
  3975. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  3976. emit_negr (j, T3_OR_FP, T2);
  3977. emit_addi (j, T3_OR_FP, T3_OR_FP, 32);
  3978. emit_lshr (j, T3_OR_FP, T1, T3_OR_FP);
  3979. emit_rshr (j, T1, T1, T2);
  3980. emit_rshr_u (j, T0, T0, T2);
  3981. emit_addr (j, T0, T0, T3_OR_FP);
  3982. jit_patch_here (j->jit, done);
  3983. jit_patch_here (j->jit, zero);
  3984. emit_sp_set_s64 (j, dst, T0, T1);
  3985. #endif
  3986. }
  3987. static void
  3988. compile_srsh_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3989. {
  3990. }
  3991. static void
  3992. compile_srsh_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3993. {
  3994. b &= 63;
  3995. #if SIZEOF_UINTPTR_T >= 8
  3996. emit_sp_ref_s64 (j, T0, a);
  3997. emit_rshi (j, T0, T0, b);
  3998. emit_sp_set_s64 (j, dst, T0);
  3999. #else
  4000. /* FIXME: Not tested. */
  4001. emit_sp_ref_s64 (j, T0, T1, a);
  4002. if (b == 0)
  4003. {
  4004. /* Nothing to do. */
  4005. }
  4006. else if (b < 32)
  4007. {
  4008. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  4009. emit_lshi (j, T2, T1, 32 - b);
  4010. emit_rshi (j, T1, T1, b);
  4011. emit_rshi_u (j, T0, T0, b);
  4012. emit_addr (j, T0, T0, T2);
  4013. }
  4014. else if (b == 32)
  4015. {
  4016. /* hi = sign-ext, lo = hi */
  4017. emit_movr (j, T0, T1);
  4018. emit_rshi (j, T1, T1, 31);
  4019. }
  4020. else /* b > 32 */
  4021. {
  4022. /* hi = sign-ext, lo = hi >> (s-32) */
  4023. emit_rshi (j, T0, T1, b - 32);
  4024. emit_rshi (j, T1, T1, 31);
  4025. }
  4026. emit_sp_set_s64 (j, dst, T0, T1);
  4027. #endif
  4028. }
  4029. static void
  4030. compile_srsh_immediate_slow (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  4031. {
  4032. }
  4033. static void
  4034. compile_s64_imm_numerically_equal (scm_jit_state *j, uint16_t a, int16_t b)
  4035. {
  4036. #if SIZEOF_UINTPTR_T >= 8
  4037. jit_reloc_t k;
  4038. uint32_t *target;
  4039. emit_sp_ref_s64 (j, T0, a);
  4040. switch (fuse_conditional_branch (j, &target))
  4041. {
  4042. case scm_op_je:
  4043. k = jit_beqi (j->jit, T0, b);
  4044. break;
  4045. case scm_op_jne:
  4046. k = jit_bnei (j->jit, T0, b);
  4047. break;
  4048. default:
  4049. UNREACHABLE ();
  4050. }
  4051. add_inter_instruction_patch (j, k, target);
  4052. #else
  4053. jit_reloc_t k1, k2;
  4054. uint32_t *target;
  4055. emit_sp_ref_s64 (j, T0, T1, a);
  4056. switch (fuse_conditional_branch (j, &target))
  4057. {
  4058. case scm_op_je:
  4059. k1 = jit_bnei (j->jit, T0, b);
  4060. k2 = jit_beqi (j->jit, T1, b < 0 ? -1 : 0);
  4061. jit_patch_here (j->jit, k1);
  4062. add_inter_instruction_patch (j, k2, target);
  4063. break;
  4064. case scm_op_jne:
  4065. k1 = jit_bnei (j->jit, T0, b);
  4066. k2 = jit_bnei (j->jit, T1, b < 0 ? -1 : 0);
  4067. add_inter_instruction_patch (j, k1, target);
  4068. add_inter_instruction_patch (j, k2, target);
  4069. break;
  4070. default:
  4071. UNREACHABLE ();
  4072. }
  4073. #endif
  4074. }
  4075. static void
  4076. compile_s64_imm_numerically_equal_slow (scm_jit_state *j, uint16_t a, int16_t b)
  4077. {
  4078. }
  4079. static void
  4080. compile_u64_imm_less (scm_jit_state *j, uint16_t a, uint16_t b)
  4081. {
  4082. #if SIZEOF_UINTPTR_T >= 8
  4083. jit_reloc_t k;
  4084. uint32_t *target;
  4085. emit_sp_ref_u64 (j, T0, a);
  4086. switch (fuse_conditional_branch (j, &target))
  4087. {
  4088. case scm_op_jl:
  4089. k = jit_blti_u (j->jit, T0, b);
  4090. break;
  4091. case scm_op_jnl:
  4092. k = jit_bgei_u (j->jit, T0, b);
  4093. break;
  4094. default:
  4095. UNREACHABLE ();
  4096. }
  4097. add_inter_instruction_patch (j, k, target);
  4098. #else
  4099. jit_reloc_t k1, k2;
  4100. uint32_t *target;
  4101. emit_sp_ref_u64 (j, T0, T1, a);
  4102. switch (fuse_conditional_branch (j, &target))
  4103. {
  4104. case scm_op_jl:
  4105. k1 = jit_bnei (j->jit, T1, 0);
  4106. k2 = jit_blti_u (j->jit, T0, b);
  4107. jit_patch_here (j->jit, k1);
  4108. add_inter_instruction_patch (j, k2, target);
  4109. break;
  4110. case scm_op_jnl:
  4111. k1 = jit_bnei (j->jit, T1, 0);
  4112. k2 = jit_bgei_u (j->jit, T0, b);
  4113. add_inter_instruction_patch (j, k1, target);
  4114. add_inter_instruction_patch (j, k2, target);
  4115. break;
  4116. default:
  4117. UNREACHABLE ();
  4118. }
  4119. #endif
  4120. }
  4121. static void
  4122. compile_u64_imm_less_slow (scm_jit_state *j, uint16_t a, uint16_t b)
  4123. {
  4124. }
  4125. static void
  4126. compile_imm_u64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  4127. {
  4128. #if SIZEOF_UINTPTR_T >= 8
  4129. jit_reloc_t k;
  4130. uint32_t *target;
  4131. emit_sp_ref_u64 (j, T0, a);
  4132. switch (fuse_conditional_branch (j, &target))
  4133. {
  4134. case scm_op_jl:
  4135. k = jit_bgti_u (j->jit, T0, b);
  4136. break;
  4137. case scm_op_jnl:
  4138. k = jit_blei_u (j->jit, T0, b);
  4139. break;
  4140. default:
  4141. UNREACHABLE ();
  4142. }
  4143. add_inter_instruction_patch (j, k, target);
  4144. #else
  4145. jit_reloc_t k1, k2;
  4146. uint32_t *target;
  4147. emit_sp_ref_u64 (j, T0, T1, a);
  4148. switch (fuse_conditional_branch (j, &target))
  4149. {
  4150. case scm_op_jl:
  4151. k1 = jit_bnei (j->jit, T1, 0);
  4152. k2 = jit_bgti_u (j->jit, T0, b);
  4153. add_inter_instruction_patch (j, k1, target);
  4154. add_inter_instruction_patch (j, k2, target);
  4155. break;
  4156. case scm_op_jnl:
  4157. k1 = jit_bnei (j->jit, T1, 0);
  4158. k2 = jit_blei_u (j->jit, T0, b);
  4159. jit_patch_here (j->jit, k1);
  4160. add_inter_instruction_patch (j, k2, target);
  4161. break;
  4162. default:
  4163. UNREACHABLE ();
  4164. }
  4165. #endif
  4166. }
  4167. static void
  4168. compile_imm_u64_less_slow (scm_jit_state *j, uint16_t a, uint16_t b)
  4169. {
  4170. }
  4171. static void
  4172. compile_s64_imm_less (scm_jit_state *j, uint16_t a, int16_t b)
  4173. {
  4174. #if SIZEOF_UINTPTR_T >= 8
  4175. jit_reloc_t k;
  4176. uint32_t *target;
  4177. emit_sp_ref_s64 (j, T0, a);
  4178. switch (fuse_conditional_branch (j, &target))
  4179. {
  4180. case scm_op_jl:
  4181. k = jit_blti (j->jit, T0, b);
  4182. break;
  4183. case scm_op_jnl:
  4184. k = jit_bgei (j->jit, T0, b);
  4185. break;
  4186. default:
  4187. UNREACHABLE ();
  4188. }
  4189. add_inter_instruction_patch (j, k, target);
  4190. #else
  4191. jit_reloc_t k1, k2, k3;
  4192. int32_t sign = b < 0 ? -1 : 0;
  4193. uint32_t *target;
  4194. emit_sp_ref_s64 (j, T0, T1, a);
  4195. switch (fuse_conditional_branch (j, &target))
  4196. {
  4197. case scm_op_jl:
  4198. k1 = jit_blti (j->jit, T1, sign);
  4199. k2 = jit_bnei (j->jit, T1, sign);
  4200. k3 = jit_blti (j->jit, T0, b);
  4201. add_inter_instruction_patch (j, k1, target);
  4202. jit_patch_here (j->jit, k2);
  4203. add_inter_instruction_patch (j, k3, target);
  4204. break;
  4205. case scm_op_jnl:
  4206. k1 = jit_blti (j->jit, T1, sign);
  4207. k2 = jit_bnei (j->jit, T1, sign);
  4208. k3 = jit_bgei (j->jit, T0, b);
  4209. jit_patch_here (j->jit, k1);
  4210. add_inter_instruction_patch (j, k2, target);
  4211. add_inter_instruction_patch (j, k3, target);
  4212. break;
  4213. default:
  4214. UNREACHABLE ();
  4215. }
  4216. #endif
  4217. }
  4218. static void
  4219. compile_s64_imm_less_slow (scm_jit_state *j, uint16_t a, int16_t b)
  4220. {
  4221. }
  4222. static void
  4223. compile_imm_s64_less (scm_jit_state *j, uint16_t a, int16_t b)
  4224. {
  4225. #if SIZEOF_UINTPTR_T >= 8
  4226. jit_reloc_t k;
  4227. uint32_t *target;
  4228. emit_sp_ref_s64 (j, T0, a);
  4229. switch (fuse_conditional_branch (j, &target))
  4230. {
  4231. case scm_op_jl:
  4232. k = jit_bgti (j->jit, T0, b);
  4233. break;
  4234. case scm_op_jnl:
  4235. k = jit_blei (j->jit, T0, b);
  4236. break;
  4237. default:
  4238. UNREACHABLE ();
  4239. }
  4240. add_inter_instruction_patch (j, k, target);
  4241. #else
  4242. jit_reloc_t k1, k2, k3;
  4243. int32_t sign = b < 0 ? -1 : 0;
  4244. uint32_t *target;
  4245. emit_sp_ref_s64 (j, T0, T1, a);
  4246. switch (fuse_conditional_branch (j, &target))
  4247. {
  4248. case scm_op_jl:
  4249. k1 = jit_blti (j->jit, T1, sign);
  4250. k2 = jit_bnei (j->jit, T1, sign);
  4251. k3 = jit_bgti (j->jit, T0, b);
  4252. jit_patch_here (j->jit, k1);
  4253. add_inter_instruction_patch (j, k2, target);
  4254. add_inter_instruction_patch (j, k3, target);
  4255. break;
  4256. case scm_op_jnl:
  4257. k1 = jit_blti (j->jit, T1, sign);
  4258. k2 = jit_bnei (j->jit, T1, sign);
  4259. k3 = jit_blei (j->jit, T0, b);
  4260. add_inter_instruction_patch (j, k1, target);
  4261. jit_patch_here (j->jit, k2);
  4262. add_inter_instruction_patch (j, k3, target);
  4263. break;
  4264. default:
  4265. UNREACHABLE ();
  4266. }
  4267. #endif
  4268. }
  4269. static void
  4270. compile_imm_s64_less_slow (scm_jit_state *j, uint16_t a, int16_t b)
  4271. {
  4272. }
  4273. static void
  4274. compile_u8_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4275. {
  4276. emit_sp_ref_ptr (j, T0, ptr);
  4277. emit_sp_ref_sz (j, T1, idx);
  4278. jit_ldxr_uc (j->jit, T0, T0, T1);
  4279. record_gpr_clobber (j, T0);
  4280. #if SIZEOF_UINTPTR_T >= 8
  4281. emit_sp_set_u64 (j, dst, T0);
  4282. #else
  4283. emit_movi (j, T1, 0);
  4284. emit_sp_set_u64 (j, dst, T0, T1);
  4285. #endif
  4286. }
  4287. static void
  4288. compile_u8_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4289. {
  4290. }
  4291. static void
  4292. compile_u16_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4293. {
  4294. emit_sp_ref_ptr (j, T0, ptr);
  4295. emit_sp_ref_sz (j, T1, idx);
  4296. jit_ldxr_us (j->jit, T0, T0, T1);
  4297. record_gpr_clobber (j, T0);
  4298. #if SIZEOF_UINTPTR_T >= 8
  4299. emit_sp_set_u64 (j, dst, T0);
  4300. #else
  4301. emit_movi (j, T1, 0);
  4302. emit_sp_set_u64 (j, dst, T0, T1);
  4303. #endif
  4304. }
  4305. static void
  4306. compile_u16_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4307. {
  4308. }
  4309. static void
  4310. compile_u32_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4311. {
  4312. emit_sp_ref_ptr (j, T0, ptr);
  4313. emit_sp_ref_sz (j, T1, idx);
  4314. #if SIZEOF_UINTPTR_T >= 8
  4315. jit_ldxr_ui (j->jit, T0, T0, T1);
  4316. record_gpr_clobber (j, T0);
  4317. emit_sp_set_u64 (j, dst, T0);
  4318. #else
  4319. emit_ldxr (j, T0, T0, T1);
  4320. emit_movi (j, T1, 0);
  4321. emit_sp_set_u64 (j, dst, T0, T1);
  4322. #endif
  4323. }
  4324. static void
  4325. compile_u32_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4326. {
  4327. }
  4328. static void
  4329. compile_u64_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4330. {
  4331. emit_sp_ref_ptr (j, T0, ptr);
  4332. emit_sp_ref_sz (j, T1, idx);
  4333. #if SIZEOF_UINTPTR_T >= 8
  4334. emit_ldxr (j, T0, T0, T1);
  4335. emit_sp_set_u64 (j, dst, T0);
  4336. #else
  4337. emit_addr (j, T0, T0, T1);
  4338. if (BIGENDIAN)
  4339. {
  4340. emit_ldr (j, T1, T0);
  4341. emit_ldxi (j, T0, T0, 4);
  4342. }
  4343. else
  4344. {
  4345. emit_ldxi (j, T1, T0, 4);
  4346. emit_ldr (j, T0, T0);
  4347. }
  4348. emit_sp_set_u64 (j, dst, T0, T1);
  4349. #endif
  4350. }
  4351. static void
  4352. compile_u64_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4353. {
  4354. }
  4355. static void
  4356. compile_u8_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4357. {
  4358. emit_sp_ref_ptr (j, T0, ptr);
  4359. emit_sp_ref_sz (j, T1, idx);
  4360. #if SIZEOF_UINTPTR_T >= 8
  4361. emit_sp_ref_u64 (j, T2, v);
  4362. #else
  4363. emit_sp_ref_u64_lower_half (j, T2, v);
  4364. #endif
  4365. jit_stxr_c (j->jit, T0, T1, T2);
  4366. }
  4367. static void
  4368. compile_u8_set_slow (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4369. {
  4370. }
  4371. static void
  4372. compile_u16_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4373. {
  4374. emit_sp_ref_ptr (j, T0, ptr);
  4375. emit_sp_ref_sz (j, T1, idx);
  4376. #if SIZEOF_UINTPTR_T >= 8
  4377. emit_sp_ref_u64 (j, T2, v);
  4378. #else
  4379. emit_sp_ref_u64_lower_half (j, T2, v);
  4380. #endif
  4381. jit_stxr_s (j->jit, T0, T1, T2);
  4382. }
  4383. static void
  4384. compile_u16_set_slow (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4385. {
  4386. }
  4387. static void
  4388. compile_u32_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4389. {
  4390. emit_sp_ref_ptr (j, T0, ptr);
  4391. emit_sp_ref_sz (j, T1, idx);
  4392. #if SIZEOF_UINTPTR_T >= 8
  4393. emit_sp_ref_u64 (j, T2, v);
  4394. jit_stxr_i (j->jit, T0, T1, T2);
  4395. #else
  4396. emit_sp_ref_u64_lower_half (j, T2, v);
  4397. jit_stxr (j->jit, T0, T1, T2);
  4398. #endif
  4399. }
  4400. static void
  4401. compile_u32_set_slow (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4402. {
  4403. }
  4404. static void
  4405. compile_u64_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4406. {
  4407. emit_sp_ref_ptr (j, T0, ptr);
  4408. emit_sp_ref_sz (j, T1, idx);
  4409. #if SIZEOF_UINTPTR_T >= 8
  4410. emit_sp_ref_u64 (j, T2, v);
  4411. jit_stxr (j->jit, T0, T1, T2);
  4412. #else
  4413. jit_addr (j->jit, T0, T0, T1);
  4414. emit_sp_ref_u64 (j, T1, T2, v);
  4415. if (BIGENDIAN)
  4416. {
  4417. jit_str (j->jit, T0, T2);
  4418. jit_stxi (j->jit, 4, T0, T1);
  4419. }
  4420. else
  4421. {
  4422. jit_str (j->jit, T0, T1);
  4423. jit_stxi (j->jit, 4, T0, T2);
  4424. }
  4425. #endif
  4426. }
  4427. static void
  4428. compile_u64_set_slow (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4429. {
  4430. }
  4431. static void
  4432. compile_s8_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4433. {
  4434. emit_sp_ref_ptr (j, T0, ptr);
  4435. emit_sp_ref_sz (j, T1, idx);
  4436. jit_ldxr_c (j->jit, T0, T0, T1);
  4437. record_gpr_clobber (j, T0);
  4438. #if SIZEOF_UINTPTR_T >= 8
  4439. emit_sp_set_s64 (j, dst, T0);
  4440. #else
  4441. emit_rshi (j, T1, T0, 7);
  4442. emit_sp_set_u64 (j, dst, T0, T1);
  4443. #endif
  4444. }
  4445. static void
  4446. compile_s8_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4447. {
  4448. }
  4449. static void
  4450. compile_s16_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4451. {
  4452. emit_sp_ref_ptr (j, T0, ptr);
  4453. emit_sp_ref_sz (j, T1, idx);
  4454. jit_ldxr_s (j->jit, T0, T0, T1);
  4455. record_gpr_clobber (j, T0);
  4456. #if SIZEOF_UINTPTR_T >= 8
  4457. emit_sp_set_s64 (j, dst, T0);
  4458. #else
  4459. emit_rshi (j, T1, T0, 15);
  4460. emit_sp_set_u64 (j, dst, T0, T1);
  4461. #endif
  4462. }
  4463. static void
  4464. compile_s16_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4465. {
  4466. }
  4467. static void
  4468. compile_s32_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4469. {
  4470. emit_sp_ref_ptr (j, T0, ptr);
  4471. emit_sp_ref_sz (j, T1, idx);
  4472. jit_ldxr_i (j->jit, T0, T0, T1);
  4473. record_gpr_clobber (j, T0);
  4474. #if SIZEOF_UINTPTR_T >= 8
  4475. emit_sp_set_s64 (j, dst, T0);
  4476. #else
  4477. emit_rshi (j, T1, T0, 31);
  4478. emit_sp_set_u64 (j, dst, T0, T1);
  4479. #endif
  4480. }
  4481. static void
  4482. compile_s32_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4483. {
  4484. }
  4485. static void
  4486. compile_s64_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4487. {
  4488. compile_u64_ref (j, dst, ptr, idx);
  4489. }
  4490. static void
  4491. compile_s64_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4492. {
  4493. }
  4494. static void
  4495. compile_s8_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4496. {
  4497. compile_u8_set (j, ptr, idx, v);
  4498. }
  4499. static void
  4500. compile_s8_set_slow (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4501. {
  4502. }
  4503. static void
  4504. compile_s16_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4505. {
  4506. compile_u16_set (j, ptr, idx, v);
  4507. }
  4508. static void
  4509. compile_s16_set_slow (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4510. {
  4511. }
  4512. static void
  4513. compile_s32_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4514. {
  4515. compile_u32_set (j, ptr, idx, v);
  4516. }
  4517. static void
  4518. compile_s32_set_slow (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4519. {
  4520. }
  4521. static void
  4522. compile_s64_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4523. {
  4524. compile_u64_set (j, ptr, idx, v);
  4525. }
  4526. static void
  4527. compile_s64_set_slow (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4528. {
  4529. }
  4530. static void
  4531. compile_f32_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4532. {
  4533. emit_sp_ref_ptr (j, T0, ptr);
  4534. emit_sp_ref_sz (j, T1, idx);
  4535. jit_ldxr_f (j->jit, JIT_F0, T0, T1);
  4536. record_fpr_clobber (j, JIT_F0);
  4537. jit_extr_f_d (j->jit, JIT_F0, JIT_F0);
  4538. emit_sp_set_f64 (j, dst, JIT_F0);
  4539. }
  4540. static void
  4541. compile_f32_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4542. {
  4543. }
  4544. static void
  4545. compile_f64_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4546. {
  4547. emit_sp_ref_ptr (j, T0, ptr);
  4548. emit_sp_ref_sz (j, T1, idx);
  4549. jit_ldxr_d (j->jit, JIT_F0, T0, T1);
  4550. record_fpr_clobber (j, JIT_F0);
  4551. emit_sp_set_f64 (j, dst, JIT_F0);
  4552. }
  4553. static void
  4554. compile_f64_ref_slow (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  4555. {
  4556. }
  4557. static void
  4558. compile_f32_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4559. {
  4560. emit_sp_ref_ptr (j, T0, ptr);
  4561. emit_sp_ref_sz (j, T1, idx);
  4562. emit_sp_ref_f64 (j, JIT_F0, v);
  4563. jit_extr_d_f (j->jit, JIT_F0, JIT_F0);
  4564. record_fpr_clobber (j, JIT_F0);
  4565. jit_stxr_f (j->jit, T0, T1, JIT_F0);
  4566. }
  4567. static void
  4568. compile_f32_set_slow (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4569. {
  4570. }
  4571. static void
  4572. compile_f64_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4573. {
  4574. emit_sp_ref_ptr (j, T0, ptr);
  4575. emit_sp_ref_sz (j, T1, idx);
  4576. emit_sp_ref_f64 (j, JIT_F0, v);
  4577. jit_stxr_d (j->jit, T0, T1, JIT_F0);
  4578. }
  4579. static void
  4580. compile_f64_set_slow (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  4581. {
  4582. }
  4583. static void
  4584. compile_s64_to_f64 (scm_jit_state *j, uint16_t dst, uint16_t src)
  4585. {
  4586. #if SIZEOF_UINTPTR_T >= 8
  4587. emit_sp_ref_s64 (j, T0, src);
  4588. jit_extr_d (j->jit, JIT_F0, T0);
  4589. #else
  4590. emit_call_1 (j, scm_vm_intrinsics.s64_to_f64, sp_slot_operand (j, src));
  4591. jit_retval_d (j->jit, JIT_F0);
  4592. emit_reload_sp (j);
  4593. #endif
  4594. record_fpr_clobber (j, JIT_F0);
  4595. emit_sp_set_f64 (j, dst, JIT_F0);
  4596. }
  4597. static void
  4598. compile_s64_to_f64_slow (scm_jit_state *j, uint16_t dst, uint16_t src)
  4599. {
  4600. }
  4601. #define UNPACK_8_8_8(op,a,b,c) \
  4602. do \
  4603. { \
  4604. a = (op >> 8) & 0xff; \
  4605. b = (op >> 16) & 0xff; \
  4606. c = op >> 24; \
  4607. } \
  4608. while (0)
  4609. #define UNPACK_8_16(op,a,b) \
  4610. do \
  4611. { \
  4612. a = (op >> 8) & 0xff; \
  4613. b = op >> 16; \
  4614. } \
  4615. while (0)
  4616. #define UNPACK_12_12(op,a,b) \
  4617. do \
  4618. { \
  4619. a = (op >> 8) & 0xfff; \
  4620. b = op >> 20; \
  4621. } \
  4622. while (0)
  4623. #define UNPACK_24(op,a) \
  4624. do \
  4625. { \
  4626. a = op >> 8; \
  4627. } \
  4628. while (0)
  4629. #define UNPACK_8_24(op,a,b) \
  4630. do \
  4631. { \
  4632. a = op & 0xff; \
  4633. b = op >> 8; \
  4634. } \
  4635. while (0)
  4636. #define UNPACK_16_16(op,a,b) \
  4637. do \
  4638. { \
  4639. a = op & 0xffff; \
  4640. b = op >> 16; \
  4641. } \
  4642. while (0)
  4643. #define COMPILE_OP1(t0) \
  4644. COMPILE_##t0
  4645. #define COMPILE_OP2(t0, t1) \
  4646. COMPILE_##t0##__##t1
  4647. #define COMPILE_OP3(t0, t1, t2) \
  4648. COMPILE_##t0##__##t1##__##t2
  4649. #define COMPILE_OP4(t0, t1, t2, t3) \
  4650. COMPILE_##t0##__##t1##__##t2##__##t3
  4651. #define COMPILE_OP5(t0, t1, t2, t3, t4) \
  4652. COMPILE_##t0##__##t1##__##t2##__##t3##__##t4
  4653. #define COMPILE_DOP1(t0) COMPILE_OP1(t0)
  4654. #define COMPILE_DOP2(t0, t1) COMPILE_OP2(t0, t1)
  4655. #define COMPILE_DOP3(t0, t1, t2) COMPILE_OP3(t0, t1, t2)
  4656. #define COMPILE_DOP4(t0, t1, t2, t3) COMPILE_OP4(t0, t1, t2, t3)
  4657. #define COMPILE_DOP5(t0, t1, t2, t3, t4) COMPILE_OP5(t0, t1, t2, t3, t4)
  4658. #define COMPILE_NOP(j, comp) \
  4659. { \
  4660. bad_instruction (j); \
  4661. }
  4662. #define COMPILE_X32(j, comp) \
  4663. { \
  4664. comp (j); \
  4665. }
  4666. #define COMPILE_X8_C24(j, comp) \
  4667. { \
  4668. uint32_t a; \
  4669. UNPACK_24 (j->ip[0], a); \
  4670. comp (j, a); \
  4671. }
  4672. #define COMPILE_X8_F24(j, comp) \
  4673. COMPILE_X8_C24 (j, comp)
  4674. #define COMPILE_X8_S24(j, comp) \
  4675. COMPILE_X8_C24 (j, comp)
  4676. #define COMPILE_X8_L24(j, comp) \
  4677. { \
  4678. int32_t a = j->ip[0]; \
  4679. a >>= 8; /* Sign extension. */ \
  4680. comp (j, j->ip + a); \
  4681. }
  4682. #define COMPILE_X8_C12_C12(j, comp) \
  4683. { \
  4684. uint16_t a, b; \
  4685. UNPACK_12_12 (j->ip[0], a, b); \
  4686. comp (j, a, b); \
  4687. }
  4688. #define COMPILE_X8_S12_C12(j, comp) \
  4689. COMPILE_X8_C12_C12 (j, comp)
  4690. #define COMPILE_X8_S12_S12(j, comp) \
  4691. COMPILE_X8_C12_C12 (j, comp)
  4692. #define COMPILE_X8_F12_F12(j, comp) \
  4693. COMPILE_X8_C12_C12 (j, comp)
  4694. #define COMPILE_X8_S12_Z12(j, comp) \
  4695. { \
  4696. uint16_t a = (j->ip[0] >> 8) & 0xfff; \
  4697. int16_t b = ((int32_t) j->ip[0]) >> 20; /* Sign extension. */ \
  4698. comp (j, a, b); \
  4699. }
  4700. #define COMPILE_X8_S8_C8_S8(j, comp) \
  4701. { \
  4702. uint8_t a, b, c; \
  4703. UNPACK_8_8_8 (j->ip[0], a, b, c); \
  4704. comp (j, a, b, c); \
  4705. }
  4706. #define COMPILE_X8_S8_S8_C8(j, comp) \
  4707. COMPILE_X8_S8_C8_S8 (j, comp)
  4708. #define COMPILE_X8_S8_S8_S8(j, comp) \
  4709. COMPILE_X8_S8_C8_S8 (j, comp)
  4710. #define COMPILE_X8_S8_I16(j, comp) \
  4711. { \
  4712. uint8_t a; \
  4713. scm_t_bits b; \
  4714. UNPACK_8_16 (j->ip[0], a, b); \
  4715. comp (j, a, SCM_PACK (b)); \
  4716. }
  4717. #define COMPILE_X8_S8_ZI16(j, comp) \
  4718. { \
  4719. uint8_t a; \
  4720. int16_t b; \
  4721. UNPACK_8_16 (j->ip[0], a, b); \
  4722. comp (j, a, SCM_PACK ((scm_t_signed_bits) b)); \
  4723. }
  4724. #define COMPILE_X32__C32(j, comp) \
  4725. { \
  4726. comp (j, j->ip[1]); \
  4727. }
  4728. #define COMPILE_X32__L32(j, comp) \
  4729. { \
  4730. int32_t a = j->ip[1]; \
  4731. comp (j, j->ip + a); \
  4732. }
  4733. #define COMPILE_X32__N32(j, comp) \
  4734. COMPILE_X32__L32 (j, comp)
  4735. #define COMPILE_X8_C24__L32(j, comp) \
  4736. { \
  4737. uint32_t a; \
  4738. int32_t b; \
  4739. UNPACK_24 (j->ip[0], a); \
  4740. b = j->ip[1]; \
  4741. comp (j, a, j->ip + b); \
  4742. }
  4743. #define COMPILE_X8_S24__L32(j, comp) \
  4744. COMPILE_X8_C24__L32 (j, comp)
  4745. #define COMPILE_X8_S24__LO32(j, comp) \
  4746. COMPILE_X8_C24__L32 (j, comp)
  4747. #define COMPILE_X8_S24__N32(j, comp) \
  4748. COMPILE_X8_C24__L32 (j, comp)
  4749. #define COMPILE_X8_S24__R32(j, comp) \
  4750. COMPILE_X8_C24__L32 (j, comp)
  4751. #define COMPILE_X8_C24__X8_C24(j, comp) \
  4752. { \
  4753. uint32_t a, b; \
  4754. UNPACK_24 (j->ip[0], a); \
  4755. UNPACK_24 (j->ip[1], b); \
  4756. comp (j, a, b); \
  4757. }
  4758. #define COMPILE_X8_F24__X8_C24(j, comp) \
  4759. COMPILE_X8_C24__X8_C24(j, comp)
  4760. #define COMPILE_X8_F24__X8_F24(j, comp) \
  4761. COMPILE_X8_C24__X8_C24(j, comp)
  4762. #define COMPILE_X8_S24__X8_S24(j, comp) \
  4763. COMPILE_X8_C24__X8_C24(j, comp)
  4764. #define COMPILE_X8_F12_F12__X8_C24(j, comp) \
  4765. { \
  4766. uint16_t a, b; \
  4767. uint32_t c; \
  4768. UNPACK_12_12 (j->ip[0], a, b); \
  4769. UNPACK_24 (j->ip[1], c); \
  4770. comp (j, a, b, c); \
  4771. }
  4772. #define COMPILE_X8_F24__B1_X7_C24(j, comp) \
  4773. { \
  4774. uint32_t a, c; \
  4775. uint8_t b; \
  4776. UNPACK_24 (j->ip[0], a); \
  4777. b = j->ip[1] & 0x1; \
  4778. UNPACK_24 (j->ip[1], c); \
  4779. comp (j, a, b, c); \
  4780. }
  4781. #define COMPILE_X8_S12_S12__C32(j, comp) \
  4782. { \
  4783. uint16_t a, b; \
  4784. uint32_t c; \
  4785. UNPACK_12_12 (j->ip[0], a, b); \
  4786. c = j->ip[1]; \
  4787. comp (j, a, b, c); \
  4788. }
  4789. #define COMPILE_X8_S24__C16_C16(j, comp) \
  4790. { \
  4791. uint32_t a; \
  4792. uint16_t b, c; \
  4793. UNPACK_24 (j->ip[0], a); \
  4794. UNPACK_16_16 (j->ip[1], b, c); \
  4795. comp (j, a, b, c); \
  4796. }
  4797. #define COMPILE_X8_S24__C32(j, comp) \
  4798. { \
  4799. uint32_t a, b; \
  4800. UNPACK_24 (j->ip[0], a); \
  4801. b = j->ip[1]; \
  4802. comp (j, a, b); \
  4803. }
  4804. #define COMPILE_X8_S24__I32(j, comp) \
  4805. { \
  4806. uint32_t a; \
  4807. scm_t_bits b; \
  4808. UNPACK_24 (j->ip[0], a); \
  4809. b = j->ip[1]; \
  4810. comp (j, a, SCM_PACK (b)); \
  4811. }
  4812. #define COMPILE_X8_S8_S8_C8__C32(j, comp) \
  4813. { \
  4814. uint8_t a, b, c; \
  4815. uint32_t d; \
  4816. UNPACK_8_8_8 (j->ip[0], a, b, c); \
  4817. d = j->ip[1]; \
  4818. comp (j, a, b, c, d); \
  4819. }
  4820. #define COMPILE_X8_S8_S8_S8__C32(j, comp) \
  4821. COMPILE_X8_S8_S8_C8__C32(j, comp)
  4822. #define COMPILE_X8_S8_C8_S8__C32(j, comp) \
  4823. COMPILE_X8_S8_S8_C8__C32(j, comp)
  4824. #define COMPILE_X8_S24__V32_X8_L24(j, comp) \
  4825. { \
  4826. uint32_t a, len; \
  4827. UNPACK_24 (j->ip[0], a); \
  4828. len = j->ip[1]; \
  4829. j->next_ip += len; \
  4830. comp (j, a, len, j->ip + 2); \
  4831. }
  4832. #define COMPILE_X32__LO32__L32(j, comp) \
  4833. { \
  4834. int32_t a = j->ip[1], b = j->ip[2]; \
  4835. comp (j, j->ip + a, j->ip + b); \
  4836. }
  4837. #define COMPILE_X8_F24__X8_C24__L32(j, comp) \
  4838. { \
  4839. uint32_t a, b; \
  4840. int32_t c; \
  4841. UNPACK_24 (j->ip[0], a); \
  4842. UNPACK_24 (j->ip[1], b); \
  4843. c = j->ip[2]; \
  4844. comp (j, a, b, j->ip + c); \
  4845. }
  4846. #define COMPILE_X8_S24__A32__B32(j, comp) \
  4847. { \
  4848. uint32_t a; \
  4849. uint64_t b; \
  4850. UNPACK_24 (j->ip[0], a); \
  4851. b = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  4852. ASSERT (b <= (uint64_t) UINTPTR_MAX); \
  4853. comp (j, a, SCM_PACK ((uintptr_t) b)); \
  4854. }
  4855. #define COMPILE_X8_S24__AF32__BF32(j, comp) \
  4856. { \
  4857. uint32_t a; \
  4858. union { uint64_t u; double d; } b; \
  4859. UNPACK_24 (j->ip[0], a); \
  4860. b.u = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  4861. comp (j, a, b.d); \
  4862. }
  4863. #define COMPILE_X8_S24__AS32__BS32(j, comp) \
  4864. { \
  4865. uint32_t a; \
  4866. uint64_t b; \
  4867. UNPACK_24 (j->ip[0], a); \
  4868. b = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  4869. comp (j, a, (int64_t) b); \
  4870. }
  4871. #define COMPILE_X8_S24__AU32__BU32(j, comp) \
  4872. { \
  4873. uint32_t a; \
  4874. uint64_t b; \
  4875. UNPACK_24 (j->ip[0], a); \
  4876. b = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  4877. comp (j, a, b); \
  4878. }
  4879. #define COMPILE_X8_S24__B1_X7_F24__X8_L24(j, comp) \
  4880. { \
  4881. uint32_t a, c; \
  4882. uint8_t b; \
  4883. int32_t d; \
  4884. UNPACK_24 (j->ip[0], a); \
  4885. b = j->ip[1] & 0x1; \
  4886. UNPACK_24 (j->ip[1], c); \
  4887. d = j->ip[2]; d >>= 8; /* Sign extension. */ \
  4888. comp (j, a, b, c, j->ip + d); \
  4889. }
  4890. #define COMPILE_X8_S24__X8_S24__C8_S24(j, comp) \
  4891. { \
  4892. uint32_t a, b, d; \
  4893. uint8_t c; \
  4894. UNPACK_24 (j->ip[0], a); \
  4895. UNPACK_24 (j->ip[1], b); \
  4896. UNPACK_8_24 (j->ip[2], c, d); \
  4897. comp (j, a, b, c, d); \
  4898. }
  4899. #define COMPILE_X8_C24__C8_C24__X8_C24__N32(j, comp) \
  4900. { \
  4901. uint32_t a, c, d; \
  4902. uint8_t b; \
  4903. int32_t e; \
  4904. UNPACK_24 (j->ip[0], a); \
  4905. UNPACK_8_24 (j->ip[1], b, c); \
  4906. UNPACK_24 (j->ip[2], d); \
  4907. e = j->ip[3]; \
  4908. comp (j, a, b, c, d, j->ip + e); \
  4909. }
  4910. #define COMPILE_X8_S24__X8_S24__C8_S24__X8_S24(j, comp) \
  4911. { \
  4912. uint32_t a, b, d, e; \
  4913. uint8_t c; \
  4914. UNPACK_24 (j->ip[0], a); \
  4915. UNPACK_24 (j->ip[1], b); \
  4916. UNPACK_8_24 (j->ip[2], c, d); \
  4917. UNPACK_24 (j->ip[3], e); \
  4918. comp (j, a, b, c, d, e); \
  4919. }
  4920. static uintptr_t opcodes_seen[256 / (SCM_SIZEOF_UINTPTR_T * 8)];
  4921. static uintptr_t
  4922. bitvector_ref (const uintptr_t *bv, size_t n)
  4923. {
  4924. uintptr_t word = bv[n / (SCM_SIZEOF_UINTPTR_T * 8)];
  4925. return word & (((uintptr_t) 1) << (n & (SCM_SIZEOF_UINTPTR_T * 8 - 1)));
  4926. }
  4927. static void
  4928. bitvector_set (uintptr_t *bv, size_t n)
  4929. {
  4930. uintptr_t *word_loc = &bv[n / (SCM_SIZEOF_UINTPTR_T * 8)];
  4931. *word_loc |= ((uintptr_t) 1) << (n & (SCM_SIZEOF_UINTPTR_T * 8 - 1));
  4932. }
  4933. static void
  4934. compile1 (scm_jit_state *j)
  4935. {
  4936. uint8_t opcode = j->ip[0] & 0xff;
  4937. if (jit_log_level >= LOG_LEVEL_DEBUG)
  4938. {
  4939. const char *n;
  4940. switch (opcode)
  4941. {
  4942. #define NAME(code, cname, name, arity) case code: n = name; break;
  4943. FOR_EACH_VM_OPERATION(NAME)
  4944. #undef NAME
  4945. default:
  4946. UNREACHABLE ();
  4947. }
  4948. if (!bitvector_ref (opcodes_seen, opcode))
  4949. {
  4950. bitvector_set (opcodes_seen, opcode);
  4951. DEBUG ("Instruction first seen at vcode %p: %s\n", j->ip, n);
  4952. }
  4953. LOG ("Instruction at vcode %p: %s\n", j->ip, n);
  4954. }
  4955. j->next_ip = j->ip + op_lengths[opcode];
  4956. switch (opcode)
  4957. {
  4958. #define COMPILE1(code, cname, name, arity) \
  4959. case code: COMPILE_##arity(j, compile_##cname); break;
  4960. FOR_EACH_VM_OPERATION(COMPILE1)
  4961. #undef COMPILE1
  4962. default:
  4963. UNREACHABLE ();
  4964. }
  4965. j->ip = j->next_ip;
  4966. }
  4967. static void
  4968. compile_slow_path (scm_jit_state *j)
  4969. {
  4970. uint8_t opcode = j->ip[0] & 0xff;
  4971. j->next_ip = j->ip + op_lengths[opcode];
  4972. switch (opcode)
  4973. {
  4974. #define COMPILE_SLOW(code, cname, name, arity) \
  4975. case code: COMPILE_##arity(j, compile_##cname##_slow); break;
  4976. FOR_EACH_VM_OPERATION(COMPILE_SLOW)
  4977. #undef COMPILE_SLOW
  4978. default:
  4979. UNREACHABLE ();
  4980. }
  4981. j->ip = j->next_ip;
  4982. }
  4983. static void
  4984. analyze (scm_jit_state *j)
  4985. {
  4986. memset (j->op_attrs, 0, j->end - j->start);
  4987. j->op_attrs[0] = OP_ATTR_BLOCK | OP_ATTR_ENTRY;
  4988. for (j->ip = (uint32_t *) j->start; j->ip < j->end; j->ip = j->next_ip)
  4989. {
  4990. uint8_t opcode = j->ip[0] & 0xff;
  4991. uint8_t attrs = 0;
  4992. uint32_t *target;
  4993. j->next_ip = j->ip + op_lengths[opcode];
  4994. switch (opcode)
  4995. {
  4996. case scm_op_check_arguments:
  4997. case scm_op_check_positional_arguments:
  4998. attrs |= OP_ATTR_ENTRY;
  4999. /* Fall through. */
  5000. case scm_op_u64_numerically_equal:
  5001. case scm_op_u64_less:
  5002. case scm_op_s64_less:
  5003. case scm_op_f64_numerically_equal:
  5004. case scm_op_f64_less:
  5005. case scm_op_numerically_equal:
  5006. case scm_op_less:
  5007. case scm_op_immediate_tag_equals:
  5008. case scm_op_heap_tag_equals:
  5009. case scm_op_eq:
  5010. case scm_op_eq_immediate:
  5011. case scm_op_heap_numbers_equal:
  5012. case scm_op_s64_imm_numerically_equal:
  5013. case scm_op_u64_imm_less:
  5014. case scm_op_imm_u64_less:
  5015. case scm_op_s64_imm_less:
  5016. case scm_op_imm_s64_less:
  5017. attrs |= OP_ATTR_BLOCK;
  5018. fuse_conditional_branch (j, &target);
  5019. j->op_attrs[target - j->start] |= attrs;
  5020. break;
  5021. case scm_op_j:
  5022. target = j->ip + (((int32_t)j->ip[0]) >> 8);
  5023. j->op_attrs[target - j->start] |= OP_ATTR_BLOCK;
  5024. break;
  5025. case scm_op_jtable:
  5026. {
  5027. uint32_t len = j->ip[1];
  5028. const uint32_t *offsets = j->ip + 2;
  5029. for (uint32_t i = 0; i < len; i++)
  5030. {
  5031. int32_t offset = offsets[i];
  5032. offset >>= 8; /* Sign-extending shift. */
  5033. target = j->ip + offset;
  5034. ASSERT(j->start <= target && target < j->end);
  5035. j->op_attrs[target - j->start] |= OP_ATTR_BLOCK;
  5036. }
  5037. j->next_ip += len;
  5038. break;
  5039. }
  5040. case scm_op_call:
  5041. case scm_op_call_label:
  5042. attrs = OP_ATTR_BLOCK;
  5043. target = j->next_ip;
  5044. j->op_attrs[target - j->start] |= OP_ATTR_BLOCK | OP_ATTR_ENTRY;
  5045. break;
  5046. case scm_op_prompt:
  5047. target = j->ip + (((int32_t) j->ip[2]) >> 8);
  5048. j->op_attrs[target - j->start] |= OP_ATTR_BLOCK | OP_ATTR_ENTRY;
  5049. break;
  5050. default:
  5051. break;
  5052. }
  5053. }
  5054. /* Even in loops, the entry should be a jump target. */
  5055. ASSERT (j->op_attrs[j->entry - j->start] & OP_ATTR_BLOCK);
  5056. }
  5057. static void
  5058. compile (scm_jit_state *j)
  5059. {
  5060. j->ip = (uint32_t *) j->start;
  5061. set_register_state (j, SP_IN_REGISTER | FP_IN_REGISTER);
  5062. j->frame_size_min = 0;
  5063. j->frame_size_max = INT32_MAX;
  5064. for (ptrdiff_t offset = 0; j->ip + offset < j->end; offset++) {
  5065. j->labels[inline_label_offset (offset)] = NULL;
  5066. j->labels[slow_label_offset (offset)] = NULL;
  5067. }
  5068. j->reloc_idx = 0;
  5069. while (j->ip < j->end)
  5070. {
  5071. ptrdiff_t offset = j->ip - j->start;
  5072. uint8_t attrs = j->op_attrs[offset];
  5073. j->labels[inline_label_offset (offset)] = jit_address (j->jit);
  5074. if (attrs & OP_ATTR_BLOCK)
  5075. {
  5076. uint32_t state = SP_IN_REGISTER;
  5077. if (attrs & OP_ATTR_ENTRY)
  5078. state |= FP_IN_REGISTER;
  5079. j->register_state = state;
  5080. }
  5081. compile1 (j);
  5082. if (jit_has_overflow (j->jit))
  5083. return;
  5084. }
  5085. jit_breakpoint (j->jit);
  5086. j->ip = (uint32_t *) j->start;
  5087. while (j->ip < j->end)
  5088. {
  5089. ptrdiff_t offset = j->ip - j->start;
  5090. j->labels[slow_label_offset (offset)] = jit_address (j->jit);
  5091. // set register state from j->register_states[offset] ?
  5092. reset_register_state (j, SP_IN_REGISTER);
  5093. compile_slow_path (j);
  5094. if (jit_has_overflow (j->jit))
  5095. return;
  5096. }
  5097. jit_breakpoint (j->jit);
  5098. for (size_t i = 0; i < j->reloc_idx; i++)
  5099. {
  5100. void *target = j->labels[j->relocs[i].target_label_offset];
  5101. ASSERT(target);
  5102. jit_patch_there (j->jit, j->relocs[i].reloc, target);
  5103. }
  5104. }
  5105. static scm_i_pthread_once_t initialize_jit_once = SCM_I_PTHREAD_ONCE_INIT;
  5106. static void*
  5107. jit_alloc_fn (size_t size)
  5108. {
  5109. return scm_gc_malloc (size, "jit state");
  5110. }
  5111. static void
  5112. jit_free_fn (void *unused)
  5113. {
  5114. }
  5115. static scm_jit_state *
  5116. initialize_thread_jit_state (scm_thread *thread)
  5117. {
  5118. scm_jit_state *j;
  5119. ASSERT (!thread->jit_state);
  5120. j = scm_gc_malloc (sizeof (*j), "jit state");
  5121. memset (j, 0, sizeof (*j));
  5122. thread->jit_state = j;
  5123. j->jit = jit_new_state (jit_alloc_fn, jit_free_fn);
  5124. return j;
  5125. }
  5126. static void
  5127. initialize_jit (void)
  5128. {
  5129. scm_jit_state *j;
  5130. if (!init_jit ())
  5131. {
  5132. scm_jit_counter_threshold = -1;
  5133. fprintf (stderr, "JIT failed to initialize\n");
  5134. fprintf (stderr, "disabling automatic JIT compilation\n");
  5135. return;
  5136. }
  5137. /* Init the thread's jit state so we can emit the entry
  5138. trampoline and the handle-interrupts trampoline. */
  5139. j = initialize_thread_jit_state (SCM_I_CURRENT_THREAD);
  5140. jit_pointer_t enter_mcode_addr = emit_code (j, emit_entry_trampoline);
  5141. ASSERT (enter_mcode_addr);
  5142. enter_mcode = jit_address_to_function_pointer (enter_mcode_addr);
  5143. handle_interrupts_trampoline =
  5144. emit_code (j, emit_handle_interrupts_trampoline);
  5145. ASSERT (handle_interrupts_trampoline);
  5146. scm_jit_return_to_interpreter_trampoline =
  5147. emit_code (j, emit_return_to_interpreter_trampoline);
  5148. ASSERT (scm_jit_return_to_interpreter_trampoline);
  5149. scm_jit_return_to_interpreter_trampoline = jit_address_to_function_pointer
  5150. (scm_jit_return_to_interpreter_trampoline);
  5151. }
  5152. static scm_i_pthread_once_t create_perf_map_once = SCM_I_PTHREAD_ONCE_INIT;
  5153. static FILE *perf_map = NULL;
  5154. static void
  5155. create_perf_map (void)
  5156. {
  5157. unsigned long pid = getpid ();
  5158. char *file_name;
  5159. if (asprintf (&file_name, "/tmp/perf-%lu.map", pid) < 0)
  5160. return;
  5161. perf_map = fopen (file_name, "w");
  5162. if (perf_map)
  5163. DEBUG ("created %s\n", file_name);
  5164. free (file_name);
  5165. }
  5166. static uint8_t *
  5167. compute_mcode (scm_thread *thread, uint32_t *entry_ip,
  5168. struct scm_jit_function_data *data)
  5169. {
  5170. scm_jit_state *j = thread->jit_state;
  5171. uint8_t *entry_mcode;
  5172. if (!j)
  5173. {
  5174. scm_i_pthread_once (&initialize_jit_once, initialize_jit);
  5175. if (scm_jit_counter_threshold == -1)
  5176. {
  5177. /* initialization failed! */
  5178. return NULL;
  5179. }
  5180. j = thread->jit_state;
  5181. /* It's possible that initialize_jit_once inits this thread's jit
  5182. state. */
  5183. if (!j)
  5184. j = initialize_thread_jit_state (thread);
  5185. }
  5186. j->thread = thread;
  5187. j->start = (const uint32_t *) (((char *)data) + data->start);
  5188. j->end = (const uint32_t *) (((char *)data) + data->end);
  5189. j->entry = entry_ip;
  5190. ASSERT (j->start < j->end);
  5191. ASSERT (j->start <= j->entry);
  5192. ASSERT (j->entry < j->end);
  5193. j->op_attrs = calloc ((j->end - j->start), sizeof (*j->op_attrs));
  5194. ASSERT (j->op_attrs);
  5195. j->labels = calloc ((j->end - j->start) * 2, sizeof (*j->labels));
  5196. ASSERT (j->labels);
  5197. j->frame_size_min = 0;
  5198. j->frame_size_max = INT32_MAX;
  5199. INFO ("vcode: start=%p,+%zu entry=+%zu\n", j->start, j->end - j->start,
  5200. j->entry - j->start);
  5201. analyze (j);
  5202. uint8_t *mcode = emit_code (j, compile);
  5203. if (mcode)
  5204. {
  5205. entry_mcode = j->labels[inline_label_offset (j->entry - j->start)];
  5206. data->mcode = mcode;
  5207. if (jit_log_level >= LOG_LEVEL_INFO) {
  5208. scm_i_pthread_once (&create_perf_map_once, create_perf_map);
  5209. if (perf_map) {
  5210. uint8_t *end = j->code_arena->base + j->code_arena->used;
  5211. fprintf (perf_map, "%lx %zx %p,+%zu\n", (long)mcode, end - mcode,
  5212. j->start, j->end - j->start);
  5213. fflush (perf_map);
  5214. }
  5215. }
  5216. }
  5217. else
  5218. {
  5219. entry_mcode = NULL;
  5220. }
  5221. free (j->op_attrs);
  5222. j->op_attrs = NULL;
  5223. free (j->labels);
  5224. j->labels = NULL;
  5225. free (j->relocs);
  5226. j->relocs = NULL;
  5227. j->reloc_idx = 0;
  5228. j->reloc_count = 0;
  5229. j->start = j->end = j->ip = j->entry = NULL;
  5230. j->frame_size_min = 0;
  5231. j->frame_size_max = INT32_MAX;
  5232. return entry_mcode;
  5233. }
  5234. const uint8_t *
  5235. scm_jit_compute_mcode (scm_thread *thread, struct scm_jit_function_data *data)
  5236. {
  5237. const uint32_t *vcode_start = (const uint32_t *) (((char *)data) + data->start);
  5238. if (data->mcode)
  5239. {
  5240. if (vcode_start == thread->vm.ip)
  5241. return data->mcode;
  5242. /* The function has mcode, compiled via some other activation
  5243. (possibly in another thread), but right now we're currently in
  5244. an interpreted loop (not at the beginning of the function). It
  5245. would be nice if we could jump into the already-compiled
  5246. function, but we don't know the offset. You'd think we could
  5247. just compile again without writing bytes to find out the offset
  5248. into the old code, but we're not guaranteed to get the same
  5249. compiled code, for example due to variations on whether direct
  5250. callees have mcode at the time of the compile, or different
  5251. encodings for relative references. So oh well: we're just
  5252. going to compile another copy and update the mcode pointer,
  5253. hoping this is a rare occurence. */
  5254. }
  5255. uint8_t *mcode = compute_mcode (thread, thread->vm.ip, data);
  5256. if (!mcode)
  5257. {
  5258. scm_jit_counter_threshold = -1;
  5259. fprintf (stderr, "JIT failed due to resource exhaustion\n");
  5260. fprintf (stderr, "disabling automatic JIT compilation\n");
  5261. }
  5262. else if (--jit_stop_after == 0)
  5263. {
  5264. scm_jit_counter_threshold = -1;
  5265. fprintf (stderr, "stopping automatic JIT compilation, as requested\n");
  5266. if (jit_pause_when_stopping)
  5267. {
  5268. fprintf (stderr, "sleeping for 30s; to debug:\n");
  5269. fprintf (stderr, " gdb -p %d\n\n", getpid ());
  5270. sleep (30);
  5271. }
  5272. }
  5273. return mcode;
  5274. }
  5275. void
  5276. scm_jit_enter_mcode (scm_thread *thread, const uint8_t *mcode)
  5277. {
  5278. LOG ("entering mcode: %p\n", mcode);
  5279. if (!SCM_FRAME_MACHINE_RETURN_ADDRESS (thread->vm.fp))
  5280. SCM_FRAME_SET_MACHINE_RETURN_ADDRESS
  5281. (thread->vm.fp, scm_jit_return_to_interpreter_trampoline);
  5282. enter_mcode (thread, mcode);
  5283. LOG ("exited mcode\n");
  5284. }
  5285. /* Call to force a thread to go back to the interpreter, for example
  5286. when single-stepping is enabled. */
  5287. void
  5288. scm_jit_clear_mcode_return_addresses (scm_thread *thread)
  5289. {
  5290. union scm_vm_stack_element *fp;
  5291. struct scm_vm *vp = &thread->vm;
  5292. for (fp = vp->fp; fp < vp->stack_top; fp = SCM_FRAME_DYNAMIC_LINK (fp))
  5293. SCM_FRAME_SET_MACHINE_RETURN_ADDRESS
  5294. (fp, scm_jit_return_to_interpreter_trampoline);
  5295. }
  5296. void
  5297. scm_jit_state_free (scm_jit_state *j)
  5298. {
  5299. /* Nothing to do; we leave j->jit NULL between compilations. */
  5300. }
  5301. void
  5302. scm_init_jit (void)
  5303. {
  5304. scm_jit_counter_threshold = scm_getenv_int ("GUILE_JIT_THRESHOLD",
  5305. default_jit_threshold);
  5306. jit_stop_after = scm_getenv_int ("GUILE_JIT_STOP_AFTER", -1);
  5307. jit_pause_when_stopping = scm_getenv_int ("GUILE_JIT_PAUSE_WHEN_STOPPING", 0);
  5308. jit_log_level = scm_getenv_int ("GUILE_JIT_LOG", 0);
  5309. }
  5310. #endif /* ENABLE_JIT */