jit.c 162 KB

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