jit.c 170 KB

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