jit.c 131 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785
  1. /* Copyright 2018
  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 <lightning.h>
  23. #include "frames.h"
  24. #include "gsubr.h"
  25. #include "instructions.h"
  26. #include "intrinsics.h"
  27. #include "simpos.h" /* scm_getenv_int */
  28. #include "threads.h"
  29. #include "vm-builtins.h"
  30. #include "vm-operations.h"
  31. #include "jit.h"
  32. /* Guile's just-in-time (JIT) compiler is a simple "template JIT". It
  33. produces machine code corresponding to each VM instruction,
  34. substituting in the arguments from the bytecode. The generated code
  35. performs the same operations on the Guile program state the VM
  36. interpreter would: the same stack reads and writes, the same calls,
  37. the same control flow: the same thing. It's a very simple JIT.
  38. This JIT uses GNU Lightning, a library for generating assembly code.
  39. It has backends for every architecture you can think of. Lightning
  40. exposes a minimum of 3 "volatile" or "scratch" registers, those that
  41. may be overwritten by called functions, and 3 "non-volatile" or
  42. "preserved" registers, those whose values will persist over calls.
  43. Guile's JIT uses two preserved registers for itself, to store the
  44. current thread and the current stack pointer. The other four
  45. registers are available for the JIT. However as Guile's JIT is
  46. really simple and doesn't do register allocation, no other register
  47. is live between bytecodes; the other four registers are just scratch
  48. space.
  49. Machine code emitted by the JIT (mcode) should only ever be entered
  50. from the interpreter (the VM). To enter bytecode, the interpreter
  51. calls an "entry trampoline" that saves the needed non-volatile
  52. registers, reserves some stack space, loads the thread and stack
  53. pointer into the reserved registers, then jumps into the mcode. The
  54. mcode then does its thing.
  55. When mcode needs to call out to another function, e.g. via the "call"
  56. instruction, it makes a new frame in just the same way the VM would,
  57. with the difference that it also sets the machine return address
  58. (mRA) in the stack frame, in addition to the virtual (bytecode)
  59. return address (vRA). If the callee has mcode, then the caller jumps
  60. to the callee's mcode. It's a jump, not a call, as the stack is
  61. maintained on the side: it's not the stack used by the e.g. x86
  62. "call" instruction.
  63. When mcode calls a function that doesn't have vcode, or returns to a
  64. continuation that doesn't have vcode, the mcode simply returns to the
  65. VM interpreter, allowing the interpreter to pick up from there. The
  66. return actually happens via an exit trampoline, which restores the
  67. saved register values.
  68. Every function in Guile's VM begins with an "instrument-entry"
  69. instruction. The instruction links to a statically allocated "struct
  70. scm_jit_function_data" corresponding to that function. When the
  71. interpreter sees instrument-entry, first it checks that if the
  72. function has mcode, by looking in the scm_jit_function_data. If it
  73. has mcode, the interpreter enters mcode directly, as described above.
  74. If a function doesn't have mcode, "instrument-entry" will increment a
  75. counter in the scm_jit_function_data. If the counter exceeds a
  76. threshold, the interpreter will ask the JIT compiler to produce
  77. mcode. If the JIT compiler was able to do so (always possible except
  78. in case of resource exhaustion), then it sets the mcode pointer in
  79. the scm_jit_function_data, and returns the mcode pointer to the
  80. interpreter. At that point the interpreter will enter mcode.
  81. If the counter value does not exceed the threshold, then the VM
  82. will interpret the function instead of running compiled code.
  83. Additionally, Guile puts an "instrument-loop" instruction into the
  84. body of each loop iteration. It works similarly, except that the
  85. returned mcode pointer starts in the middle of the function, at the
  86. point that corresponds to the program point of the "instrument-loop"
  87. instruction. The idea is that some functions have long-running loops
  88. in them, and it would be a shame to have to wait until the next time
  89. they're called to enter mcode. Being able to "tier up" from inside a
  90. loop reduces overall program latency.
  91. Think of the JIT as microarchitecture. The interpreter specifies the
  92. architecture of the VM, in terms of the stack, stack and frame
  93. pointers, and a virtual instruction pointer. Sometimes this
  94. architectural state is manipulated by the interpreter. Sometimes
  95. it's compiled down to native code. But the existence of native code
  96. is a detail that's fully encapsulated; systems-oriented Guile Scheme
  97. can walk stacks, throw errors, reinstate partial continuations, and
  98. so on without being aware of the existence of the JIT. */
  99. static const uint32_t default_jit_threshold = 50000;
  100. /* Threshold for when to JIT-compile a function. Set from the
  101. GUILE_JIT_THRESHOLD environment variable. */
  102. uint32_t scm_jit_counter_threshold = -1;
  103. /* If positive, stop JIT compilation after the Nth compilation. Useful
  104. for hunting down bugs. */
  105. static int jit_stop_after = -1;
  106. /* If nonzero, pause when stopping JIT compilation after the Nth
  107. compilation. For debugging. */
  108. static int jit_pause_when_stopping = 0;
  109. /* Log level for JIT events. 0 means off. */
  110. static int jit_log_level = 0;
  111. /* Entry trampoline: saves registers, initializes THREAD and SP
  112. registers, and jumps into mcode. */
  113. static void (*enter_mcode) (scm_thread *thread, const uint8_t *mcode);
  114. /* Exit trampoline: restores registers and returns to interpreter. */
  115. static void *exit_mcode;
  116. /* Handle interrupts trampoline: the slow path of the handle-interrupts
  117. instruction, compiled as a stub on the side to reduce code size. */
  118. static void *handle_interrupts_trampoline;
  119. /* Thread-local buffer into which to write code. */
  120. struct code_arena
  121. {
  122. uint8_t *base;
  123. size_t used;
  124. size_t size;
  125. struct code_arena *prev;
  126. };
  127. /* State of the JIT compiler for the current thread. */
  128. struct scm_jit_state {
  129. jit_state_t *jit;
  130. scm_thread *thread;
  131. const uint32_t *start;
  132. uint32_t *ip;
  133. uint32_t *next_ip;
  134. const uint32_t *end;
  135. uint32_t *entry;
  136. jit_node_t *entry_label;
  137. uint8_t *op_attrs;
  138. jit_node_t **labels;
  139. int32_t frame_size;
  140. uint32_t register_state;
  141. jit_gpr_t sp_cache_gpr;
  142. jit_fpr_t sp_cache_fpr;
  143. uint32_t sp_cache_gpr_idx;
  144. uint32_t sp_cache_fpr_idx;
  145. struct code_arena *code_arena;
  146. };
  147. typedef struct scm_jit_state scm_jit_state;
  148. /* Lightning routines take an implicit parameter, _jit. All functions
  149. that call lightning API should have a parameter "scm_jit_state *j";
  150. this definition makes lightning load its state from that
  151. parameter. */
  152. #define _jit (j->jit)
  153. /* From the Lightning documentation:
  154. 'frame' receives an integer argument that defines the size in bytes
  155. for the stack frame of the current, 'C' callable, jit function. To
  156. calculate this value, a good formula is maximum number of arguments
  157. to any called native function times eight, plus the sum of the
  158. arguments to any call to 'jit_allocai'. GNU lightning
  159. automatically adjusts this value for any backend specific stack
  160. memory it may need, or any alignment constraint.
  161. Here we assume that we don't have intrinsics with more than 8
  162. arguments. */
  163. static const uint32_t entry_frame_size = 8 * 8;
  164. static const uint32_t program_word_offset_free_variable = 2;
  165. static const uint32_t frame_offset_mra = 0 * sizeof(union scm_vm_stack_element);
  166. static const uint32_t frame_offset_vra = 1 * sizeof(union scm_vm_stack_element);
  167. static const uint32_t frame_offset_prev = 2 * sizeof(union scm_vm_stack_element);
  168. static const uint32_t frame_overhead_slots = 3;
  169. #define DEFINE_THREAD_OFFSET(f) \
  170. static const uint32_t thread_offset_##f = \
  171. offsetof (struct scm_thread, f)
  172. DEFINE_THREAD_OFFSET (handle);
  173. DEFINE_THREAD_OFFSET (pending_asyncs);
  174. DEFINE_THREAD_OFFSET (block_asyncs);
  175. #define DEFINE_THREAD_VP_OFFSET(f) \
  176. static const uint32_t thread_offset_##f = \
  177. offsetof (struct scm_thread, vm) + offsetof (struct scm_vm, f)
  178. DEFINE_THREAD_VP_OFFSET (fp);
  179. DEFINE_THREAD_VP_OFFSET (sp);
  180. DEFINE_THREAD_VP_OFFSET (ip);
  181. DEFINE_THREAD_VP_OFFSET (sp_min_since_gc);
  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. /* Scratch registers. */
  195. static const jit_gpr_t T0 = JIT_V1;
  196. static const jit_gpr_t T1 = JIT_V2;
  197. static const jit_gpr_t T2 = JIT_R2;
  198. static const jit_gpr_t T3_OR_FP = JIT_R1;
  199. static const jit_gpr_t T4_OR_SP = JIT_R0;
  200. /* Sometimes you want to call out the fact that T0 and T1 are preserved
  201. across calls. In that case, use these. */
  202. static const jit_gpr_t T0_PRESERVED = JIT_V1;
  203. static const jit_gpr_t T1_PRESERVED = JIT_V2;
  204. static const uint32_t SP_IN_REGISTER = 0x1;
  205. static const uint32_t FP_IN_REGISTER = 0x2;
  206. static const uint32_t SP_CACHE_GPR = 0x4;
  207. static const uint32_t SP_CACHE_FPR = 0x8;
  208. static const uint8_t OP_ATTR_BLOCK = 0x1;
  209. static const uint8_t OP_ATTR_ENTRY = 0x2;
  210. #ifdef WORDS_BIGENDIAN
  211. #define BIGENDIAN 1
  212. #else
  213. #define BIGENDIAN 0
  214. #endif
  215. #if BIGENDIAN
  216. static const uint32_t uint32_offset_low_byte = 3;
  217. #else
  218. static const uint32_t uint32_offset_low_byte = 0;
  219. #endif
  220. #if SCM_SIZEOF_UINTPTR_T == 4
  221. static const uint32_t log2_sizeof_uintptr_t = 2;
  222. #elif SCM_SIZEOF_UINTPTR_T == 8
  223. static const uint32_t log2_sizeof_uintptr_t = 3;
  224. #else
  225. #error unhandled uintptr_t size
  226. #endif
  227. #define LENGTH_NOP 0
  228. #define LENGTH_OP1(a) 1
  229. #define LENGTH_OP2(a,b) 2
  230. #define LENGTH_OP3(a,b,c) 3
  231. #define LENGTH_OP4(a,b,c,d) 4
  232. #define LENGTH_DOP1(a) 1
  233. #define LENGTH_DOP2(a,b) 2
  234. #define LENGTH_DOP3(a,b,c) 3
  235. #define LENGTH_DOP4(a,b,c,d) 4
  236. static const uint8_t op_lengths[256] = {
  237. #define OP_LENGTH(code, cname, name, arity) LENGTH_##arity,
  238. FOR_EACH_VM_OPERATION(OP_LENGTH)
  239. #undef OP_LENGTH
  240. };
  241. static void die (int line, const char *msg) SCM_NORETURN;
  242. static void
  243. die (int line, const char *msg)
  244. {
  245. fprintf (stderr, "jit.c:%d: fatal: %s\n", line, msg);
  246. abort ();
  247. }
  248. #define DIE(msg) die(__LINE__, msg)
  249. #define ASSERT(x) \
  250. do { if (SCM_UNLIKELY (!(x))) DIE ("assertion failed"); } while (0)
  251. #define UNREACHABLE() \
  252. DIE ("unreachable")
  253. #define _LOG(level, ...) \
  254. do { \
  255. if (SCM_UNLIKELY (jit_log_level >= level)) \
  256. fprintf (stderr, "jit: " __VA_ARGS__); \
  257. } while (0)
  258. enum {
  259. LOG_LEVEL_NONE,
  260. LOG_LEVEL_INFO,
  261. LOG_LEVEL_DEBUG,
  262. LOG_LEVEL_LOG
  263. };
  264. #define INFO(...) _LOG(LOG_LEVEL_INFO, __VA_ARGS__)
  265. #define DEBUG(...) _LOG(LOG_LEVEL_DEBUG, __VA_ARGS__)
  266. #define LOG(...) _LOG(LOG_LEVEL_LOG, __VA_ARGS__)
  267. static void
  268. reset_register_state (scm_jit_state *j, uint32_t state)
  269. {
  270. j->register_state = state;
  271. }
  272. static void
  273. clear_register_state (scm_jit_state *j, uint32_t state)
  274. {
  275. j->register_state &= ~state;
  276. }
  277. static void
  278. clear_scratch_register_state (scm_jit_state *j)
  279. {
  280. reset_register_state (j, 0);
  281. }
  282. static void
  283. set_register_state (scm_jit_state *j, uint32_t state)
  284. {
  285. j->register_state |= state;
  286. }
  287. static uint32_t
  288. has_register_state (scm_jit_state *j, uint32_t state)
  289. {
  290. return (j->register_state & state) == state;
  291. }
  292. #define ASSERT_HAS_REGISTER_STATE(state) ASSERT (has_register_state (j, state))
  293. static void
  294. record_gpr_clobber (scm_jit_state *j, jit_gpr_t r)
  295. {
  296. if (j->sp_cache_gpr == r)
  297. clear_register_state (j, SP_CACHE_GPR);
  298. }
  299. static void
  300. record_fpr_clobber (scm_jit_state *j, jit_gpr_t r)
  301. {
  302. if (j->sp_cache_fpr == r)
  303. clear_register_state (j, SP_CACHE_FPR);
  304. }
  305. static void
  306. set_sp_cache_gpr (scm_jit_state *j, uint32_t idx, jit_gpr_t r)
  307. {
  308. set_register_state (j, SP_CACHE_GPR);
  309. j->sp_cache_gpr_idx = idx;
  310. if (j->sp_cache_fpr_idx == idx)
  311. clear_register_state (j, SP_CACHE_FPR);
  312. }
  313. static void
  314. set_sp_cache_fpr (scm_jit_state *j, uint32_t idx, jit_fpr_t r)
  315. {
  316. set_register_state (j, SP_CACHE_FPR);
  317. j->sp_cache_fpr_idx = idx;
  318. if (j->sp_cache_gpr_idx == idx)
  319. clear_register_state (j, SP_CACHE_GPR);
  320. }
  321. /* Q: When should I use emit_retval instead of jit_retval? When to use
  322. emit_movi, emit_ldxi?
  323. A: Generally you should use the emit_ variants instead of the jit_
  324. variants. Guile's JIT compiler has a primitive form of local
  325. (intrablock) register allocation that records recent stores. A
  326. subsequent load might be able to replace a register read instead of a
  327. memory load. This simple allocator works for straight-line code, and
  328. it works as long as register writes are recorded. The JIT itself
  329. will clear the register allocator state at control-flow joins, but
  330. control flow within an instruction needs to be careful.
  331. It's OK to use the jit_emit, jit_retval etc primitives if you
  332. manually make corresponding changes to the register_state, perhaps by
  333. inserting record_gpr_clobber calls. If the register is later
  334. clobbered by e.g. emit_sp_set_scm, sometimes those can be omitted
  335. though. Also, if your instruction includes a call, that code will
  336. invalidate any cached register-stack-index associations, so if
  337. there's a call, maybe you can avoid calling emit_*.
  338. Note of course that an association between registers and
  339. stack-indexed locals is also invalidated if the stack frame expands
  340. via alloc-frame or push, or shrinks via reset-frame, pop, drop,
  341. etc. */
  342. static void
  343. emit_retval (scm_jit_state *j, jit_gpr_t r)
  344. {
  345. jit_retval (r);
  346. record_gpr_clobber (j, r);
  347. }
  348. static void
  349. emit_retval_d (scm_jit_state *j, jit_fpr_t r)
  350. {
  351. jit_retval_d (r);
  352. record_fpr_clobber (j, r);
  353. }
  354. static jit_node_t *
  355. emit_movi (scm_jit_state *j, jit_gpr_t r, jit_word_t i)
  356. {
  357. jit_node_t *k = jit_movi (r, i);
  358. record_gpr_clobber (j, r);
  359. return k;
  360. }
  361. static void
  362. emit_ldxi (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t src, jit_word_t offset)
  363. {
  364. if (offset == 0)
  365. jit_ldr (dst, src);
  366. else
  367. jit_ldxi (dst, src, offset);
  368. record_gpr_clobber (j, dst);
  369. }
  370. #define DEFINE_CLOBBER_RECORDING_EMITTER_R(stem, typ) \
  371. static void \
  372. emit_##stem (scm_jit_state *j, jit_##typ##_t dst, jit_##typ##_t a) \
  373. { \
  374. jit_##stem (dst, a); \
  375. record_##typ##_clobber (j, dst); \
  376. }
  377. #define DEFINE_CLOBBER_RECORDING_EMITTER_P(stem, typ) \
  378. static void \
  379. emit_##stem (scm_jit_state *j, jit_##typ##_t dst, jit_pointer_t a) \
  380. { \
  381. jit_##stem (dst, a); \
  382. record_##typ##_clobber (j, dst); \
  383. }
  384. #define DEFINE_CLOBBER_RECORDING_EMITTER_R_I(stem, typ) \
  385. static void \
  386. emit_##stem (scm_jit_state *j, jit_##typ##_t dst, \
  387. jit_##typ##_t a, jit_word_t b) \
  388. { \
  389. jit_##stem (dst, a, b); \
  390. record_##typ##_clobber (j, dst); \
  391. }
  392. #define DEFINE_CLOBBER_RECORDING_EMITTER_R_R(stem, typ) \
  393. static void \
  394. emit_##stem (scm_jit_state *j, jit_##typ##_t dst, \
  395. jit_##typ##_t a, jit_##typ##_t b) \
  396. { \
  397. jit_##stem (dst, a, b); \
  398. record_##typ##_clobber (j, dst); \
  399. }
  400. DEFINE_CLOBBER_RECORDING_EMITTER_R(ldr, gpr)
  401. DEFINE_CLOBBER_RECORDING_EMITTER_P(ldi, gpr)
  402. DEFINE_CLOBBER_RECORDING_EMITTER_R(movr, gpr)
  403. DEFINE_CLOBBER_RECORDING_EMITTER_R(comr, gpr)
  404. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(ldxr, gpr)
  405. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(addi, gpr)
  406. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(addr, gpr)
  407. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(addr_d, fpr)
  408. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(subi, gpr)
  409. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(subr, gpr)
  410. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(subr_d, fpr)
  411. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(muli, gpr)
  412. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(mulr, gpr)
  413. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(mulr_d, fpr)
  414. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(divr_d, fpr)
  415. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(andi, gpr)
  416. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(andr, gpr)
  417. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(orr, gpr)
  418. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(xorr, gpr)
  419. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(rshi, gpr)
  420. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(rshi_u, gpr)
  421. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(rshr, gpr)
  422. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(rshr_u, gpr)
  423. DEFINE_CLOBBER_RECORDING_EMITTER_R_I(lshi, gpr)
  424. DEFINE_CLOBBER_RECORDING_EMITTER_R_R(lshr, gpr)
  425. static void
  426. emit_reload_sp (scm_jit_state *j)
  427. {
  428. emit_ldxi (j, SP, THREAD, thread_offset_sp);
  429. set_register_state (j, SP_IN_REGISTER);
  430. }
  431. static void
  432. emit_store_sp (scm_jit_state *j)
  433. {
  434. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  435. jit_stxi (thread_offset_sp, THREAD, SP);
  436. }
  437. static void
  438. emit_reload_fp (scm_jit_state *j)
  439. {
  440. emit_ldxi (j, FP, THREAD, thread_offset_fp);
  441. set_register_state (j, FP_IN_REGISTER);
  442. }
  443. static void
  444. emit_store_fp (scm_jit_state *j)
  445. {
  446. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  447. jit_stxi (thread_offset_fp, THREAD, FP);
  448. }
  449. static uint32_t
  450. save_reloadable_register_state (scm_jit_state *j)
  451. {
  452. return j->register_state & (SP_IN_REGISTER | FP_IN_REGISTER);
  453. }
  454. static void
  455. restore_reloadable_register_state (scm_jit_state *j, uint32_t state)
  456. {
  457. if ((state & SP_IN_REGISTER) && !has_register_state (j, SP_IN_REGISTER))
  458. emit_reload_sp (j);
  459. if ((state & FP_IN_REGISTER) && !has_register_state (j, FP_IN_REGISTER))
  460. emit_reload_fp (j);
  461. }
  462. static void
  463. emit_subtract_stack_slots (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t src,
  464. uint32_t n)
  465. {
  466. emit_subi (j, dst, src, n * sizeof (union scm_vm_stack_element));
  467. }
  468. static void
  469. emit_load_mra (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t fp)
  470. {
  471. emit_ldxi (j, dst, fp, frame_offset_mra);
  472. }
  473. static jit_node_t *
  474. emit_store_mra (scm_jit_state *j, jit_gpr_t fp, jit_gpr_t t)
  475. {
  476. jit_node_t *addr = emit_movi (j, t, 0); /* patched later */
  477. ASSERT (frame_offset_mra == 0);
  478. jit_str (fp, t);
  479. return addr;
  480. }
  481. static void
  482. emit_load_vra (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t fp)
  483. {
  484. emit_ldxi (j, dst, fp, frame_offset_vra);
  485. }
  486. static void
  487. emit_store_vra (scm_jit_state *j, jit_gpr_t fp, jit_gpr_t t, const uint32_t *vra)
  488. {
  489. emit_movi (j, t, (intptr_t) vra);
  490. jit_stxi (frame_offset_vra, fp, t);
  491. }
  492. static void
  493. emit_load_prev_fp_offset (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t fp)
  494. {
  495. emit_ldxi (j, dst, fp, frame_offset_prev);
  496. }
  497. static void
  498. emit_store_prev_fp_offset (scm_jit_state *j, jit_gpr_t fp, jit_gpr_t t,
  499. uint32_t n)
  500. {
  501. emit_movi (j, t, n);
  502. jit_stxi (frame_offset_prev, fp, t);
  503. }
  504. static void
  505. emit_store_ip (scm_jit_state *j, jit_gpr_t ip)
  506. {
  507. jit_stxi (thread_offset_ip, THREAD, ip);
  508. }
  509. static void
  510. emit_store_current_ip (scm_jit_state *j, jit_gpr_t t)
  511. {
  512. emit_movi (j, t, (intptr_t) j->ip);
  513. emit_store_ip (j, t);
  514. }
  515. static void
  516. emit_pop_fp (scm_jit_state *j, jit_gpr_t old_fp)
  517. {
  518. emit_ldxi (j, old_fp, THREAD, thread_offset_fp);
  519. emit_load_prev_fp_offset (j, FP, old_fp);
  520. emit_lshi (j, FP, FP, 3); /* Multiply by sizeof (scm_vm_stack_element) */
  521. emit_addr (j, FP, old_fp, FP);
  522. set_register_state (j, FP_IN_REGISTER);
  523. emit_store_fp (j);
  524. }
  525. static void
  526. emit_reset_frame (scm_jit_state *j, uint32_t nlocals)
  527. {
  528. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  529. emit_subtract_stack_slots (j, SP, FP, nlocals);
  530. set_register_state (j, SP_IN_REGISTER);
  531. emit_store_sp (j);
  532. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  533. }
  534. static void
  535. emit_call (scm_jit_state *j, void *f)
  536. {
  537. jit_prepare ();
  538. jit_finishi (f);
  539. clear_scratch_register_state (j);
  540. }
  541. static void
  542. emit_call_r (scm_jit_state *j, void *f, jit_gpr_t a)
  543. {
  544. jit_prepare ();
  545. jit_pushargr (a);
  546. jit_finishi (f);
  547. clear_scratch_register_state (j);
  548. }
  549. static void
  550. emit_call_i (scm_jit_state *j, void *f, intptr_t a)
  551. {
  552. jit_prepare ();
  553. jit_pushargi (a);
  554. jit_finishi (f);
  555. clear_scratch_register_state (j);
  556. }
  557. static void
  558. emit_call_r_r (scm_jit_state *j, void *f, jit_gpr_t a, jit_gpr_t b)
  559. {
  560. jit_prepare ();
  561. jit_pushargr (a);
  562. jit_pushargr (b);
  563. jit_finishi (f);
  564. clear_scratch_register_state (j);
  565. }
  566. static void
  567. emit_call_r_i (scm_jit_state *j, void *f, jit_gpr_t a, intptr_t b)
  568. {
  569. jit_prepare ();
  570. jit_pushargr (a);
  571. jit_pushargi ((intptr_t) b);
  572. jit_finishi (f);
  573. clear_scratch_register_state (j);
  574. }
  575. static void
  576. emit_call_r_r_r (scm_jit_state *j, void *f, jit_gpr_t a, jit_gpr_t b,
  577. jit_gpr_t c)
  578. {
  579. jit_prepare ();
  580. jit_pushargr (a);
  581. jit_pushargr (b);
  582. jit_pushargr (c);
  583. jit_finishi (f);
  584. clear_scratch_register_state (j);
  585. }
  586. static void
  587. emit_alloc_frame_for_sp (scm_jit_state *j, jit_gpr_t t)
  588. {
  589. jit_node_t *k, *fast, *watermark;
  590. uint32_t saved_state = save_reloadable_register_state (j);
  591. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  592. emit_ldxi (j, t, THREAD, thread_offset_sp_min_since_gc);
  593. fast = jit_bger (SP, t);
  594. emit_ldxi (j, t, THREAD, thread_offset_stack_limit);
  595. watermark = jit_bger (SP, t);
  596. /* Slow case: call out to expand stack. */
  597. emit_store_current_ip (j, t);
  598. emit_call_r_r (j, scm_vm_intrinsics.expand_stack, THREAD, SP);
  599. restore_reloadable_register_state (j, saved_state);
  600. k = jit_jmpi ();
  601. /* Past sp_min_since_gc, but within stack_limit: update watermark and
  602. fall through. */
  603. jit_patch (watermark);
  604. jit_stxi (thread_offset_sp_min_since_gc, THREAD, SP);
  605. jit_patch (fast);
  606. /* Fast case: Just update sp. */
  607. emit_store_sp (j);
  608. jit_patch (k);
  609. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  610. }
  611. static void
  612. emit_alloc_frame (scm_jit_state *j, jit_gpr_t t, uint32_t nlocals)
  613. {
  614. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  615. emit_subtract_stack_slots (j, SP, FP, nlocals);
  616. emit_alloc_frame_for_sp (j, t);
  617. }
  618. static void
  619. emit_get_callee_vcode (scm_jit_state *j, jit_gpr_t dst)
  620. {
  621. emit_call_r (j, scm_vm_intrinsics.get_callee_vcode, THREAD);
  622. emit_retval (j, dst);
  623. emit_reload_sp (j);
  624. emit_reload_fp (j);
  625. }
  626. static void
  627. emit_get_vcode_low_byte (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t addr)
  628. {
  629. if (uint32_offset_low_byte == 0)
  630. jit_ldr_uc (dst, addr);
  631. else
  632. jit_ldxi_uc (dst, addr, uint32_offset_low_byte);
  633. record_gpr_clobber (j, dst);
  634. }
  635. static void
  636. emit_get_ip_relative_addr (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t ip,
  637. uint32_t offset)
  638. {
  639. uint32_t byte_offset = offset * sizeof (uint32_t);
  640. jit_ldxi_i (dst, ip, byte_offset);
  641. record_gpr_clobber (j, dst);
  642. emit_lshi (j, dst, dst, 2); /* Multiply by sizeof (uint32_t) */
  643. emit_addr (j, dst, dst, ip);
  644. }
  645. static void
  646. emit_exit (scm_jit_state *j)
  647. {
  648. /* emit_exit drops back to the interpreter. As such, it's always used
  649. in a context like:
  650. mcode = get_mcode
  651. if mcode:
  652. goto mcode
  653. else
  654. emit_exit
  655. Likewise, this position is usually around calls or returns, where
  656. SP and FP are both live. However! Lightning has a little register
  657. allocator internally which it uses to get temporary registers. It
  658. tracks what registers are used, to avoid clobbering live registers.
  659. Often the get_mcode operation looks like
  660. jit_ldi (T0, code_loc)
  661. But on many architectures, this requires a temporary, and because
  662. Lightning doesn't see a use of SP or FP before the goto, it thinks
  663. it can use these registers.
  664. So, here we insert a bogus dependencies on SP and FP, on the exit
  665. path. On this path they aren't needed, but they should keep the
  666. registers live up to the preceding branch, forcing the jit_ldi to
  667. choose another temporary to use. THREAD shouldn't need this
  668. treatment as Lightning won't allocate a callee-save register as a
  669. temporary, but who knows!
  670. */
  671. jit_xorr (FP, FP, FP);
  672. jit_xorr (SP, SP, SP);
  673. jit_patch_abs (jit_jmpi (), exit_mcode);
  674. }
  675. static jit_node_t*
  676. emit_push_frame (scm_jit_state *j, uint32_t proc_slot, uint32_t nlocals,
  677. const uint32_t *vra)
  678. {
  679. jit_gpr_t t = T0;
  680. jit_node_t *continuation;
  681. emit_reload_fp (j);
  682. emit_subtract_stack_slots (j, FP, FP, proc_slot);
  683. continuation = emit_store_mra (j, FP, t);
  684. emit_store_vra (j, FP, t, vra);
  685. emit_store_prev_fp_offset (j, FP, t, proc_slot);
  686. emit_store_fp (j);
  687. emit_reset_frame (j, nlocals);
  688. return continuation;
  689. }
  690. static void
  691. emit_indirect_tail_call (scm_jit_state *j)
  692. {
  693. jit_node_t *not_instrumented, *no_mcode;
  694. emit_get_callee_vcode (j, T0);
  695. /* FIXME: If all functions start with instrument-entry, no need for
  696. this check. */
  697. emit_get_vcode_low_byte (j, T1, T0);
  698. not_instrumented = jit_bnei (T1, scm_op_instrument_entry);
  699. emit_get_ip_relative_addr (j, T1, T0, 1);
  700. emit_ldxi (j, T1, T1, 0);
  701. no_mcode = jit_beqi (T1, 0);
  702. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER | SP_IN_REGISTER);
  703. jit_jmpr (T1);
  704. jit_patch (not_instrumented);
  705. jit_patch (no_mcode);
  706. emit_store_ip (j, T0);
  707. emit_exit (j);
  708. }
  709. static void
  710. emit_direct_tail_call (scm_jit_state *j, const uint32_t *vcode)
  711. {
  712. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER | SP_IN_REGISTER);
  713. if (vcode == j->start)
  714. {
  715. jit_patch_at (jit_jmpi (), j->labels[0]);
  716. }
  717. else if ((vcode[0] & 0xff) != scm_op_instrument_entry)
  718. {
  719. emit_movi (j, T0, (intptr_t) vcode);
  720. emit_store_ip (j, T0);
  721. emit_exit (j);
  722. }
  723. else
  724. {
  725. struct scm_jit_function_data *data;
  726. data = (struct scm_jit_function_data *) (vcode + (int32_t)(vcode[1]));
  727. if (data->mcode)
  728. {
  729. /* FIXME: Jump indirectly, to allow mcode to be changed
  730. (e.g. to add/remove breakpoints or hooks). */
  731. jit_patch_abs (jit_jmpi (), data->mcode);
  732. }
  733. else
  734. {
  735. jit_node_t *no_mcode;
  736. /* No need to track clobbers. */
  737. jit_ldi (T0, &data->mcode);
  738. no_mcode = jit_beqi (T0, 0);
  739. jit_jmpr (T0);
  740. jit_patch (no_mcode);
  741. jit_movi (T0, (intptr_t) vcode);
  742. emit_store_ip (j, T0);
  743. emit_exit (j);
  744. }
  745. }
  746. }
  747. static void
  748. emit_fp_ref_scm (scm_jit_state *j, jit_gpr_t dst, uint32_t slot)
  749. {
  750. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  751. emit_ldxi (j, dst, FP, -8 * ((ptrdiff_t) slot + 1));
  752. }
  753. static void
  754. emit_fp_set_scm (scm_jit_state *j, uint32_t slot, jit_gpr_t val)
  755. {
  756. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  757. jit_stxi (-8 * ((ptrdiff_t) slot + 1), FP, val);
  758. clear_register_state (j, SP_CACHE_GPR);
  759. }
  760. static void
  761. emit_sp_ref_scm (scm_jit_state *j, jit_gpr_t dst, uint32_t slot)
  762. {
  763. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  764. emit_ldxi (j, dst, SP, 8 * slot);
  765. }
  766. static void
  767. emit_sp_set_scm (scm_jit_state *j, uint32_t slot, jit_gpr_t val)
  768. {
  769. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  770. if (slot == 0)
  771. jit_str (SP, val);
  772. else
  773. jit_stxi (8 * slot, SP, val);
  774. set_sp_cache_gpr (j, slot, val);
  775. }
  776. /* Use when you know that the u64 value will be within the size_t range,
  777. for example when it's ensured by the compiler. */
  778. static void
  779. emit_sp_ref_sz (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  780. {
  781. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  782. if (BIGENDIAN && sizeof (size_t) == 4)
  783. emit_ldxi (j, dst, SP, src * 8 + 4);
  784. else
  785. emit_ldxi (j, dst, SP, src * 8);
  786. }
  787. static void
  788. emit_sp_set_sz (scm_jit_state *j, uint32_t dst, jit_gpr_t src)
  789. {
  790. size_t offset = dst * 8;
  791. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  792. if (sizeof (size_t) == 4)
  793. {
  794. size_t lo, hi;
  795. if (BIGENDIAN)
  796. lo = offset + 4, hi = offset;
  797. else
  798. lo = offset, hi = offset + 4;
  799. jit_stxi (lo, SP, src);
  800. /* Set high word to 0. Clobber src. */
  801. emit_xorr (j, src, src, src);
  802. jit_stxi (hi, SP, src);
  803. }
  804. else
  805. {
  806. jit_stxi (offset, SP, src);
  807. set_sp_cache_gpr (j, dst, src);
  808. }
  809. }
  810. #if SIZEOF_UINTPTR_T >= 8
  811. static void
  812. emit_sp_ref_u64 (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  813. {
  814. size_t offset = src * 8;
  815. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  816. emit_ldxi (j, dst, SP, offset);
  817. }
  818. static void
  819. emit_sp_set_u64 (scm_jit_state *j, uint32_t dst, jit_gpr_t src)
  820. {
  821. size_t offset = dst * 8;
  822. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  823. if (dst == 0)
  824. jit_str (SP, src);
  825. else
  826. jit_stxi (offset, SP, src);
  827. set_sp_cache_gpr (j, dst, src);
  828. }
  829. static void
  830. emit_sp_ref_s64 (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  831. {
  832. emit_sp_ref_u64 (j, dst, src);
  833. }
  834. static void
  835. emit_sp_set_s64 (scm_jit_state *j, uint32_t dst, jit_gpr_t src)
  836. {
  837. emit_sp_set_u64 (j, dst, src);
  838. }
  839. static void
  840. emit_sp_ref_ptr (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  841. {
  842. emit_sp_ref_u64 (j, dst, src);
  843. }
  844. #else /* SCM_SIZEOF_UINTPTR_T >= 8 */
  845. static void
  846. emit_sp_ref_u64 (scm_jit_state *j, jit_gpr_t dst_lo, jit_gpr_t dst_hi,
  847. uint32_t src)
  848. {
  849. size_t offset = src * 8;
  850. jit_gpr_t first, second;
  851. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  852. #if BIGENDIAN
  853. first = dst_hi, second = dst_lo;
  854. #else
  855. first = dst_lo, second = dst_hi;
  856. #endif
  857. emit_ldxi (j, first, SP, offset);
  858. emit_ldxi (j, second, SP, offset + 4);
  859. }
  860. static void
  861. emit_sp_set_u64 (scm_jit_state *j, uint32_t dst, jit_gpr_t lo, jit_gpr_t hi)
  862. {
  863. size_t offset = dst * 8;
  864. jit_gpr_t first, second;
  865. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  866. #if BIGENDIAN
  867. first = hi, second = lo;
  868. #else
  869. first = lo, second = hi;
  870. #endif
  871. if (offset == 0)
  872. jit_str (SP, first);
  873. else
  874. jit_stxi (offset, SP, first);
  875. jit_stxi (offset + 4, SP, second);
  876. clear_register_state (j, SP_CACHE_GPR);
  877. }
  878. static void
  879. emit_sp_ref_s64 (scm_jit_state *j, jit_gpr_t dst_lo, jit_gpr_t dst_hi,
  880. uint32_t src)
  881. {
  882. emit_sp_ref_u64 (j, dst_lo, dst_hi, src);
  883. }
  884. static void
  885. emit_sp_set_s64 (scm_jit_state *j, uint32_t dst, jit_gpr_t lo, jit_gpr_t hi)
  886. {
  887. emit_sp_set_u64 (j, dst, lo, hi);
  888. }
  889. static void
  890. emit_sp_ref_u64_lower_half (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  891. {
  892. size_t offset = src * 8;
  893. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  894. emit_ldxi (j, dst, SP, offset);
  895. }
  896. static void
  897. emit_sp_ref_ptr (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  898. {
  899. emit_sp_ref_u64_lower_half (j, dst, src);
  900. }
  901. #endif /* SCM_SIZEOF_UINTPTR_T >= 8 */
  902. static void
  903. emit_sp_ref_f64 (scm_jit_state *j, jit_fpr_t dst, uint32_t src)
  904. {
  905. size_t offset = src * 8;
  906. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  907. if (offset == 0)
  908. jit_ldr_d (dst, SP);
  909. else
  910. jit_ldxi_d (dst, SP, offset);
  911. record_fpr_clobber (j, dst);
  912. }
  913. static void
  914. emit_sp_set_f64 (scm_jit_state *j, uint32_t dst, jit_fpr_t src)
  915. {
  916. size_t offset = dst * 8;
  917. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  918. if (offset == 0)
  919. jit_str_d (SP, src);
  920. else
  921. jit_stxi_d (offset, SP, src);
  922. set_sp_cache_fpr (j, dst, src);
  923. }
  924. static void
  925. emit_mov (scm_jit_state *j, uint32_t dst, uint32_t src, jit_gpr_t t)
  926. {
  927. emit_sp_ref_scm (j, t, src);
  928. emit_sp_set_scm (j, dst, t);
  929. /* FIXME: The compiler currently emits "push", "mov", etc for SCM,
  930. F64, U64, and S64 variables. However SCM values are the usual
  931. case, and on a 32-bit machine it might be cheaper to move a SCM
  932. than to move a 64-bit number. */
  933. if (sizeof (void*) < sizeof (union scm_vm_stack_element))
  934. {
  935. /* Copy the high word as well. */
  936. uintptr_t src_offset = src * sizeof (union scm_vm_stack_element);
  937. uintptr_t dst_offset = dst * sizeof (union scm_vm_stack_element);
  938. jit_ldxi (t, SP, src_offset + sizeof (void*));
  939. jit_stxi (dst_offset + sizeof (void*), SP, t);
  940. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  941. }
  942. else
  943. /* In any case since we move the register using GPRs, it won't be in
  944. a cached FPR. */
  945. clear_register_state (j, SP_CACHE_FPR);
  946. }
  947. static jit_node_t*
  948. emit_branch_if_frame_locals_count_less_than (scm_jit_state *j, jit_gpr_t t,
  949. uint32_t nlocals)
  950. {
  951. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  952. emit_subr (j, t, FP, SP);
  953. return jit_blti (t, nlocals * sizeof (union scm_vm_stack_element));
  954. }
  955. static jit_node_t*
  956. emit_branch_if_frame_locals_count_eq (scm_jit_state *j, jit_gpr_t t,
  957. uint32_t nlocals)
  958. {
  959. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  960. emit_subr (j, t, FP, SP);
  961. return jit_beqi (t, nlocals * sizeof (union scm_vm_stack_element));
  962. }
  963. static jit_node_t*
  964. emit_branch_if_frame_locals_count_not_eq (scm_jit_state *j, jit_gpr_t t,
  965. uint32_t nlocals)
  966. {
  967. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  968. emit_subr (j, t, FP, SP);
  969. return jit_bnei (t, nlocals * sizeof (union scm_vm_stack_element));
  970. }
  971. static jit_node_t*
  972. emit_branch_if_frame_locals_count_greater_than (scm_jit_state *j, jit_gpr_t t,
  973. uint32_t nlocals)
  974. {
  975. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  976. emit_subr (j, t, FP, SP);
  977. return jit_bgti (t, nlocals * sizeof (union scm_vm_stack_element));
  978. }
  979. static void
  980. emit_load_fp_slot (scm_jit_state *j, jit_gpr_t dst, uint32_t slot)
  981. {
  982. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  983. emit_subi (j, dst, FP, (slot + 1) * sizeof (union scm_vm_stack_element));
  984. }
  985. static jit_node_t *
  986. emit_branch_if_immediate (scm_jit_state *j, jit_gpr_t r)
  987. {
  988. return jit_bmsi (r, 6);
  989. }
  990. static void
  991. emit_load_heap_object_word (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t r,
  992. uint32_t word)
  993. {
  994. emit_ldxi (j, dst, r, word * sizeof(SCM));
  995. }
  996. static void
  997. emit_load_heap_object_tc (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t r,
  998. scm_t_bits mask)
  999. {
  1000. emit_load_heap_object_word (j, dst, r, 0);
  1001. emit_andi (j, dst, dst, mask);
  1002. }
  1003. static jit_node_t *
  1004. emit_branch_if_heap_object_has_tc (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
  1005. scm_t_bits mask, scm_t_bits tc)
  1006. {
  1007. emit_load_heap_object_tc (j, t, r, mask);
  1008. return jit_beqi (t, tc);
  1009. }
  1010. static jit_node_t *
  1011. emit_branch_if_heap_object_not_tc (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
  1012. scm_t_bits mask, scm_t_bits tc)
  1013. {
  1014. emit_load_heap_object_tc (j, t, r, mask);
  1015. return jit_bnei (t, tc);
  1016. }
  1017. static jit_node_t *
  1018. emit_branch_if_heap_object_not_tc7 (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
  1019. scm_t_bits tc7)
  1020. {
  1021. return emit_branch_if_heap_object_not_tc (j, r, t, 0x7f, tc7);
  1022. }
  1023. static jit_node_t*
  1024. emit_entry_trampoline (scm_jit_state *j)
  1025. {
  1026. jit_node_t *thread, *ip, *exit;
  1027. jit_prolog ();
  1028. jit_frame (entry_frame_size);
  1029. thread = jit_arg ();
  1030. ip = jit_arg ();
  1031. /* Load our reserved registers: THREAD and SP. */
  1032. jit_getarg (THREAD, thread);
  1033. emit_reload_sp (j);
  1034. /* Load FP, set during call sequences. */
  1035. emit_reload_fp (j);
  1036. /* Jump to the mcode! */
  1037. jit_getarg (T0, ip);
  1038. jit_jmpr (T0);
  1039. exit = jit_indirect ();
  1040. /* When mcode returns, interpreter should continue with vp->ip. */
  1041. jit_ret ();
  1042. return exit;
  1043. }
  1044. static void
  1045. emit_handle_interrupts_trampoline (scm_jit_state *j)
  1046. {
  1047. jit_prolog ();
  1048. jit_tramp (entry_frame_size);
  1049. /* Precondition: IP synced, MRA in T0. */
  1050. emit_call_r_r (j, scm_vm_intrinsics.push_interrupt_frame, THREAD, T0);
  1051. emit_reload_sp (j);
  1052. emit_reload_fp (j);
  1053. emit_direct_tail_call (j, scm_vm_intrinsics.handle_interrupt_code);
  1054. }
  1055. /* To limit the number of mmap calls and re-emission of JIT code, use
  1056. 256 kB code arenas. Unused pages won't be resident. Assume pages
  1057. are power-of-two-sized and this size is a multiple of the page size
  1058. on all architectures. */
  1059. static const size_t default_code_arena_size = 0x40000;
  1060. static struct code_arena *
  1061. allocate_code_arena (size_t size, struct code_arena *prev)
  1062. {
  1063. struct code_arena *ret = malloc (sizeof (struct code_arena));
  1064. if (!ret) return NULL;
  1065. memset (ret, 0, sizeof (*ret));
  1066. ret->used = 0;
  1067. ret->size = size;
  1068. ret->prev = prev;
  1069. ret->base = mmap (NULL, ret->size,
  1070. PROT_EXEC | PROT_READ | PROT_WRITE,
  1071. MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  1072. if (ret->base == MAP_FAILED)
  1073. {
  1074. perror ("allocating JIT code buffer failed");
  1075. free (ret);
  1076. return NULL;
  1077. }
  1078. INFO ("allocated code arena, %p-%p\n", ret->base, ret->base + ret->size);
  1079. return ret;
  1080. }
  1081. static void
  1082. prepare_jit_state (scm_jit_state *j)
  1083. {
  1084. j->jit = jit_new_state ();
  1085. }
  1086. static void
  1087. reset_jit_state (scm_jit_state *j)
  1088. {
  1089. jit_clear_state ();
  1090. jit_destroy_state ();
  1091. j->jit = NULL;
  1092. }
  1093. static void *
  1094. emit_code (scm_jit_state *j)
  1095. {
  1096. uint8_t *ret = NULL;
  1097. jit_realize ();
  1098. jit_get_data (NULL, NULL);
  1099. jit_set_data (NULL, 0, JIT_DISABLE_DATA | JIT_DISABLE_NOTE);
  1100. if (!j->code_arena)
  1101. j->code_arena = allocate_code_arena (default_code_arena_size, NULL);
  1102. if (!j->code_arena)
  1103. /* Resource exhaustion; turn off JIT. */
  1104. return NULL;
  1105. while (1)
  1106. {
  1107. struct code_arena *arena = j->code_arena;
  1108. jit_set_code (arena->base + arena->used, arena->size - arena->used);
  1109. ret = jit_emit ();
  1110. if (ret)
  1111. {
  1112. jit_word_t size = 0;
  1113. jit_get_code (&size);
  1114. ASSERT (size <= (arena->size - arena->used));
  1115. DEBUG ("mcode: %p,+%zu\n", ret, size);
  1116. arena->used += size;
  1117. /* Align next JIT to 16-byte boundaries to optimize initial
  1118. icache fetch. */
  1119. arena->used = (arena->used + 15) & ~15;
  1120. /* Assertion should not be invalidated as arena size is a
  1121. multiple of 16. */
  1122. ASSERT (arena->used <= arena->size);
  1123. return ret;
  1124. }
  1125. else
  1126. {
  1127. if (arena->used == 0)
  1128. {
  1129. /* Code too big to fit into empty arena; allocate a larger
  1130. one. */
  1131. INFO ("code didn't fit in empty arena of size %zu\n", arena->size);
  1132. arena = allocate_code_arena (arena->size * 2, arena->prev);
  1133. if (!arena)
  1134. return NULL;
  1135. munmap (j->code_arena->base, j->code_arena->size);
  1136. free (j->code_arena);
  1137. j->code_arena = arena;
  1138. }
  1139. else
  1140. {
  1141. /* Arena full; allocate another. */
  1142. /* FIXME: If partial code that we wrote crosses a page
  1143. boundary, we could tell the OS to forget about the tail
  1144. pages. */
  1145. INFO ("code didn't fit in arena tail %zu\n",
  1146. arena->size - arena->used);
  1147. arena = allocate_code_arena (arena->size, arena);
  1148. if (!arena)
  1149. return NULL;
  1150. j->code_arena = arena;
  1151. }
  1152. }
  1153. }
  1154. }
  1155. static void
  1156. emit_free_variable_ref (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t prog,
  1157. size_t n)
  1158. {
  1159. emit_load_heap_object_word (j, dst, prog,
  1160. n + program_word_offset_free_variable);
  1161. }
  1162. static void
  1163. add_inter_instruction_patch (scm_jit_state *j, jit_node_t *label,
  1164. const uint32_t *target)
  1165. {
  1166. ASSERT (j->start <= target && target < j->end);
  1167. jit_patch_at (label, j->labels[target - j->start]);
  1168. }
  1169. static void
  1170. bad_instruction (scm_jit_state *j)
  1171. {
  1172. ASSERT (0);
  1173. }
  1174. static void
  1175. compile_halt (scm_jit_state *j)
  1176. {
  1177. bad_instruction (j);
  1178. }
  1179. static void
  1180. compile_call (scm_jit_state *j, uint32_t proc, uint32_t nlocals)
  1181. {
  1182. /* 2 = size of call inst */
  1183. jit_node_t *mcont = emit_push_frame (j, proc, nlocals, j->ip + 2);
  1184. emit_indirect_tail_call (j);
  1185. jit_patch (mcont);
  1186. reset_register_state (j, FP_IN_REGISTER | SP_IN_REGISTER);
  1187. j->frame_size = -1;
  1188. }
  1189. static void
  1190. compile_call_label (scm_jit_state *j, uint32_t proc, uint32_t nlocals, const uint32_t *vcode)
  1191. {
  1192. /* 2 = size of call-label inst */
  1193. jit_node_t *mcont = emit_push_frame (j, proc, nlocals, j->ip + 3);
  1194. emit_direct_tail_call (j, vcode);
  1195. jit_patch (mcont);
  1196. reset_register_state (j, FP_IN_REGISTER | SP_IN_REGISTER);
  1197. j->frame_size = -1;
  1198. }
  1199. static void
  1200. compile_tail_call (scm_jit_state *j)
  1201. {
  1202. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  1203. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1204. emit_indirect_tail_call (j);
  1205. j->frame_size = -1;
  1206. }
  1207. static void
  1208. compile_tail_call_label (scm_jit_state *j, const uint32_t *vcode)
  1209. {
  1210. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  1211. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1212. emit_direct_tail_call (j, vcode);
  1213. j->frame_size = -1;
  1214. }
  1215. static void
  1216. compile_instrument_entry (scm_jit_state *j, void *data)
  1217. {
  1218. }
  1219. static void
  1220. compile_instrument_loop (scm_jit_state *j, void *data)
  1221. {
  1222. /* Nothing to do. */
  1223. }
  1224. static void
  1225. compile_receive (scm_jit_state *j, uint16_t dst, uint16_t proc, uint32_t nlocals)
  1226. {
  1227. jit_gpr_t t = T0;
  1228. jit_node_t *k;
  1229. uint32_t saved_state = j->register_state;
  1230. k = emit_branch_if_frame_locals_count_greater_than (j, t, proc);
  1231. emit_store_current_ip (j, T0);
  1232. emit_call (j, scm_vm_intrinsics.error_no_values);
  1233. j->register_state = saved_state;
  1234. jit_patch (k);
  1235. emit_fp_ref_scm (j, t, proc);
  1236. emit_fp_set_scm (j, dst, t);
  1237. emit_reset_frame (j, nlocals);
  1238. j->frame_size = nlocals;
  1239. }
  1240. static void
  1241. compile_receive_values (scm_jit_state *j, uint32_t proc, uint8_t allow_extra,
  1242. uint32_t nvalues)
  1243. {
  1244. jit_gpr_t t = T0;
  1245. uint32_t saved_state = j->register_state;
  1246. if (allow_extra)
  1247. {
  1248. jit_node_t *k;
  1249. k = emit_branch_if_frame_locals_count_greater_than (j, t, proc+nvalues-1);
  1250. emit_store_current_ip (j, T0);
  1251. emit_call (j, scm_vm_intrinsics.error_not_enough_values);
  1252. j->register_state = saved_state;
  1253. jit_patch (k);
  1254. }
  1255. else
  1256. {
  1257. jit_node_t *k;
  1258. k = emit_branch_if_frame_locals_count_eq (j, t, proc + nvalues);
  1259. emit_store_current_ip (j, T0);
  1260. emit_call_i (j, scm_vm_intrinsics.error_wrong_number_of_values, nvalues);
  1261. j->register_state = saved_state;
  1262. jit_patch (k);
  1263. j->frame_size = proc + nvalues;
  1264. }
  1265. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1266. }
  1267. static void
  1268. compile_shuffle_down (scm_jit_state *j, uint16_t from, uint16_t to)
  1269. {
  1270. jit_gpr_t walk = T0, t = T1;
  1271. size_t offset = (from - to) * sizeof (union scm_vm_stack_element);
  1272. jit_node_t *done, *head, *back;
  1273. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  1274. emit_load_fp_slot (j, walk, from);
  1275. done = jit_bltr (walk, SP);
  1276. head = jit_label ();
  1277. jit_ldr (t, walk);
  1278. jit_stxi (offset, walk, t);
  1279. jit_subi (walk, walk, sizeof (union scm_vm_stack_element));
  1280. back = jit_bger (walk, SP);
  1281. jit_patch_at (back, head);
  1282. jit_patch (done);
  1283. jit_addi (SP, SP, offset);
  1284. emit_store_sp (j);
  1285. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1286. if (j->frame_size >= 0)
  1287. j->frame_size -= (from - to);
  1288. }
  1289. static void
  1290. compile_return_values (scm_jit_state *j)
  1291. {
  1292. jit_gpr_t old_fp = T0, ra = T1;
  1293. jit_node_t *interp;
  1294. emit_pop_fp (j, old_fp);
  1295. emit_load_mra (j, ra, old_fp);
  1296. interp = jit_beqi (ra, 0);
  1297. jit_jmpr (ra);
  1298. jit_patch (interp);
  1299. emit_load_vra (j, ra, old_fp);
  1300. emit_store_ip (j, ra);
  1301. emit_exit (j);
  1302. j->frame_size = -1;
  1303. }
  1304. static void
  1305. compile_subr_call (scm_jit_state *j, uint32_t idx)
  1306. {
  1307. jit_gpr_t t = T0, ret = T1;
  1308. void *subr;
  1309. uint32_t i;
  1310. jit_node_t *immediate, *not_values, *k;
  1311. ASSERT (j->frame_size >= 0);
  1312. subr = scm_subr_function_by_index (idx);
  1313. emit_store_current_ip (j, t);
  1314. jit_prepare ();
  1315. for (i = 2; i <= j->frame_size; i++)
  1316. {
  1317. emit_sp_ref_scm (j, t, j->frame_size - i);
  1318. jit_pushargr (t);
  1319. }
  1320. jit_finishi (subr);
  1321. clear_scratch_register_state (j);
  1322. jit_retval (ret);
  1323. immediate = emit_branch_if_immediate (j, ret);
  1324. not_values = emit_branch_if_heap_object_not_tc7 (j, ret, t, scm_tc7_values);
  1325. emit_call_r_r (j, scm_vm_intrinsics.unpack_values_object, THREAD, ret);
  1326. emit_reload_fp (j);
  1327. emit_reload_sp (j);
  1328. k = jit_jmpi ();
  1329. jit_patch (immediate);
  1330. jit_patch (not_values);
  1331. emit_reload_fp (j);
  1332. emit_subtract_stack_slots (j, SP, FP, 1);
  1333. set_register_state (j, SP_IN_REGISTER);
  1334. emit_store_sp (j);
  1335. jit_str (SP, ret);
  1336. jit_patch (k);
  1337. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1338. j->frame_size = -1;
  1339. }
  1340. static void
  1341. compile_foreign_call (scm_jit_state *j, uint16_t cif_idx, uint16_t ptr_idx)
  1342. {
  1343. uint32_t saved_state;
  1344. ASSERT (j->frame_size >= 0);
  1345. emit_store_current_ip (j, T0);
  1346. emit_sp_ref_scm (j, T0, j->frame_size - 1);
  1347. emit_free_variable_ref (j, T1, T0, cif_idx);
  1348. emit_free_variable_ref (j, T2, T0, ptr_idx);
  1349. /* FIXME: Inline the foreign call. */
  1350. saved_state = save_reloadable_register_state (j);
  1351. emit_call_r_r_r (j, scm_vm_intrinsics.foreign_call, THREAD, T1, T2);
  1352. restore_reloadable_register_state (j, saved_state);
  1353. j->frame_size = 2; /* Return value and errno. */
  1354. }
  1355. static void
  1356. compile_continuation_call (scm_jit_state *j, uint32_t contregs_idx)
  1357. {
  1358. emit_reload_fp (j);
  1359. emit_store_current_ip (j, T0);
  1360. emit_fp_ref_scm (j, T0, 0);
  1361. emit_free_variable_ref (j, T0, T0, contregs_idx);
  1362. emit_call_r_r (j, scm_vm_intrinsics.reinstate_continuation_x, THREAD, T0);
  1363. /* Does not fall through. */
  1364. j->frame_size = -1;
  1365. }
  1366. static void
  1367. compile_compose_continuation (scm_jit_state *j, uint32_t cont_idx)
  1368. {
  1369. jit_node_t *interp;
  1370. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  1371. emit_store_current_ip (j, T0);
  1372. emit_fp_ref_scm (j, T0, 0);
  1373. emit_free_variable_ref (j, T0, T0, cont_idx);
  1374. emit_call_r_r (j, scm_vm_intrinsics.compose_continuation, THREAD, T0);
  1375. jit_retval (T0);
  1376. interp = jit_beqi (T0, 0);
  1377. emit_reload_sp (j);
  1378. emit_reload_fp (j);
  1379. jit_jmpr (T0);
  1380. jit_patch (interp);
  1381. emit_exit (j);
  1382. j->frame_size = -1;
  1383. }
  1384. static void
  1385. compile_capture_continuation (scm_jit_state *j, uint32_t dst)
  1386. {
  1387. emit_store_current_ip (j, T0);
  1388. emit_call_r (j, scm_vm_intrinsics.capture_continuation, THREAD);
  1389. jit_retval (T0);
  1390. emit_reload_sp (j);
  1391. emit_reload_fp (j);
  1392. emit_sp_set_scm (j, dst, T0);
  1393. }
  1394. static void
  1395. compile_abort (scm_jit_state *j)
  1396. {
  1397. jit_node_t *k, *interp;
  1398. jit_movi (T0, (intptr_t) (j->ip + 1));
  1399. emit_store_ip (j, T0);
  1400. k = jit_movi (T0, 0);
  1401. emit_call_r_r (j, scm_vm_intrinsics.abort_to_prompt, THREAD, T0);
  1402. jit_retval (T1_PRESERVED);
  1403. interp = jit_beqi (T1_PRESERVED, 0);
  1404. emit_reload_sp (j);
  1405. emit_reload_fp (j);
  1406. jit_jmpr (T1_PRESERVED);
  1407. jit_patch (interp);
  1408. emit_exit (j);
  1409. jit_patch (k);
  1410. j->frame_size = -1;
  1411. }
  1412. static void
  1413. compile_builtin_ref (scm_jit_state *j, uint16_t dst, uint16_t idx)
  1414. {
  1415. SCM builtin = scm_vm_builtin_ref (idx);
  1416. emit_movi (j, T0, SCM_UNPACK (builtin));
  1417. emit_sp_set_scm (j, dst, T0);
  1418. }
  1419. static void
  1420. compile_throw (scm_jit_state *j, uint16_t key, uint16_t args)
  1421. {
  1422. emit_store_current_ip (j, T0);
  1423. emit_sp_ref_scm (j, T0, key);
  1424. emit_sp_ref_scm (j, T1, args);
  1425. emit_call_r_r (j, scm_vm_intrinsics.throw_, T0, T1);
  1426. /* throw_ does not return. */
  1427. }
  1428. static void
  1429. compile_throw_value (scm_jit_state *j, uint32_t val,
  1430. const void *key_subr_and_message)
  1431. {
  1432. emit_store_current_ip (j, T0);
  1433. emit_sp_ref_scm (j, T0, val);
  1434. emit_call_r_i (j, scm_vm_intrinsics.throw_with_value, T0,
  1435. (intptr_t) key_subr_and_message);
  1436. /* throw_with_value does not return. */
  1437. }
  1438. static void
  1439. compile_throw_value_and_data (scm_jit_state *j, uint32_t val,
  1440. const void *key_subr_and_message)
  1441. {
  1442. emit_store_current_ip (j, T0);
  1443. emit_sp_ref_scm (j, T0, val);
  1444. emit_call_r_i (j, scm_vm_intrinsics.throw_with_value_and_data, T0,
  1445. (intptr_t) key_subr_and_message);
  1446. /* throw_with_value_and_data does not return. */
  1447. }
  1448. static void
  1449. compile_assert_nargs_ee (scm_jit_state *j, uint32_t nlocals)
  1450. {
  1451. jit_node_t *k;
  1452. jit_gpr_t t = T0;
  1453. uint32_t saved_state = j->register_state;
  1454. k = emit_branch_if_frame_locals_count_eq (j, t, nlocals);
  1455. emit_store_current_ip (j, t);
  1456. emit_call_r (j, scm_vm_intrinsics.error_wrong_num_args, THREAD);
  1457. jit_patch (k);
  1458. j->register_state = saved_state;
  1459. j->frame_size = nlocals;
  1460. }
  1461. static void
  1462. compile_assert_nargs_ge (scm_jit_state *j, uint32_t nlocals)
  1463. {
  1464. if (nlocals > 0)
  1465. {
  1466. jit_gpr_t t = T0;
  1467. jit_node_t *k;
  1468. uint32_t saved_state = j->register_state;
  1469. k = emit_branch_if_frame_locals_count_greater_than (j, t, nlocals-1);
  1470. emit_store_current_ip (j, t);
  1471. emit_call_r (j, scm_vm_intrinsics.error_wrong_num_args, THREAD);
  1472. jit_patch (k);
  1473. j->register_state = saved_state;
  1474. }
  1475. }
  1476. static void
  1477. compile_assert_nargs_le (scm_jit_state *j, uint32_t nlocals)
  1478. {
  1479. jit_node_t *k;
  1480. jit_gpr_t t = T0;
  1481. uint32_t saved_state = j->register_state;
  1482. k = emit_branch_if_frame_locals_count_less_than (j, t, nlocals + 1);
  1483. emit_store_current_ip (j, t);
  1484. emit_call_r (j, scm_vm_intrinsics.error_wrong_num_args, THREAD);
  1485. jit_patch (k);
  1486. j->register_state = saved_state;
  1487. }
  1488. static void
  1489. compile_alloc_frame (scm_jit_state *j, uint32_t nlocals)
  1490. {
  1491. jit_gpr_t t = T0, saved_frame_size = T1_PRESERVED;
  1492. if (j->frame_size < 0)
  1493. jit_subr (saved_frame_size, FP, SP);
  1494. /* This will clear the regalloc, so no need to track clobbers. */
  1495. emit_alloc_frame (j, t, nlocals);
  1496. if (j->frame_size >= 0)
  1497. {
  1498. int32_t slots = nlocals - j->frame_size;
  1499. if (slots > 0)
  1500. {
  1501. jit_movi (t, SCM_UNPACK (SCM_UNDEFINED));
  1502. while (slots-- > 0)
  1503. emit_sp_set_scm (j, slots, t);
  1504. }
  1505. }
  1506. else
  1507. {
  1508. jit_node_t *head, *k, *back;
  1509. jit_gpr_t walk = saved_frame_size;
  1510. jit_subr (walk, FP, saved_frame_size);
  1511. k = jit_bler (walk, SP);
  1512. jit_movi (t, SCM_UNPACK (SCM_UNDEFINED));
  1513. head = jit_label ();
  1514. jit_subi (walk, walk, sizeof (union scm_vm_stack_element));
  1515. jit_str (walk, t);
  1516. back = jit_bner (walk, SP);
  1517. jit_patch_at (back, head);
  1518. jit_patch (k);
  1519. }
  1520. j->frame_size = nlocals;
  1521. }
  1522. static void
  1523. compile_reset_frame (scm_jit_state *j, uint32_t nlocals)
  1524. {
  1525. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1526. emit_reset_frame (j, nlocals);
  1527. j->frame_size = nlocals;
  1528. }
  1529. static void
  1530. compile_push (scm_jit_state *j, uint32_t src)
  1531. {
  1532. jit_gpr_t t = T0;
  1533. jit_subi (SP, SP, sizeof (union scm_vm_stack_element));
  1534. emit_alloc_frame_for_sp (j, t);
  1535. emit_mov (j, 0, src + 1, t);
  1536. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1537. if (j->frame_size >= 0)
  1538. j->frame_size++;
  1539. }
  1540. static void
  1541. compile_pop (scm_jit_state *j, uint32_t dst)
  1542. {
  1543. emit_mov (j, dst + 1, 0, T0);
  1544. jit_addi (SP, SP, sizeof (union scm_vm_stack_element));
  1545. emit_store_sp (j);
  1546. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1547. if (j->frame_size >= 0)
  1548. j->frame_size--;
  1549. }
  1550. static void
  1551. compile_drop (scm_jit_state *j, uint32_t nvalues)
  1552. {
  1553. jit_addi (SP, SP, nvalues * sizeof (union scm_vm_stack_element));
  1554. emit_store_sp (j);
  1555. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1556. if (j->frame_size >= 0)
  1557. j->frame_size -= nvalues;
  1558. }
  1559. static void
  1560. compile_assert_nargs_ee_locals (scm_jit_state *j, uint16_t expected,
  1561. uint16_t nlocals)
  1562. {
  1563. compile_assert_nargs_ee (j, expected);
  1564. if (nlocals)
  1565. compile_alloc_frame (j, expected + nlocals);
  1566. }
  1567. static void
  1568. compile_expand_apply_argument (scm_jit_state *j)
  1569. {
  1570. emit_store_current_ip (j, T0);
  1571. emit_call_r (j, scm_vm_intrinsics.expand_apply_argument, THREAD);
  1572. emit_reload_sp (j);
  1573. emit_reload_fp (j);
  1574. j->frame_size = -1;
  1575. }
  1576. static void
  1577. compile_bind_kwargs (scm_jit_state *j, uint32_t nreq, uint8_t flags,
  1578. uint32_t nreq_and_opt, uint32_t ntotal, const void *kw)
  1579. {
  1580. uint8_t allow_other_keys = flags & 0x1, has_rest = flags & 0x2;
  1581. jit_gpr_t t = T0, npositional = T1;
  1582. emit_store_current_ip (j, t);
  1583. jit_prepare ();
  1584. jit_pushargr (THREAD);
  1585. jit_pushargi (nreq);
  1586. jit_pushargi (nreq_and_opt - nreq);
  1587. jit_finishi (scm_vm_intrinsics.compute_kwargs_npositional);
  1588. clear_scratch_register_state (j);
  1589. jit_retval_i (npositional);
  1590. jit_prepare ();
  1591. jit_pushargr (THREAD);
  1592. jit_pushargr (npositional);
  1593. jit_pushargi (ntotal);
  1594. jit_pushargi ((intptr_t) kw);
  1595. jit_pushargi (!has_rest);
  1596. jit_pushargi (allow_other_keys);
  1597. jit_finishi (scm_vm_intrinsics.bind_kwargs);
  1598. clear_scratch_register_state (j);
  1599. if (has_rest)
  1600. {
  1601. emit_call_r_i (j, scm_vm_intrinsics.cons_rest, THREAD, ntotal);
  1602. jit_retval (t);
  1603. emit_reload_fp (j);
  1604. emit_fp_set_scm (j, nreq_and_opt, t);
  1605. }
  1606. else
  1607. emit_reload_fp (j);
  1608. emit_reset_frame (j, ntotal);
  1609. j->frame_size = ntotal;
  1610. }
  1611. static void
  1612. compile_bind_rest (scm_jit_state *j, uint32_t dst)
  1613. {
  1614. jit_node_t *k, *cons;
  1615. jit_gpr_t t = T1;
  1616. cons = emit_branch_if_frame_locals_count_greater_than (j, t, dst);
  1617. compile_alloc_frame (j, dst + 1);
  1618. emit_movi (j, t, SCM_UNPACK (SCM_EOL));
  1619. emit_sp_set_scm (j, 0, t);
  1620. k = jit_jmpi ();
  1621. jit_patch (cons);
  1622. emit_store_current_ip (j, t);
  1623. emit_call_r_i (j, scm_vm_intrinsics.cons_rest, THREAD, dst);
  1624. emit_retval (j, t);
  1625. compile_reset_frame (j, dst + 1);
  1626. emit_sp_set_scm (j, 0, t);
  1627. jit_patch (k);
  1628. }
  1629. static void
  1630. compile_allocate_words (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1631. {
  1632. jit_gpr_t t = T0;
  1633. emit_store_current_ip (j, t);
  1634. emit_sp_ref_sz (j, t, nwords);
  1635. emit_call_r_r (j, scm_vm_intrinsics.allocate_words, THREAD, t);
  1636. emit_retval (j, t);
  1637. record_gpr_clobber (j, t);
  1638. emit_reload_sp (j);
  1639. emit_sp_set_scm (j, dst, t);
  1640. }
  1641. static void
  1642. compile_allocate_words_immediate (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1643. {
  1644. jit_gpr_t t = T0;
  1645. emit_store_current_ip (j, t);
  1646. emit_movi (j, t, nwords);
  1647. emit_call_r_r (j, scm_vm_intrinsics.allocate_words, THREAD, t);
  1648. emit_retval (j, t);
  1649. emit_reload_sp (j);
  1650. emit_sp_set_scm (j, dst, t);
  1651. }
  1652. static void
  1653. compile_scm_ref (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1654. {
  1655. emit_sp_ref_scm (j, T0, obj);
  1656. emit_sp_ref_sz (j, T1, idx);
  1657. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  1658. emit_ldxr (j, T0, T0, T1);
  1659. emit_sp_set_scm (j, dst, T0);
  1660. }
  1661. static void
  1662. compile_scm_set (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  1663. {
  1664. emit_sp_ref_scm (j, T0, obj);
  1665. emit_sp_ref_sz (j, T1, idx);
  1666. emit_sp_ref_scm (j, T2, val);
  1667. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  1668. jit_stxr (T0, T1, T2);
  1669. }
  1670. static void
  1671. compile_scm_ref_tag (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t tag)
  1672. {
  1673. emit_sp_ref_scm (j, T0, obj);
  1674. emit_ldr (j, T0, T0);
  1675. emit_subi (j, T0, T0, tag);
  1676. emit_sp_set_scm (j, dst, T0);
  1677. }
  1678. static void
  1679. compile_scm_set_tag (scm_jit_state *j, uint8_t obj, uint8_t tag, uint8_t val)
  1680. {
  1681. emit_sp_ref_scm (j, T0, obj);
  1682. emit_sp_ref_scm (j, T1, val);
  1683. emit_addi (j, T1, T1, tag);
  1684. jit_str (T0, T1);
  1685. }
  1686. static void
  1687. compile_scm_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1688. {
  1689. emit_sp_ref_scm (j, T0, obj);
  1690. emit_ldxi (j, T0, T0, idx * sizeof (SCM));
  1691. emit_sp_set_scm (j, dst, T0);
  1692. }
  1693. static void
  1694. compile_scm_set_immediate (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  1695. {
  1696. emit_sp_ref_scm (j, T0, obj);
  1697. emit_sp_ref_scm (j, T1, val);
  1698. jit_stxi (idx * sizeof (SCM), T0, T1);
  1699. }
  1700. static void
  1701. compile_word_ref (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1702. {
  1703. emit_sp_ref_scm (j, T0, obj);
  1704. emit_sp_ref_sz (j, T1, idx);
  1705. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  1706. emit_ldxr (j, T0, T0, T1);
  1707. emit_sp_set_sz (j, dst, T0);
  1708. }
  1709. static void
  1710. compile_word_set (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  1711. {
  1712. emit_sp_ref_scm (j, T0, obj);
  1713. emit_sp_ref_sz (j, T1, idx);
  1714. emit_sp_ref_sz (j, T2, val);
  1715. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  1716. jit_stxr (T0, T1, T2);
  1717. }
  1718. static void
  1719. compile_word_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1720. {
  1721. emit_sp_ref_scm (j, T0, obj);
  1722. emit_ldxi (j, T0, T0, idx * sizeof (SCM));
  1723. emit_sp_set_sz (j, dst, T0);
  1724. }
  1725. static void
  1726. compile_word_set_immediate (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  1727. {
  1728. emit_sp_ref_scm (j, T0, obj);
  1729. emit_sp_ref_sz (j, T1, val);
  1730. jit_stxi (idx * sizeof (SCM), T0, T1);
  1731. }
  1732. static void
  1733. compile_pointer_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1734. {
  1735. emit_sp_ref_scm (j, T0, obj);
  1736. emit_ldxi (j, T0, T0, idx * sizeof (SCM));
  1737. emit_sp_set_scm (j, dst, T0);
  1738. }
  1739. static void
  1740. compile_pointer_set_immediate (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  1741. {
  1742. emit_sp_ref_scm (j, T0, obj);
  1743. emit_sp_ref_scm (j, T1, val);
  1744. jit_stxi (idx * sizeof (SCM), T0, T1);
  1745. }
  1746. static void
  1747. compile_tail_pointer_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1748. {
  1749. emit_sp_ref_scm (j, T0, obj);
  1750. emit_addi (j, T0, T0, idx * sizeof (SCM));
  1751. emit_sp_set_scm (j, dst, T0);
  1752. }
  1753. static void
  1754. compile_mov (scm_jit_state *j, uint16_t dst, uint16_t src)
  1755. {
  1756. emit_mov (j, dst, src, T0);
  1757. }
  1758. static void
  1759. compile_long_mov (scm_jit_state *j, uint32_t dst, uint32_t src)
  1760. {
  1761. emit_mov (j, dst, src, T0);
  1762. }
  1763. static void
  1764. compile_long_fmov (scm_jit_state *j, uint32_t dst, uint32_t src)
  1765. {
  1766. jit_gpr_t t = T0;
  1767. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1768. emit_fp_ref_scm (j, t, src);
  1769. emit_fp_set_scm (j, dst, t);
  1770. }
  1771. static void
  1772. compile_call_scm_from_scm_scm (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  1773. {
  1774. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1775. jit_node_t *fast = NULL;
  1776. emit_sp_ref_scm (j, T0, a);
  1777. emit_sp_ref_scm (j, T1, b);
  1778. switch ((enum scm_vm_intrinsic) idx)
  1779. {
  1780. case SCM_VM_INTRINSIC_ADD:
  1781. {
  1782. jit_node_t *a_not_inum = jit_bmci (T0, scm_tc2_int);
  1783. jit_node_t *b_not_inum = jit_bmci (T1, scm_tc2_int);
  1784. jit_subi (T0, T0, scm_tc2_int);
  1785. fast = jit_bxaddr (T0, T1);
  1786. /* Restore previous value before slow path. */
  1787. jit_subr (T0, T0, T1);
  1788. jit_addi (T0, T0, scm_tc2_int);
  1789. jit_patch (a_not_inum);
  1790. jit_patch (b_not_inum);
  1791. break;
  1792. }
  1793. case SCM_VM_INTRINSIC_SUB:
  1794. {
  1795. jit_node_t *a_not_inum = jit_bmci (T0, scm_tc2_int);
  1796. jit_node_t *b_not_inum = jit_bmci (T1, scm_tc2_int);
  1797. jit_subi (T1, T1, scm_tc2_int);
  1798. fast = jit_bxsubr (T0, T1);
  1799. /* Restore previous values before slow path. */
  1800. jit_addr (T0, T0, T1);
  1801. jit_addi (T1, T1, scm_tc2_int);
  1802. jit_patch (a_not_inum);
  1803. jit_patch (b_not_inum);
  1804. break;
  1805. }
  1806. default:
  1807. break;
  1808. }
  1809. emit_store_current_ip (j, T2);
  1810. emit_call_r_r (j, intrinsic, T0, T1);
  1811. emit_retval (j, T0);
  1812. emit_reload_sp (j);
  1813. if (fast)
  1814. jit_patch (fast);
  1815. emit_sp_set_scm (j, dst, T0);
  1816. }
  1817. static void
  1818. compile_call_scm_from_scm_uimm (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  1819. {
  1820. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1821. jit_node_t *fast = NULL;
  1822. emit_sp_ref_scm (j, T0, a);
  1823. switch ((enum scm_vm_intrinsic) idx)
  1824. {
  1825. case SCM_VM_INTRINSIC_ADD_IMMEDIATE:
  1826. {
  1827. scm_t_bits addend = b << 2;
  1828. jit_node_t *not_inum = jit_bmci (T0, 2);
  1829. fast = jit_bxaddi (T0, addend);
  1830. /* Restore previous value before slow path. */
  1831. jit_subi (T0, T0, addend);
  1832. jit_patch (not_inum);
  1833. break;
  1834. }
  1835. case SCM_VM_INTRINSIC_SUB_IMMEDIATE:
  1836. {
  1837. scm_t_bits subtrahend = b << 2;
  1838. jit_node_t *not_inum = jit_bmci (T0, 2);
  1839. fast = jit_bxsubi (T0, subtrahend);
  1840. /* Restore previous value before slow path. */
  1841. jit_addi (T0, T0, subtrahend);
  1842. jit_patch (not_inum);
  1843. break;
  1844. }
  1845. default:
  1846. break;
  1847. }
  1848. emit_store_current_ip (j, T1);
  1849. jit_prepare ();
  1850. jit_pushargr (T0);
  1851. jit_pushargi (b);
  1852. jit_finishi (intrinsic);
  1853. clear_scratch_register_state (j);
  1854. emit_retval (j, T0);
  1855. emit_reload_sp (j);
  1856. if (fast)
  1857. jit_patch (fast);
  1858. emit_sp_set_scm (j, dst, T0);
  1859. }
  1860. static void
  1861. compile_call_scm_sz_u32 (scm_jit_state *j, uint8_t a, uint8_t b, uint8_t c, uint32_t idx)
  1862. {
  1863. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1864. emit_store_current_ip (j, T0);
  1865. emit_sp_ref_scm (j, T0, a);
  1866. emit_sp_ref_sz (j, T1, b);
  1867. emit_sp_ref_sz (j, T2, c);
  1868. jit_prepare ();
  1869. jit_pushargr (T0);
  1870. jit_pushargr (T1);
  1871. jit_pushargr (T2);
  1872. jit_finishi (intrinsic);
  1873. clear_scratch_register_state (j);
  1874. emit_reload_sp (j);
  1875. }
  1876. static void
  1877. compile_call_scm_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  1878. {
  1879. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1880. emit_store_current_ip (j, T0);
  1881. emit_sp_ref_scm (j, T0, a);
  1882. jit_prepare ();
  1883. jit_pushargr (T0);
  1884. jit_finishi (intrinsic);
  1885. clear_scratch_register_state (j);
  1886. emit_retval (j, T0);
  1887. emit_reload_sp (j);
  1888. emit_sp_set_scm (j, dst, T0);
  1889. }
  1890. static void
  1891. compile_call_f64_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  1892. {
  1893. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1894. emit_store_current_ip (j, T0);
  1895. emit_sp_ref_scm (j, T0, a);
  1896. jit_prepare ();
  1897. jit_pushargr (T0);
  1898. jit_finishi (intrinsic);
  1899. clear_scratch_register_state (j);
  1900. emit_retval_d (j, JIT_F0);
  1901. emit_reload_sp (j);
  1902. emit_sp_set_f64 (j, dst, JIT_F0);
  1903. }
  1904. static void
  1905. compile_call_u64_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  1906. {
  1907. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1908. emit_store_current_ip (j, T0);
  1909. emit_sp_ref_scm (j, T0, a);
  1910. #if INDIRECT_INT64_INTRINSICS
  1911. jit_prepare ();
  1912. jit_addi (T1, SP, dst * sizeof (union scm_vm_stack_element));
  1913. jit_pushargr (T1);
  1914. jit_pushargr (T0);
  1915. jit_finishi (intrinsic);
  1916. clear_scratch_register_state (j);
  1917. emit_reload_sp (j);
  1918. #else
  1919. jit_prepare ();
  1920. jit_pushargr (T0);
  1921. jit_finishi (intrinsic);
  1922. clear_scratch_register_state (j);
  1923. emit_retval (j, T0);
  1924. emit_reload_sp (j);
  1925. emit_sp_set_u64 (j, dst, T0);
  1926. #endif
  1927. }
  1928. static void
  1929. compile_make_short_immediate (scm_jit_state *j, uint8_t dst, SCM a)
  1930. {
  1931. emit_movi (j, T0, SCM_UNPACK (a));
  1932. emit_sp_set_scm (j, dst, T0);
  1933. }
  1934. static void
  1935. compile_make_long_immediate (scm_jit_state *j, uint32_t dst, SCM a)
  1936. {
  1937. emit_movi (j, T0, SCM_UNPACK (a));
  1938. emit_sp_set_scm (j, dst, T0);
  1939. }
  1940. static void
  1941. compile_make_long_long_immediate (scm_jit_state *j, uint32_t dst, SCM a)
  1942. {
  1943. emit_movi (j, T0, SCM_UNPACK (a));
  1944. emit_sp_set_scm (j, dst, T0);
  1945. }
  1946. static void
  1947. compile_make_non_immediate (scm_jit_state *j, uint32_t dst, const void *data)
  1948. {
  1949. emit_movi (j, T0, (uintptr_t)data);
  1950. emit_sp_set_scm (j, dst, T0);
  1951. }
  1952. static void
  1953. compile_static_ref (scm_jit_state *j, uint32_t dst, void *loc)
  1954. {
  1955. emit_ldi (j, T0, loc);
  1956. emit_sp_set_scm (j, dst, T0);
  1957. }
  1958. static void
  1959. compile_static_set (scm_jit_state *j, uint32_t obj, void *loc)
  1960. {
  1961. emit_sp_ref_scm (j, T0, obj);
  1962. jit_sti (loc, T0);
  1963. }
  1964. static void
  1965. compile_static_patch (scm_jit_state *j, void *dst, const void *src)
  1966. {
  1967. emit_movi (j, T0, (uintptr_t) src);
  1968. jit_sti (dst, T0);
  1969. }
  1970. static void
  1971. compile_prompt (scm_jit_state *j, uint32_t tag, uint8_t escape_only_p,
  1972. uint32_t proc_slot, const uint32_t *vcode)
  1973. {
  1974. jit_node_t *mra;
  1975. emit_store_current_ip (j, T0);
  1976. jit_prepare ();
  1977. jit_pushargr (THREAD);
  1978. jit_pushargi (escape_only_p);
  1979. emit_sp_ref_scm (j, T0, tag);
  1980. jit_pushargr (T0);
  1981. emit_reload_fp (j);
  1982. jit_subi (FP, FP, proc_slot * sizeof (union scm_vm_stack_element));
  1983. jit_pushargr (FP);
  1984. jit_pushargi ((uintptr_t) vcode);
  1985. mra = emit_movi (j, T2, 0);
  1986. jit_pushargr (T2);
  1987. jit_finishi (scm_vm_intrinsics.push_prompt);
  1988. clear_scratch_register_state (j);
  1989. emit_reload_sp (j);
  1990. emit_reload_fp (j);
  1991. add_inter_instruction_patch (j, mra, vcode);
  1992. }
  1993. static void
  1994. compile_load_label (scm_jit_state *j, uint32_t dst, const uint32_t *vcode)
  1995. {
  1996. emit_movi (j, T0, (uintptr_t) vcode);
  1997. #if SIZEOF_UINTPTR_T >= 8
  1998. emit_sp_set_u64 (j, dst, T0);
  1999. #else
  2000. emit_movi (j, T1, 0);
  2001. emit_sp_set_u64 (j, dst, T0, T1);
  2002. #endif
  2003. }
  2004. static void
  2005. compile_call_s64_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2006. {
  2007. compile_call_u64_from_scm (j, dst, a, idx);
  2008. }
  2009. static void
  2010. compile_call_scm_from_u64 (scm_jit_state *j, uint16_t dst, uint16_t src, uint32_t idx)
  2011. {
  2012. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2013. emit_store_current_ip (j, T0);
  2014. jit_prepare ();
  2015. #if INDIRECT_INT64_INTRINSICS
  2016. jit_addi (T0, SP, src * sizeof (union scm_vm_stack_element));
  2017. #else
  2018. emit_sp_ref_u64 (j, T0, src);
  2019. #endif
  2020. jit_pushargr (T0);
  2021. jit_finishi (intrinsic);
  2022. clear_scratch_register_state (j);
  2023. emit_retval (j, T0);
  2024. emit_reload_sp (j);
  2025. emit_sp_set_scm (j, dst, T0);
  2026. }
  2027. static void
  2028. compile_call_scm_from_s64 (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t b)
  2029. {
  2030. compile_call_scm_from_u64 (j, dst, a, b);
  2031. }
  2032. static void
  2033. compile_tag_char (scm_jit_state *j, uint16_t dst, uint16_t src)
  2034. {
  2035. #if SIZEOF_UINTPTR_T >= 8
  2036. emit_sp_ref_u64 (j, T0, src);
  2037. #else
  2038. emit_sp_ref_u64_lower_half (j, T0, src);
  2039. #endif
  2040. emit_lshi (j, T0, T0, 8);
  2041. emit_addi (j, T0, T0, scm_tc8_char);
  2042. emit_sp_set_scm (j, dst, T0);
  2043. }
  2044. static void
  2045. compile_untag_char (scm_jit_state *j, uint16_t dst, uint16_t src)
  2046. {
  2047. emit_sp_ref_scm (j, T0, src);
  2048. emit_rshi (j, T0, T0, 8);
  2049. #if SIZEOF_UINTPTR_T >= 8
  2050. emit_sp_set_u64 (j, dst, T0);
  2051. #else
  2052. emit_movi (j, T1, 0);
  2053. emit_sp_set_u64 (j, dst, T0, T1);
  2054. #endif
  2055. }
  2056. static void
  2057. compile_atomic_ref_scm_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t offset)
  2058. {
  2059. emit_sp_ref_scm (j, T0, obj);
  2060. #if defined(__i386__) || defined(__x86_64__)
  2061. /* Disassembly of atomic_ref_scm is just a mov. */
  2062. emit_ldxi (j, T0, T0, offset * sizeof (SCM));
  2063. #else
  2064. emit_addi (j, T0, T0, offset * sizeof (SCM));
  2065. emit_movr (j, T1_PRESERVED, SP);
  2066. emit_call_r (j, scm_vm_intrinsics.atomic_ref_scm, T0);
  2067. emit_retval (j, T0);
  2068. emit_movr (j, SP, T1_PRESERVED);
  2069. set_register_state (j, SP_IN_REGISTER);
  2070. #endif
  2071. emit_sp_set_scm (j, dst, T0);
  2072. }
  2073. static void
  2074. compile_atomic_set_scm_immediate (scm_jit_state *j, uint8_t obj, uint8_t offset, uint8_t val)
  2075. {
  2076. emit_sp_ref_scm (j, T1, obj);
  2077. emit_sp_ref_scm (j, T2, val);
  2078. emit_addi (j, T1, T1, offset * sizeof (SCM));
  2079. emit_movr (j, T0_PRESERVED, SP);
  2080. emit_call_r_r (j, scm_vm_intrinsics.atomic_set_scm, T1, T2);
  2081. emit_movr (j, SP, T0_PRESERVED);
  2082. set_register_state (j, SP_IN_REGISTER);
  2083. }
  2084. static void
  2085. compile_atomic_scm_swap_immediate (scm_jit_state *j, uint32_t dst, uint32_t obj, uint8_t offset, uint32_t val)
  2086. {
  2087. emit_sp_ref_scm (j, T1, obj);
  2088. emit_sp_ref_scm (j, T2, val);
  2089. emit_addi (j, T1, T1, offset * sizeof (SCM));
  2090. emit_movr (j, T0_PRESERVED, SP);
  2091. emit_call_r_r (j, scm_vm_intrinsics.atomic_swap_scm, T1, T2);
  2092. emit_retval (j, T1);
  2093. emit_movr (j, SP, T0_PRESERVED);
  2094. set_register_state (j, SP_IN_REGISTER);
  2095. emit_sp_set_scm (j, dst, T1);
  2096. }
  2097. static void
  2098. compile_atomic_scm_compare_and_swap_immediate (scm_jit_state *j, uint32_t dst,
  2099. uint32_t obj, uint8_t offset,
  2100. uint32_t expected, uint32_t desired)
  2101. {
  2102. emit_sp_ref_scm (j, T0, obj);
  2103. emit_sp_ref_scm (j, T1, expected);
  2104. emit_sp_ref_scm (j, T2, desired);
  2105. emit_addi (j, T0, T0, offset * sizeof (SCM));
  2106. emit_call_r_r_r (j, scm_vm_intrinsics.atomic_compare_and_swap_scm, T0, T1, T2);
  2107. emit_retval (j, T0);
  2108. emit_reload_sp (j);
  2109. emit_sp_set_scm (j, dst, T0);
  2110. }
  2111. static void
  2112. compile_call_thread_scm_scm (scm_jit_state *j, uint16_t a, uint16_t b, uint32_t idx)
  2113. {
  2114. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2115. emit_store_current_ip (j, T0);
  2116. emit_sp_ref_scm (j, T0, a);
  2117. emit_sp_ref_scm (j, T1, b);
  2118. emit_call_r_r_r (j, intrinsic, THREAD, T0, T1);
  2119. emit_reload_sp (j);
  2120. }
  2121. static void
  2122. compile_call_thread (scm_jit_state *j, uint32_t idx)
  2123. {
  2124. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2125. emit_store_current_ip (j, T0);
  2126. emit_call_r (j, intrinsic, THREAD);
  2127. emit_reload_sp (j);
  2128. }
  2129. static void
  2130. compile_call_scm_from_thread_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2131. {
  2132. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2133. emit_store_current_ip (j, T0);
  2134. emit_sp_ref_scm (j, T0, a);
  2135. emit_call_r_r (j, intrinsic, THREAD, T0);
  2136. emit_retval (j, T0);
  2137. emit_reload_sp (j);
  2138. emit_sp_set_scm (j, dst, T0);
  2139. }
  2140. static void
  2141. compile_call_thread_scm (scm_jit_state *j, uint32_t a, uint32_t idx)
  2142. {
  2143. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2144. emit_store_current_ip (j, T0);
  2145. emit_sp_ref_scm (j, T0, a);
  2146. emit_call_r_r (j, intrinsic, THREAD, T0);
  2147. emit_reload_sp (j);
  2148. }
  2149. static void
  2150. compile_call_scm_from_scm_u64 (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  2151. {
  2152. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2153. emit_store_current_ip (j, T0);
  2154. emit_sp_ref_scm (j, T0, a);
  2155. jit_prepare ();
  2156. jit_pushargr (T0);
  2157. #if INDIRECT_INT64_INTRINSICS
  2158. emit_addi (j, T1, SP, b * sizeof (union scm_vm_stack_element));
  2159. #else
  2160. emit_sp_ref_u64 (j, T1, b);
  2161. #endif
  2162. jit_pushargr (T1);
  2163. jit_finishi (intrinsic);
  2164. clear_scratch_register_state (j);
  2165. emit_retval (j, T0);
  2166. emit_reload_sp (j);
  2167. emit_sp_set_scm (j, dst, T0);
  2168. }
  2169. static void
  2170. compile_call_scm_from_thread (scm_jit_state *j, uint32_t dst, uint32_t idx)
  2171. {
  2172. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2173. emit_store_current_ip (j, T0);
  2174. emit_call_r (j, intrinsic, THREAD);
  2175. emit_retval (j, T0);
  2176. emit_reload_sp (j);
  2177. emit_sp_set_scm (j, dst, T0);
  2178. }
  2179. static void
  2180. compile_fadd (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2181. {
  2182. emit_sp_ref_f64 (j, JIT_F0, a);
  2183. emit_sp_ref_f64 (j, JIT_F1, b);
  2184. emit_addr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2185. emit_sp_set_f64 (j, dst, JIT_F0);
  2186. }
  2187. static void
  2188. compile_fsub (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2189. {
  2190. emit_sp_ref_f64 (j, JIT_F0, a);
  2191. emit_sp_ref_f64 (j, JIT_F1, b);
  2192. emit_subr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2193. emit_sp_set_f64 (j, dst, JIT_F0);
  2194. }
  2195. static void
  2196. compile_fmul (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2197. {
  2198. emit_sp_ref_f64 (j, JIT_F0, a);
  2199. emit_sp_ref_f64 (j, JIT_F1, b);
  2200. emit_mulr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2201. emit_sp_set_f64 (j, dst, JIT_F0);
  2202. }
  2203. static void
  2204. compile_fdiv (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2205. {
  2206. emit_sp_ref_f64 (j, JIT_F0, a);
  2207. emit_sp_ref_f64 (j, JIT_F1, b);
  2208. emit_divr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2209. emit_sp_set_f64 (j, dst, JIT_F0);
  2210. }
  2211. static void
  2212. compile_uadd (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2213. {
  2214. #if SIZEOF_UINTPTR_T >= 8
  2215. emit_sp_ref_u64 (j, T0, a);
  2216. emit_sp_ref_u64 (j, T1, b);
  2217. emit_addr (j, T0, T0, T1);
  2218. emit_sp_set_u64 (j, dst, T0);
  2219. #else
  2220. emit_sp_ref_u64 (j, T0, T1, a);
  2221. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2222. emit_addcr (j, T0, T0, T2);
  2223. emit_addxr (j, T1, T1, T3_OR_FP);
  2224. emit_sp_set_u64 (j, dst, T0, T1);
  2225. #endif
  2226. }
  2227. static void
  2228. compile_usub (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2229. {
  2230. #if SIZEOF_UINTPTR_T >= 8
  2231. emit_sp_ref_u64 (j, T0, a);
  2232. emit_sp_ref_u64 (j, T1, b);
  2233. emit_subr (j, T0, T0, T1);
  2234. emit_sp_set_u64 (j, dst, T0);
  2235. #else
  2236. emit_sp_ref_u64 (j, T0, T1, a);
  2237. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2238. emit_subcr (j, T0, T0, T2);
  2239. emit_subxr (j, T1, T1, T3_OR_FP);
  2240. emit_sp_set_u64 (j, dst, T0, T1);
  2241. #endif
  2242. }
  2243. static void
  2244. compile_umul (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2245. {
  2246. #if SIZEOF_UINTPTR_T >= 8
  2247. emit_sp_ref_u64 (j, T0, a);
  2248. emit_sp_ref_u64 (j, T1, b);
  2249. emit_mulr (j, T0, T0, T1);
  2250. emit_sp_set_u64 (j, dst, T0);
  2251. #else
  2252. /* FIXME: This is untested! */
  2253. emit_sp_ref_u64 (j, T0, T1, a);
  2254. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2255. emit_mulr (j, T1, T1, T2); /* High A times low B */
  2256. emit_mulr (j, T3_OR_FP, T3_OR_FP, T0); /* High B times low A */
  2257. emit_addr (j, T1, T1, T3_OR_FP); /* Add high results, throw away overflow */
  2258. emit_qmulr_u (j, T0, T2, T0, T2); /* Low A times low B */
  2259. emit_addr (j, T1, T1, T2); /* Add high result of low product */
  2260. clear_register_state (j, SP_CACHE_FPR | SP_CACHE_GPR);
  2261. emit_sp_set_u64 (j, dst, T0, T1);
  2262. #endif
  2263. }
  2264. static void
  2265. compile_uadd_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2266. {
  2267. #if SIZEOF_UINTPTR_T >= 8
  2268. emit_sp_ref_u64 (j, T0, a);
  2269. emit_addi (j, T0, T0, b);
  2270. emit_sp_set_u64 (j, dst, T0);
  2271. #else
  2272. emit_sp_ref_u64 (j, T0, T1, a);
  2273. emit_addci (j, T0, T0, b);
  2274. emit_addxi (j, T1, T1, 0);
  2275. emit_sp_set_u64 (j, dst, T0, T1);
  2276. #endif
  2277. }
  2278. static void
  2279. compile_usub_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2280. {
  2281. #if SIZEOF_UINTPTR_T >= 8
  2282. emit_sp_ref_u64 (j, T0, a);
  2283. emit_subi (j, T0, T0, b);
  2284. emit_sp_set_u64 (j, dst, T0);
  2285. #else
  2286. emit_sp_ref_u64 (j, T0, T1, a);
  2287. emit_subci (j, T0, T0, b);
  2288. emit_subxi (j, T1, T1, 0);
  2289. emit_sp_set_u64 (j, dst, T0, T1);
  2290. #endif
  2291. }
  2292. static void
  2293. compile_umul_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2294. {
  2295. #if SIZEOF_UINTPTR_T >= 8
  2296. emit_sp_ref_u64 (j, T0, a);
  2297. emit_muli (j, T0, T0, b);
  2298. emit_sp_set_u64 (j, dst, T0);
  2299. #else
  2300. /* FIXME: This is untested! */
  2301. emit_sp_ref_u64 (j, T0, T1, a);
  2302. emit_muli (j, T1, T1, b); /* High A times low B */
  2303. /* High B times low A is 0. */
  2304. emit_movi (j, j, T2, b);
  2305. emit_qmulr_u (j, T0, T2, T0, T2); /* Low A times low B */
  2306. emit_addr (j, T1, T1, T2); /* Add high result of low product */
  2307. emit_sp_set_u64 (j, dst, T0, T1);
  2308. #endif
  2309. }
  2310. static void
  2311. compile_load_f64 (scm_jit_state *j, uint32_t dst, double a)
  2312. {
  2313. jit_movi_d (JIT_F0, a);
  2314. record_fpr_clobber (j, JIT_F0);
  2315. emit_sp_set_f64 (j, dst, JIT_F0);
  2316. }
  2317. static void
  2318. compile_load_u64 (scm_jit_state *j, uint32_t dst, uint64_t a)
  2319. {
  2320. #if SIZEOF_UINTPTR_T >= 8
  2321. emit_movi (j, T0, a);
  2322. emit_sp_set_u64 (j, dst, T0);
  2323. #else
  2324. emit_movi (j, T0, a & 0xffffffff);
  2325. emit_movi (j, T1, a >> 32);
  2326. emit_sp_set_u64 (j, dst, T0, T1);
  2327. #endif
  2328. }
  2329. static void
  2330. compile_load_s64 (scm_jit_state *j, uint32_t dst, int64_t a)
  2331. {
  2332. compile_load_u64 (j, dst, a);
  2333. }
  2334. static void
  2335. compile_current_thread (scm_jit_state *j, uint32_t dst)
  2336. {
  2337. emit_ldxi (j, T0, THREAD, thread_offset_handle);
  2338. emit_sp_set_scm (j, dst, T0);
  2339. }
  2340. static void
  2341. compile_ulogand (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2342. {
  2343. #if SIZEOF_UINTPTR_T >= 8
  2344. emit_sp_ref_u64 (j, T0, a);
  2345. emit_sp_ref_u64 (j, T1, b);
  2346. emit_andr (j, T0, T0, T1);
  2347. emit_sp_set_u64 (j, dst, T0);
  2348. #else
  2349. emit_sp_ref_u64 (j, T0, T1, a);
  2350. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2351. emit_andr (j, T0, T0, T2);
  2352. emit_andr (j, T1, T1, T3_OR_FP);
  2353. emit_sp_set_u64 (j, dst, T0, T1);
  2354. #endif
  2355. }
  2356. static void
  2357. compile_ulogior (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2358. {
  2359. #if SIZEOF_UINTPTR_T >= 8
  2360. emit_sp_ref_u64 (j, T0, a);
  2361. emit_sp_ref_u64 (j, T1, b);
  2362. emit_orr (j, T0, T0, T1);
  2363. emit_sp_set_u64 (j, dst, T0);
  2364. #else
  2365. emit_sp_ref_u64 (j, T0, T1, a);
  2366. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2367. emit_orr (j, T0, T0, T2);
  2368. emit_orr (j, T1, T1, T3_OR_FP);
  2369. emit_sp_set_u64 (j, dst, T0, T1);
  2370. #endif
  2371. }
  2372. static void
  2373. compile_ulogsub (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2374. {
  2375. #if SIZEOF_UINTPTR_T >= 8
  2376. emit_sp_ref_u64 (j, T0, a);
  2377. emit_sp_ref_u64 (j, T1, b);
  2378. emit_comr (j, T1, T1);
  2379. emit_andr (j, T0, T0, T1);
  2380. emit_sp_set_u64 (j, dst, T0);
  2381. #else
  2382. emit_sp_ref_u64 (j, T0, T1, a);
  2383. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2384. emit_comr (j, T2, T2);
  2385. emit_comr (j, T3_OR_FP, T3_OR_FP);
  2386. emit_andr (j, T0, T0, T2);
  2387. emit_andr (j, T1, T1, T3_OR_FP);
  2388. emit_sp_set_u64 (j, dst, T0, T1);
  2389. #endif
  2390. }
  2391. static void
  2392. compile_ursh (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2393. {
  2394. #if SIZEOF_UINTPTR_T >= 8
  2395. emit_sp_ref_u64 (j, T0, a);
  2396. emit_sp_ref_u64 (j, T1, b);
  2397. emit_andi (j, T1, T1, 63);
  2398. emit_rshr_u (j, T0, T0, T1);
  2399. emit_sp_set_u64 (j, dst, T0);
  2400. #else
  2401. /* FIXME: Not tested. */
  2402. jit_node_t *zero, *both, *done;
  2403. emit_sp_ref_u64 (j, T0, T1, a);
  2404. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2405. emit_andi (j, T2, T2, 63);
  2406. zero = jit_beqi (T2, 0);
  2407. both = jit_blti (T2, 32);
  2408. /* 32 <= s < 64: hi = 0, lo = hi >> (s-32) */
  2409. emit_subi (j, T2, 32);
  2410. emit_rshr_u (j, T0, T1, T2);
  2411. emit_movi (j, T1, 0);
  2412. done = jit_jmpi ();
  2413. jit_patch (both);
  2414. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  2415. jit_negr (T3_OR_FP, T2);
  2416. emit_addi (j, T3_OR_FP, T3_OR_FP, 32);
  2417. emit_lshr (j, T3_OR_FP, T1, T3_OR_FP);
  2418. emit_rshr_u (j, T1, T1, T2);
  2419. emit_rshr_u (j, T0, T0, T2);
  2420. emit_addr (j, T0, T0, T3_OR_FP);
  2421. jit_patch (done);
  2422. jit_patch (zero);
  2423. emit_sp_set_u64 (j, dst, T0, T1);
  2424. #endif
  2425. }
  2426. static void
  2427. compile_ulsh (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2428. {
  2429. #if SIZEOF_UINTPTR_T >= 8
  2430. emit_sp_ref_u64 (j, T0, a);
  2431. emit_sp_ref_u64 (j, T1, b);
  2432. emit_andi (j, T1, T1, 63);
  2433. emit_lshr (j, T0, T0, T1);
  2434. emit_sp_set_u64 (j, dst, T0);
  2435. #else
  2436. /* FIXME: Not tested. */
  2437. jit_node_t *zero, *both, *done;
  2438. emit_sp_ref_u64 (j, T0, T1, a);
  2439. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2440. emit_andi (j, T2, T2, 63);
  2441. zero = jit_beqi (T2, 0);
  2442. both = jit_blti (T2, 32);
  2443. /* 32 <= s < 64: hi = lo << (s-32), lo = 0 */
  2444. emit_subi (j, T2, 32);
  2445. emit_lshr (j, T1, T0, T2);
  2446. emit_movi (j, T0, 0);
  2447. done = jit_jmpi ();
  2448. jit_patch (both);
  2449. /* 0 < s < 32: hi = hi << s + lo >> (32-s), lo = lo << s */
  2450. emit_negr (j, T3_OR_FP, T2);
  2451. emit_addi (j, T3_OR_FP, T3_OR_FP, 32);
  2452. emit_rshr_u (j, T3_OR_FP, T0, T3_OR_FP);
  2453. emit_lshr (j, T1, T1, T2);
  2454. emit_lshr (j, T0, T0, T2);
  2455. emit_addr (j, T1, T1, T3_OR_FP);
  2456. jit_patch (done);
  2457. jit_patch (zero);
  2458. emit_sp_set_u64 (j, dst, T0, T1);
  2459. #endif
  2460. }
  2461. static void
  2462. compile_ursh_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2463. {
  2464. b &= 63;
  2465. #if SIZEOF_UINTPTR_T >= 8
  2466. emit_sp_ref_u64 (j, T0, a);
  2467. emit_rshi_u (j, T0, T0, b);
  2468. emit_sp_set_u64 (j, dst, T0);
  2469. #else
  2470. /* FIXME: Not tested. */
  2471. emit_sp_ref_u64 (j, T0, T1, a);
  2472. if (b == 0)
  2473. {
  2474. /* Nothing to do. */
  2475. }
  2476. else if (b >= 32)
  2477. {
  2478. /* hi = 0, lo = hi >> (s-32) */
  2479. emit_rshi_u (j, T0, T1, b - 32);
  2480. emit_movi (j, T1, 0);
  2481. }
  2482. else
  2483. {
  2484. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  2485. emit_lshi (j, T2, T1, 32 - b);
  2486. emit_rshi_u (j, T1, T1, b);
  2487. emit_rshi_u (j, T0, T0, b);
  2488. emit_addr (j, T0, T0, T2);
  2489. }
  2490. emit_sp_set_u64 (j, dst, T0, T1);
  2491. #endif
  2492. }
  2493. static void
  2494. compile_ulsh_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2495. {
  2496. b &= 63;
  2497. #if SIZEOF_UINTPTR_T >= 8
  2498. emit_sp_ref_u64 (j, T0, a);
  2499. emit_lshi (j, T0, T0, b);
  2500. emit_sp_set_u64 (j, dst, T0);
  2501. #else
  2502. /* FIXME: Not tested. */
  2503. emit_sp_ref_u64 (j, T0, T1, a);
  2504. if (b == 0)
  2505. {
  2506. /* Nothing to do. */
  2507. }
  2508. else if (b >= 32)
  2509. {
  2510. /* hi = lo << (s-32), lo = 0 */
  2511. emit_lshr (j, T1, T0, b - 32);
  2512. emit_movi (j, T0, 0);
  2513. }
  2514. else
  2515. {
  2516. /* hi = hi << s + lo >> (32-s), lo = lo << s */
  2517. emit_rshi_u (j, T2, T0, 32 - b);
  2518. emit_lshi (j, T1, T1, b);
  2519. emit_lshi (j, T0, T0, b);
  2520. emit_addr (j, T1, T1, T2);
  2521. }
  2522. emit_sp_set_u64 (j, dst, T0, T1);
  2523. #endif
  2524. }
  2525. static void
  2526. compile_ulogxor (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2527. {
  2528. #if SIZEOF_UINTPTR_T >= 8
  2529. emit_sp_ref_u64 (j, T0, a);
  2530. emit_sp_ref_u64 (j, T1, b);
  2531. emit_xorr (j, T0, T0, T1);
  2532. emit_sp_set_u64 (j, dst, T0);
  2533. #else
  2534. emit_sp_ref_u64 (j, T0, T1, a);
  2535. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2536. emit_xorr (j, T0, T0, T2);
  2537. emit_xorr (j, T1, T1, T3_OR_FP);
  2538. emit_sp_set_u64 (j, dst, T0, T1);
  2539. #endif
  2540. }
  2541. static void
  2542. compile_handle_interrupts (scm_jit_state *j)
  2543. {
  2544. jit_node_t *again, *mra, *none_pending, *blocked;
  2545. uint32_t saved_state = save_reloadable_register_state (j);
  2546. /* This instruction invalidates SP_CACHE_GPR / SP_CACHE_FPR. */
  2547. again = jit_label ();
  2548. #if defined(__i386__) || defined(__x86_64__)
  2549. /* Disassembly of atomic_ref_scm is just a mov. */
  2550. jit_ldxi (T0, THREAD, thread_offset_pending_asyncs);
  2551. #else
  2552. jit_addi (T0, THREAD, thread_offset_pending_asyncs);
  2553. emit_call_r (j, scm_vm_intrinsics.atomic_ref_scm, T0);
  2554. emit_retval (j, T0);
  2555. restore_reloadable_register_state (j, saved_state);
  2556. #endif
  2557. none_pending = jit_beqi (T0, SCM_UNPACK (SCM_EOL));
  2558. jit_ldxi_i (T0, THREAD, thread_offset_block_asyncs);
  2559. blocked = jit_bnei (T0, 0);
  2560. emit_store_current_ip (j, T0);
  2561. mra = emit_movi (j, T0, 0);
  2562. jit_patch_at (mra, again);
  2563. jit_patch_abs (jit_jmpi (), handle_interrupts_trampoline);
  2564. jit_patch (none_pending);
  2565. jit_patch (blocked);
  2566. j->register_state = saved_state;
  2567. }
  2568. static void
  2569. compile_return_from_interrupt (scm_jit_state *j)
  2570. {
  2571. jit_gpr_t old_fp = T0, ra = T1;
  2572. jit_node_t *interp;
  2573. emit_pop_fp (j, old_fp);
  2574. emit_load_mra (j, ra, old_fp);
  2575. interp = jit_beqi (ra, 0);
  2576. jit_addi (SP, old_fp, frame_overhead_slots * sizeof (union scm_vm_stack_element));
  2577. set_register_state (j, SP_IN_REGISTER);
  2578. emit_store_sp (j);
  2579. jit_jmpr (ra);
  2580. jit_patch (interp);
  2581. emit_load_vra (j, ra, old_fp);
  2582. emit_store_ip (j, ra);
  2583. jit_addi (SP, old_fp, frame_overhead_slots * sizeof (union scm_vm_stack_element));
  2584. set_register_state (j, SP_IN_REGISTER);
  2585. emit_store_sp (j);
  2586. emit_exit (j);
  2587. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  2588. }
  2589. static enum scm_opcode
  2590. fuse_conditional_branch (scm_jit_state *j, uint32_t **target)
  2591. {
  2592. uint8_t next = j->next_ip[0] & 0xff;
  2593. switch (next)
  2594. {
  2595. case scm_op_jl:
  2596. case scm_op_je:
  2597. case scm_op_jnl:
  2598. case scm_op_jne:
  2599. case scm_op_jge:
  2600. case scm_op_jnge:
  2601. *target = j->next_ip + (((int32_t) j->next_ip[0]) >> 8);
  2602. j->next_ip += op_lengths[next];
  2603. return next;
  2604. default:
  2605. ASSERT (0);
  2606. }
  2607. }
  2608. static void
  2609. compile_u64_numerically_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  2610. {
  2611. uint32_t *target;
  2612. #if SIZEOF_UINTPTR_T >= 8
  2613. jit_node_t *k;
  2614. emit_sp_ref_u64 (j, T0, a);
  2615. emit_sp_ref_u64 (j, T1, b);
  2616. switch (fuse_conditional_branch (j, &target))
  2617. {
  2618. case scm_op_je:
  2619. k = jit_beqr (T0, T1);
  2620. break;
  2621. case scm_op_jne:
  2622. k = jit_bner (T0, T1);
  2623. break;
  2624. default:
  2625. UNREACHABLE ();
  2626. }
  2627. add_inter_instruction_patch (j, k, target);
  2628. #else
  2629. jit_node_t *k1, *k2;
  2630. emit_sp_ref_u64 (j, T0, T1, a);
  2631. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2632. switch (fuse_conditional_branch (j, &target))
  2633. {
  2634. case scm_op_je:
  2635. k1 = jit_bner (T0, T2);
  2636. k2 = jit_beqr (T1, T3_OR_FP);
  2637. jit_patch (k1);
  2638. add_inter_instruction_patch (j, k2, target);
  2639. break;
  2640. case scm_op_jne:
  2641. k1 = jit_bner (T0, T2);
  2642. k2 = jit_bner (T1, T3_OR_FP);
  2643. add_inter_instruction_patch (j, k1, target);
  2644. add_inter_instruction_patch (j, k2, target);
  2645. break;
  2646. default:
  2647. UNREACHABLE ();
  2648. }
  2649. #endif
  2650. }
  2651. static void
  2652. compile_u64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  2653. {
  2654. uint32_t *target;
  2655. #if SIZEOF_UINTPTR_T >= 8
  2656. jit_node_t *k;
  2657. emit_sp_ref_u64 (j, T0, a);
  2658. emit_sp_ref_u64 (j, T1, b);
  2659. switch (fuse_conditional_branch (j, &target))
  2660. {
  2661. case scm_op_jl:
  2662. k = jit_bltr_u (T0, T1);
  2663. break;
  2664. case scm_op_jnl:
  2665. k = jit_bger_u (T0, T1);
  2666. break;
  2667. default:
  2668. UNREACHABLE ();
  2669. }
  2670. add_inter_instruction_patch (j, k, target);
  2671. #else
  2672. jit_node_t *k1, *k2, *k3;
  2673. emit_sp_ref_u64 (j, T0, T1, a);
  2674. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2675. k1 = jit_bltr_u (T1, T3_OR_FP);
  2676. k2 = jit_bner (T1, T3_OR_FP);
  2677. switch (fuse_conditional_branch (j, &target))
  2678. {
  2679. case scm_op_jl:
  2680. k3 = jit_bltr_u (T0, T2);
  2681. jit_patch (k2);
  2682. add_inter_instruction_patch (j, k1, target);
  2683. add_inter_instruction_patch (j, k3, target);
  2684. break;
  2685. case scm_op_jnl:
  2686. k3 = jit_bger_u (T0, T2);
  2687. jit_patch (k1);
  2688. add_inter_instruction_patch (j, k2, target);
  2689. add_inter_instruction_patch (j, k3, target);
  2690. break;
  2691. default:
  2692. UNREACHABLE ();
  2693. }
  2694. #endif
  2695. }
  2696. static void
  2697. compile_s64_numerically_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  2698. {
  2699. compile_u64_numerically_equal (j, a, b);
  2700. }
  2701. static void
  2702. compile_s64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  2703. {
  2704. uint32_t *target;
  2705. #if SIZEOF_UINTPTR_T >= 8
  2706. jit_node_t *k;
  2707. emit_sp_ref_s64 (j, T0, a);
  2708. emit_sp_ref_s64 (j, T1, b);
  2709. switch (fuse_conditional_branch (j, &target))
  2710. {
  2711. case scm_op_jl:
  2712. k = jit_bltr (T0, T1);
  2713. break;
  2714. case scm_op_jnl:
  2715. k = jit_bger (T0, T1);
  2716. break;
  2717. default:
  2718. UNREACHABLE ();
  2719. }
  2720. add_inter_instruction_patch (j, k, target);
  2721. #else
  2722. jit_node_t *k1, *k2, *k3;
  2723. emit_sp_ref_s64 (j, T0, T1, a);
  2724. emit_sp_ref_s64 (j, T2, T3_OR_FP, b);
  2725. k1 = jit_bltr (T1, T3_OR_FP);
  2726. k2 = jit_bner (T1, T3_OR_FP);
  2727. switch (fuse_conditional_branch (j, &target))
  2728. {
  2729. case scm_op_jl:
  2730. k3 = jit_bltr (T0, T2);
  2731. jit_patch (k2);
  2732. add_inter_instruction_patch (j, k1, target);
  2733. add_inter_instruction_patch (j, k3, target);
  2734. break;
  2735. case scm_op_jnl:
  2736. k3 = jit_bger (T0, T2);
  2737. jit_patch (k1);
  2738. add_inter_instruction_patch (j, k2, target);
  2739. add_inter_instruction_patch (j, k3, target);
  2740. break;
  2741. default:
  2742. UNREACHABLE ();
  2743. }
  2744. #endif
  2745. }
  2746. static void
  2747. compile_f64_numerically_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  2748. {
  2749. jit_node_t *k;
  2750. uint32_t *target;
  2751. emit_sp_ref_f64 (j, JIT_F0, a);
  2752. emit_sp_ref_f64 (j, JIT_F1, b);
  2753. switch (fuse_conditional_branch (j, &target))
  2754. {
  2755. case scm_op_je:
  2756. k = jit_beqr_d (JIT_F0, JIT_F1);
  2757. break;
  2758. case scm_op_jne:
  2759. k = jit_bner_d (JIT_F0, JIT_F1);
  2760. break;
  2761. default:
  2762. UNREACHABLE ();
  2763. }
  2764. add_inter_instruction_patch (j, k, target);
  2765. }
  2766. static void
  2767. compile_f64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  2768. {
  2769. jit_node_t *k;
  2770. uint32_t *target;
  2771. emit_sp_ref_f64 (j, JIT_F0, a);
  2772. emit_sp_ref_f64 (j, JIT_F1, b);
  2773. switch (fuse_conditional_branch (j, &target))
  2774. {
  2775. case scm_op_jl:
  2776. k = jit_bltr_d (JIT_F0, JIT_F1);
  2777. break;
  2778. case scm_op_jnl:
  2779. k = jit_bunger_d (JIT_F0, JIT_F1);
  2780. break;
  2781. case scm_op_jge:
  2782. k = jit_bger_d (JIT_F0, JIT_F1);
  2783. break;
  2784. case scm_op_jnge:
  2785. k = jit_bunltr_d (JIT_F0, JIT_F1);
  2786. break;
  2787. default:
  2788. UNREACHABLE ();
  2789. }
  2790. add_inter_instruction_patch (j, k, target);
  2791. }
  2792. static void
  2793. compile_numerically_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  2794. {
  2795. jit_node_t *k;
  2796. uint32_t *target;
  2797. emit_store_current_ip (j, T0);
  2798. emit_sp_ref_scm (j, T0, a);
  2799. emit_sp_ref_scm (j, T1, b);
  2800. emit_call_r_r (j, scm_vm_intrinsics.numerically_equal_p, T0, T1);
  2801. emit_retval (j, T0);
  2802. emit_reload_sp (j);
  2803. switch (fuse_conditional_branch (j, &target))
  2804. {
  2805. case scm_op_je:
  2806. k = jit_bnei (T0, 0);
  2807. break;
  2808. case scm_op_jne:
  2809. k = jit_beqi (T0, 0);
  2810. break;
  2811. default:
  2812. UNREACHABLE ();
  2813. }
  2814. add_inter_instruction_patch (j, k, target);
  2815. }
  2816. static void
  2817. compile_less (scm_jit_state *j, uint16_t a, uint16_t b)
  2818. {
  2819. #if 0
  2820. jit_node_t *fast, *k2, *k3;
  2821. #endif
  2822. jit_node_t *k1;
  2823. uint32_t *target;
  2824. enum scm_opcode op = fuse_conditional_branch (j, &target);
  2825. emit_store_current_ip (j, T0);
  2826. emit_sp_ref_scm (j, T0, a);
  2827. emit_sp_ref_scm (j, T1, b);
  2828. #if 0
  2829. emit_andr (j, T2, T0, T1);
  2830. fast = jit_bmsi (T2, scm_tc2_int);
  2831. #endif
  2832. emit_call_r_r (j, scm_vm_intrinsics.less_p, T0, T1);
  2833. emit_retval (j, T0);
  2834. emit_reload_sp (j);
  2835. switch (op)
  2836. {
  2837. case scm_op_jl:
  2838. k1 = jit_beqi (T0, SCM_F_COMPARE_LESS_THAN);
  2839. break;
  2840. case scm_op_jnl:
  2841. k1 = jit_bnei (T0, SCM_F_COMPARE_LESS_THAN);
  2842. break;
  2843. case scm_op_jge:
  2844. k1 = jit_beqi (T0, SCM_F_COMPARE_NONE);
  2845. break;
  2846. case scm_op_jnge:
  2847. k1 = jit_bnei (T0, SCM_F_COMPARE_NONE);
  2848. break;
  2849. default:
  2850. UNREACHABLE ();
  2851. }
  2852. #if 0
  2853. k2 = jit_jmpi ();
  2854. jit_patch (fast);
  2855. switch (op)
  2856. {
  2857. case scm_op_jl:
  2858. case scm_op_jnge:
  2859. k3 = jit_bltr (T0, T1);
  2860. break;
  2861. case scm_op_jnl:
  2862. case scm_op_jge:
  2863. k3 = jit_bger (T0, T1);
  2864. break;
  2865. default:
  2866. UNREACHABLE ();
  2867. }
  2868. jit_patch (k2);
  2869. #endif
  2870. add_inter_instruction_patch (j, k1, target);
  2871. #if 0
  2872. add_inter_instruction_patch (j, k3, target);
  2873. #endif
  2874. }
  2875. static void
  2876. compile_check_arguments (scm_jit_state *j, uint32_t expected)
  2877. {
  2878. jit_node_t *k;
  2879. uint32_t *target;
  2880. jit_gpr_t t = T0;
  2881. emit_reload_fp (j);
  2882. switch (fuse_conditional_branch (j, &target))
  2883. {
  2884. case scm_op_jne:
  2885. k = emit_branch_if_frame_locals_count_not_eq (j, t, expected);
  2886. break;
  2887. case scm_op_jl:
  2888. k = emit_branch_if_frame_locals_count_less_than (j, t, expected);
  2889. break;
  2890. case scm_op_jge:
  2891. /* The arguments<=? instruction sets NONE to indicate
  2892. greater-than, whereas for <, NONE usually indicates
  2893. greater-than-or-equal, hence the name jge. So we need to fuse
  2894. to greater-than, not greater-than-or-equal. Perhaps we just
  2895. need to rename jge to br-if-none. */
  2896. k = emit_branch_if_frame_locals_count_greater_than (j, t, expected);
  2897. break;
  2898. default:
  2899. UNREACHABLE ();
  2900. }
  2901. add_inter_instruction_patch (j, k, target);
  2902. }
  2903. static void
  2904. compile_check_positional_arguments (scm_jit_state *j, uint32_t nreq, uint32_t expected)
  2905. {
  2906. uint32_t *target;
  2907. jit_node_t *lt, *gt, *head;
  2908. jit_gpr_t walk = T0, min = T1, obj = T2;
  2909. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER | SP_IN_REGISTER);
  2910. switch (fuse_conditional_branch (j, &target))
  2911. {
  2912. case scm_op_jge:
  2913. /* Like arguments<=?, this instruction sets NONE to indicate
  2914. greater-than, whereas for <, NONE usually indicates
  2915. greater-than-or-equal, hence the name jge. So we need to fuse
  2916. to greater-than, not greater-than-or-equal. Perhaps we just
  2917. need to rename jge to br-if-none. */
  2918. /* Break to target if npos > expected. */
  2919. break;
  2920. default:
  2921. UNREACHABLE ();
  2922. }
  2923. emit_subtract_stack_slots (j, min, FP, expected);
  2924. emit_subtract_stack_slots (j, walk, FP, nreq);
  2925. head = jit_label ();
  2926. /* npos > expected if walk < min. */
  2927. gt = jit_bltr (walk, min);
  2928. emit_subtract_stack_slots (j, walk, walk, 1);
  2929. lt = jit_bltr (walk, SP);
  2930. emit_ldr (j, obj, walk);
  2931. jit_patch_at (emit_branch_if_immediate (j, obj), head);
  2932. jit_patch_at (emit_branch_if_heap_object_not_tc7 (j, obj, obj, scm_tc7_keyword),
  2933. head);
  2934. jit_patch (lt);
  2935. add_inter_instruction_patch (j, gt, target);
  2936. }
  2937. static void
  2938. compile_immediate_tag_equals (scm_jit_state *j, uint32_t a, uint16_t mask,
  2939. uint16_t expected)
  2940. {
  2941. jit_node_t *k;
  2942. uint32_t *target;
  2943. emit_sp_ref_scm (j, T0, a);
  2944. emit_andi (j, T0, T0, mask);
  2945. switch (fuse_conditional_branch (j, &target))
  2946. {
  2947. case scm_op_je:
  2948. k = jit_beqi (T0, expected);
  2949. break;
  2950. case scm_op_jne:
  2951. k = jit_bnei (T0, expected);
  2952. break;
  2953. default:
  2954. UNREACHABLE ();
  2955. }
  2956. add_inter_instruction_patch (j, k, target);
  2957. }
  2958. static void
  2959. compile_heap_tag_equals (scm_jit_state *j, uint32_t obj,
  2960. uint16_t mask, uint16_t expected)
  2961. {
  2962. jit_node_t *k;
  2963. uint32_t *target;
  2964. emit_sp_ref_scm (j, T0, obj);
  2965. switch (fuse_conditional_branch (j, &target))
  2966. {
  2967. case scm_op_je:
  2968. k = emit_branch_if_heap_object_has_tc (j, T0, T0, mask, expected);
  2969. break;
  2970. case scm_op_jne:
  2971. k = emit_branch_if_heap_object_not_tc (j, T0, T0, mask, expected);
  2972. break;
  2973. default:
  2974. UNREACHABLE ();
  2975. }
  2976. add_inter_instruction_patch (j, k, target);
  2977. }
  2978. static void
  2979. compile_eq (scm_jit_state *j, uint16_t a, uint16_t b)
  2980. {
  2981. jit_node_t *k;
  2982. uint32_t *target;
  2983. emit_sp_ref_scm (j, T0, a);
  2984. emit_sp_ref_scm (j, T1, b);
  2985. switch (fuse_conditional_branch (j, &target))
  2986. {
  2987. case scm_op_je:
  2988. k = jit_beqr (T0, T1);
  2989. break;
  2990. case scm_op_jne:
  2991. k = jit_bner (T0, T1);
  2992. break;
  2993. default:
  2994. UNREACHABLE ();
  2995. }
  2996. add_inter_instruction_patch (j, k, target);
  2997. }
  2998. static void
  2999. compile_j (scm_jit_state *j, const uint32_t *vcode)
  3000. {
  3001. jit_node_t *jmp;
  3002. jmp = jit_jmpi ();
  3003. add_inter_instruction_patch (j, jmp, vcode);
  3004. }
  3005. static void
  3006. compile_jl (scm_jit_state *j, const uint32_t *vcode)
  3007. {
  3008. UNREACHABLE (); /* All tests should fuse their following branches. */
  3009. }
  3010. static void
  3011. compile_je (scm_jit_state *j, const uint32_t *vcode)
  3012. {
  3013. UNREACHABLE (); /* All tests should fuse their following branches. */
  3014. }
  3015. static void
  3016. compile_jnl (scm_jit_state *j, const uint32_t *vcode)
  3017. {
  3018. UNREACHABLE (); /* All tests should fuse their following branches. */
  3019. }
  3020. static void
  3021. compile_jne (scm_jit_state *j, const uint32_t *vcode)
  3022. {
  3023. UNREACHABLE (); /* All tests should fuse their following branches. */
  3024. }
  3025. static void
  3026. compile_jge (scm_jit_state *j, const uint32_t *vcode)
  3027. {
  3028. UNREACHABLE (); /* All tests should fuse their following branches. */
  3029. }
  3030. static void
  3031. compile_jnge (scm_jit_state *j, const uint32_t *vcode)
  3032. {
  3033. UNREACHABLE (); /* All tests should fuse their following branches. */
  3034. }
  3035. static void
  3036. compile_heap_numbers_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  3037. {
  3038. jit_node_t *k;
  3039. uint32_t *target;
  3040. emit_store_current_ip (j, T0);
  3041. emit_sp_ref_scm (j, T0, a);
  3042. emit_sp_ref_scm (j, T1, b);
  3043. emit_call_r_r (j, scm_vm_intrinsics.heap_numbers_equal_p, T0, T1);
  3044. emit_retval (j, T0);
  3045. emit_reload_sp (j);
  3046. switch (fuse_conditional_branch (j, &target))
  3047. {
  3048. case scm_op_je:
  3049. k = jit_bnei (T0, 0);
  3050. break;
  3051. case scm_op_jne:
  3052. k = jit_beqi (T0, 0);
  3053. break;
  3054. default:
  3055. UNREACHABLE ();
  3056. }
  3057. add_inter_instruction_patch (j, k, target);
  3058. }
  3059. static void
  3060. compile_untag_fixnum (scm_jit_state *j, uint16_t dst, uint16_t a)
  3061. {
  3062. emit_sp_ref_scm (j, T0, a);
  3063. emit_rshi (j, T0, T0, 2);
  3064. #if SIZEOF_UINTPTR_T >= 8
  3065. emit_sp_set_s64 (j, dst, T0);
  3066. #else
  3067. /* FIXME: Untested! */
  3068. emit_rshi (j, T1, T0, 31);
  3069. emit_sp_set_s64 (j, dst, T0, T1);
  3070. #endif
  3071. }
  3072. static void
  3073. compile_tag_fixnum (scm_jit_state *j, uint16_t dst, uint16_t a)
  3074. {
  3075. #if SIZEOF_UINTPTR_T >= 8
  3076. emit_sp_ref_s64 (j, T0, a);
  3077. #else
  3078. emit_sp_ref_s32 (j, T0, a);
  3079. #endif
  3080. emit_lshi (j, T0, T0, 2);
  3081. emit_addi (j, T0, T0, scm_tc2_int);
  3082. emit_sp_set_scm (j, dst, T0);
  3083. }
  3084. static void
  3085. compile_srsh (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3086. {
  3087. #if SIZEOF_UINTPTR_T >= 8
  3088. emit_sp_ref_s64 (j, T0, a);
  3089. emit_sp_ref_s64 (j, T1, b);
  3090. emit_andi (j, T1, T1, 63);
  3091. emit_rshr (j, T0, T0, T1);
  3092. emit_sp_set_s64 (j, dst, T0);
  3093. #else
  3094. /* FIXME: Not tested. */
  3095. jit_node_t *zero, *both, *done;
  3096. emit_sp_ref_s64 (j, T0, T1, a);
  3097. emit_sp_ref_s64 (j, T2, T3_OR_FP, b);
  3098. emit_andi (j, T2, T2, 63);
  3099. zero = jit_beqi (T2, 0);
  3100. both = jit_blti (T2, 32);
  3101. /* 32 <= s < 64: hi = hi >> 31, lo = hi >> (s-32) */
  3102. emit_subi (j, T2, 32);
  3103. emit_rshr (j, T0, T1, T2);
  3104. emit_rshi (j, T1, T1, 31);
  3105. done = jit_jmpi ();
  3106. jit_patch (both);
  3107. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  3108. emit_negr (j, T3_OR_FP, T2);
  3109. emit_addi (j, T3_OR_FP, T3_OR_FP, 32);
  3110. emit_lshr (j, T3_OR_FP, T1, T3_OR_FP);
  3111. emit_rshr (j, T1, T1, T2);
  3112. emit_rshr_u (j, T0, T0, T2);
  3113. emit_addr (j, T0, T0, T3_OR_FP);
  3114. jit_patch (done);
  3115. jit_patch (zero);
  3116. emit_sp_set_s64 (j, dst, T0, T1);
  3117. #endif
  3118. }
  3119. static void
  3120. compile_srsh_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3121. {
  3122. b &= 63;
  3123. #if SIZEOF_UINTPTR_T >= 8
  3124. emit_sp_ref_s64 (j, T0, a);
  3125. emit_rshi (j, T0, T0, b);
  3126. emit_sp_set_s64 (j, dst, T0);
  3127. #else
  3128. /* FIXME: Not tested. */
  3129. emit_sp_ref_s64 (j, T0, T1, a);
  3130. if (b == 0)
  3131. {
  3132. /* Nothing to do. */
  3133. }
  3134. else if (b >= 32)
  3135. {
  3136. /* hi = sign-ext, lo = hi >> (s-32) */
  3137. emit_rshi (j, T0, T1, b - 32);
  3138. emit_rshi (j, T1, T1, 31);
  3139. }
  3140. else
  3141. {
  3142. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  3143. emit_lshi (j, T2, T1, 32 - b);
  3144. emit_rshi (j, T1, T1, b);
  3145. emit_rshi_u (j, T0, T0, b);
  3146. emit_addr (j, T0, T0, T2);
  3147. }
  3148. emit_sp_set_s64 (j, dst, T0, T1);
  3149. #endif
  3150. }
  3151. static void
  3152. compile_s64_imm_numerically_equal (scm_jit_state *j, uint16_t a, int16_t b)
  3153. {
  3154. #if SIZEOF_UINTPTR_T >= 8
  3155. jit_node_t *k;
  3156. uint32_t *target;
  3157. emit_sp_ref_s64 (j, T0, a);
  3158. switch (fuse_conditional_branch (j, &target))
  3159. {
  3160. case scm_op_je:
  3161. k = jit_beqi (T0, b);
  3162. break;
  3163. case scm_op_jne:
  3164. k = jit_bnei (T0, b);
  3165. break;
  3166. default:
  3167. UNREACHABLE ();
  3168. }
  3169. add_inter_instruction_patch (j, k, target);
  3170. #else
  3171. jit_node_t *k1, *k2;
  3172. uint32_t *target;
  3173. emit_sp_ref_s64 (j, T0, T1, a);
  3174. switch (fuse_conditional_branch (j, &target))
  3175. {
  3176. case scm_op_je:
  3177. k1 = jit_bnei (T0, b);
  3178. k2 = jit_beqi (T1, b < 0 ? -1 : 0);
  3179. jit_patch (k1);
  3180. add_inter_instruction_patch (j, k2, target);
  3181. break;
  3182. case scm_op_jne:
  3183. k1 = jit_bnei (T0, b);
  3184. k2 = jit_bnei (T1, b < 0 ? -1 : 0);
  3185. add_inter_instruction_patch (j, k1, target);
  3186. add_inter_instruction_patch (j, k2, target);
  3187. break;
  3188. default:
  3189. UNREACHABLE ();
  3190. }
  3191. #endif
  3192. }
  3193. static void
  3194. compile_u64_imm_less (scm_jit_state *j, uint16_t a, uint16_t b)
  3195. {
  3196. #if SIZEOF_UINTPTR_T >= 8
  3197. jit_node_t *k;
  3198. uint32_t *target;
  3199. emit_sp_ref_u64 (j, T0, a);
  3200. switch (fuse_conditional_branch (j, &target))
  3201. {
  3202. case scm_op_jl:
  3203. k = jit_blti_u (T0, b);
  3204. break;
  3205. case scm_op_jnl:
  3206. k = jit_bgei_u (T0, b);
  3207. break;
  3208. default:
  3209. UNREACHABLE ();
  3210. }
  3211. add_inter_instruction_patch (j, k, target);
  3212. #else
  3213. jit_node_t *k1, *k2;
  3214. uint32_t *target;
  3215. emit_sp_ref_u64 (j, T0, T1, a);
  3216. switch (fuse_conditional_branch (j, &target))
  3217. {
  3218. case scm_op_jl:
  3219. k1 = jit_bnei (T1, 0);
  3220. k2 = jit_blti_u (T0, b);
  3221. jit_patch (k1);
  3222. add_inter_instruction_patch (j, k2, target);
  3223. break;
  3224. case scm_op_jnl:
  3225. k1 = jit_bgti (T1, 0);
  3226. k2 = jit_bgei_u (T0, b);
  3227. add_inter_instruction_patch (j, k1, target);
  3228. add_inter_instruction_patch (j, k2, target);
  3229. break;
  3230. default:
  3231. UNREACHABLE ();
  3232. }
  3233. #endif
  3234. }
  3235. static void
  3236. compile_imm_u64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  3237. {
  3238. #if SIZEOF_UINTPTR_T >= 8
  3239. jit_node_t *k;
  3240. uint32_t *target;
  3241. emit_sp_ref_u64 (j, T0, a);
  3242. switch (fuse_conditional_branch (j, &target))
  3243. {
  3244. case scm_op_jl:
  3245. k = jit_bgti_u (T0, b);
  3246. break;
  3247. case scm_op_jnl:
  3248. k = jit_blei_u (T0, b);
  3249. break;
  3250. default:
  3251. UNREACHABLE ();
  3252. }
  3253. add_inter_instruction_patch (j, k, target);
  3254. #else
  3255. jit_node_t *k1, *k2;
  3256. uint32_t *target;
  3257. emit_sp_ref_u64 (j, T0, T1, a);
  3258. switch (fuse_conditional_branch (j, &target))
  3259. {
  3260. case scm_op_jl:
  3261. k1 = jit_bnei (T1, 0);
  3262. k2 = jit_bgti_u (T0, b);
  3263. add_inter_instruction_patch (j, k1, target);
  3264. add_inter_instruction_patch (j, k2, target);
  3265. break;
  3266. case scm_op_jnl:
  3267. k1 = jit_bnei (T1, 0);
  3268. k2 = jit_blei_u (T0, b);
  3269. jit_patch (k1);
  3270. add_inter_instruction_patch (j, k2, target);
  3271. break;
  3272. default:
  3273. UNREACHABLE ();
  3274. }
  3275. #endif
  3276. }
  3277. static void
  3278. compile_s64_imm_less (scm_jit_state *j, uint16_t a, int16_t b)
  3279. {
  3280. #if SIZEOF_UINTPTR_T >= 8
  3281. jit_node_t *k;
  3282. uint32_t *target;
  3283. emit_sp_ref_s64 (j, T0, a);
  3284. switch (fuse_conditional_branch (j, &target))
  3285. {
  3286. case scm_op_jl:
  3287. k = jit_blti (T0, b);
  3288. break;
  3289. case scm_op_jnl:
  3290. k = jit_bgei (T0, b);
  3291. break;
  3292. default:
  3293. UNREACHABLE ();
  3294. }
  3295. add_inter_instruction_patch (j, k, target);
  3296. #else
  3297. jit_node_t *k1, *k2, *k3;
  3298. int32_t sign = b < 0 ? -1 : 0;
  3299. uint32_t *target;
  3300. emit_sp_ref_s64 (j, T0, T1, a);
  3301. switch (fuse_conditional_branch (j, &target))
  3302. {
  3303. case scm_op_jl:
  3304. k1 = jit_blti (T1, sign);
  3305. k2 = jit_bnei (T1, sign);
  3306. k3 = jit_blti (T0, b);
  3307. jit_patch (k2);
  3308. add_inter_instruction_patch (j, k1, target);
  3309. add_inter_instruction_patch (j, k3, target);
  3310. break;
  3311. case scm_op_jnl:
  3312. k1 = jit_bgti (T1, sign);
  3313. k2 = jit_bnei (T1, sign);
  3314. k3 = jit_bgei (T0, b);
  3315. jit_patch (k2);
  3316. add_inter_instruction_patch (j, k1, target);
  3317. add_inter_instruction_patch (j, k3, target);
  3318. break;
  3319. default:
  3320. UNREACHABLE ();
  3321. }
  3322. #endif
  3323. }
  3324. static void
  3325. compile_imm_s64_less (scm_jit_state *j, uint16_t a, int16_t b)
  3326. {
  3327. #if SIZEOF_UINTPTR_T >= 8
  3328. jit_node_t *k;
  3329. uint32_t *target;
  3330. emit_sp_ref_s64 (j, T0, a);
  3331. switch (fuse_conditional_branch (j, &target))
  3332. {
  3333. case scm_op_jl:
  3334. k = jit_bgti (T0, b);
  3335. break;
  3336. case scm_op_jnl:
  3337. k = jit_blei (T0, b);
  3338. break;
  3339. default:
  3340. UNREACHABLE ();
  3341. }
  3342. add_inter_instruction_patch (j, k, target);
  3343. #else
  3344. jit_node_t *k1, *k2, *k3;
  3345. int32_t sign = b < 0 ? -1 : 0;
  3346. uint32_t *target;
  3347. emit_sp_ref_s64 (j, T0, T1, a);
  3348. switch (fuse_conditional_branch (j, &target))
  3349. {
  3350. case scm_op_jl:
  3351. k1 = jit_blti (T1, sign);
  3352. k2 = jit_bnei (T1, sign);
  3353. k3 = jit_bgti (T0, b);
  3354. jit_patch (k1);
  3355. add_inter_instruction_patch (j, k2, target);
  3356. add_inter_instruction_patch (j, k3, target);
  3357. break;
  3358. case scm_op_jnl:
  3359. k1 = jit_bgti (T1, sign);
  3360. k2 = jit_bnei (T1, sign);
  3361. k3 = jit_blei (T0, b);
  3362. jit_patch (k1);
  3363. add_inter_instruction_patch (j, k2, target);
  3364. add_inter_instruction_patch (j, k3, target);
  3365. break;
  3366. default:
  3367. UNREACHABLE ();
  3368. }
  3369. #endif
  3370. }
  3371. static void
  3372. compile_u8_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3373. {
  3374. emit_sp_ref_ptr (j, T0, ptr);
  3375. emit_sp_ref_sz (j, T1, idx);
  3376. jit_ldxr_uc (T0, T0, T1);
  3377. record_gpr_clobber (j, T0);
  3378. #if SIZEOF_UINTPTR_T >= 8
  3379. emit_sp_set_u64 (j, dst, T0);
  3380. #else
  3381. emit_movi (j, T1, 0);
  3382. emit_sp_set_u64 (j, dst, T0, T1);
  3383. #endif
  3384. }
  3385. static void
  3386. compile_u16_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3387. {
  3388. emit_sp_ref_ptr (j, T0, ptr);
  3389. emit_sp_ref_sz (j, T1, idx);
  3390. jit_ldxr_us (T0, T0, T1);
  3391. record_gpr_clobber (j, T0);
  3392. #if SIZEOF_UINTPTR_T >= 8
  3393. emit_sp_set_u64 (j, dst, T0);
  3394. #else
  3395. emit_movi (j, T1, 0);
  3396. emit_sp_set_u64 (j, dst, T0, T1);
  3397. #endif
  3398. }
  3399. static void
  3400. compile_u32_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3401. {
  3402. emit_sp_ref_ptr (j, T0, ptr);
  3403. emit_sp_ref_sz (j, T1, idx);
  3404. #if SIZEOF_UINTPTR_T >= 8
  3405. jit_ldxr_ui (T0, T0, T1);
  3406. record_gpr_clobber (j, T0);
  3407. emit_sp_set_u64 (j, dst, T0);
  3408. #else
  3409. emit_ldxr (j, T0, T0, T1);
  3410. emit_movi (j, T1, 0);
  3411. emit_sp_set_u64 (j, dst, T0, T1);
  3412. #endif
  3413. }
  3414. static void
  3415. compile_u64_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3416. {
  3417. emit_sp_ref_ptr (j, T0, ptr);
  3418. emit_sp_ref_sz (j, T1, idx);
  3419. #if SIZEOF_UINTPTR_T >= 8
  3420. emit_ldxr (j, T0, T0, T1);
  3421. emit_sp_set_u64 (j, dst, T0);
  3422. #else
  3423. emit_addr (j, T0, T0, T1);
  3424. if (BIGENDIAN)
  3425. {
  3426. emit_ldxi (j, T1, T0, 4);
  3427. emit_ldr (j, T0, T0);
  3428. }
  3429. else
  3430. {
  3431. emit_ldr (j, T1, T0);
  3432. emit_ldxi (j, T0, T0, 4);
  3433. }
  3434. emit_sp_set_u64 (j, dst, T0, T1);
  3435. #endif
  3436. }
  3437. static void
  3438. compile_u8_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3439. {
  3440. emit_sp_ref_ptr (j, T0, ptr);
  3441. emit_sp_ref_sz (j, T1, idx);
  3442. #if SIZEOF_UINTPTR_T >= 8
  3443. emit_sp_ref_u64 (j, T2, v);
  3444. #else
  3445. emit_sp_ref_u64_lower_half (j, T2, v);
  3446. #endif
  3447. jit_stxr_c (T0, T1, T2);
  3448. }
  3449. static void
  3450. compile_u16_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3451. {
  3452. emit_sp_ref_ptr (j, T0, ptr);
  3453. emit_sp_ref_sz (j, T1, idx);
  3454. #if SIZEOF_UINTPTR_T >= 8
  3455. emit_sp_ref_u64 (j, T2, v);
  3456. #else
  3457. emit_sp_ref_u64_lower_half (j, T2, v);
  3458. #endif
  3459. jit_stxr_s (T0, T1, T2);
  3460. }
  3461. static void
  3462. compile_u32_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3463. {
  3464. emit_sp_ref_ptr (j, T0, ptr);
  3465. emit_sp_ref_sz (j, T1, idx);
  3466. #if SIZEOF_UINTPTR_T >= 8
  3467. emit_sp_ref_u64 (j, T2, v);
  3468. jit_stxr_i (T0, T1, T2);
  3469. #else
  3470. emit_sp_ref_u64_lower_half (j, T2, v);
  3471. jit_stxr (T0, T1, T2);
  3472. #endif
  3473. }
  3474. static void
  3475. compile_u64_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3476. {
  3477. emit_sp_ref_ptr (j, T0, ptr);
  3478. emit_sp_ref_sz (j, T1, idx);
  3479. #if SIZEOF_UINTPTR_T >= 8
  3480. emit_sp_ref_u64 (j, T2, v);
  3481. jit_stxr (T0, T1, T2);
  3482. #else
  3483. jit_addr (T0, T0, T1);
  3484. emit_sp_ref_u64 (j, T1, T2, v);
  3485. if (BIGENDIAN)
  3486. {
  3487. jit_str (T0, T2);
  3488. jit_stxi (4, T0, T1);
  3489. }
  3490. else
  3491. {
  3492. jit_str (T0, T1);
  3493. jit_stxi (4, T0, T2);
  3494. }
  3495. #endif
  3496. }
  3497. static void
  3498. compile_s8_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3499. {
  3500. emit_sp_ref_ptr (j, T0, ptr);
  3501. emit_sp_ref_sz (j, T1, idx);
  3502. jit_ldxr_c (T0, T0, T1);
  3503. record_gpr_clobber (j, T0);
  3504. #if SIZEOF_UINTPTR_T >= 8
  3505. emit_sp_set_s64 (j, dst, T0);
  3506. #else
  3507. emit_rshi (j, T1, T0, 7);
  3508. emit_sp_set_u64 (j, dst, T0, T1);
  3509. #endif
  3510. }
  3511. static void
  3512. compile_s16_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3513. {
  3514. emit_sp_ref_ptr (j, T0, ptr);
  3515. emit_sp_ref_sz (j, T1, idx);
  3516. jit_ldxr_s (T0, T0, T1);
  3517. record_gpr_clobber (j, T0);
  3518. #if SIZEOF_UINTPTR_T >= 8
  3519. emit_sp_set_s64 (j, dst, T0);
  3520. #else
  3521. emit_rshi (j, T1, T0, 15);
  3522. emit_sp_set_u64 (j, dst, T0, T1);
  3523. #endif
  3524. }
  3525. static void
  3526. compile_s32_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3527. {
  3528. emit_sp_ref_ptr (j, T0, ptr);
  3529. emit_sp_ref_sz (j, T1, idx);
  3530. jit_ldxr_i (T0, T0, T1);
  3531. record_gpr_clobber (j, T0);
  3532. #if SIZEOF_UINTPTR_T >= 8
  3533. emit_sp_set_s64 (j, dst, T0);
  3534. #else
  3535. emit_rshi (j, T1, T0, 31);
  3536. emit_sp_set_u64 (j, dst, T0, T1);
  3537. #endif
  3538. }
  3539. static void
  3540. compile_s64_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3541. {
  3542. compile_u64_ref (j, dst, ptr, idx);
  3543. }
  3544. static void
  3545. compile_s8_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3546. {
  3547. compile_u8_set (j, ptr, idx, v);
  3548. }
  3549. static void
  3550. compile_s16_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3551. {
  3552. compile_u16_set (j, ptr, idx, v);
  3553. }
  3554. static void
  3555. compile_s32_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3556. {
  3557. compile_u32_set (j, ptr, idx, v);
  3558. }
  3559. static void
  3560. compile_s64_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3561. {
  3562. compile_u64_set (j, ptr, idx, v);
  3563. }
  3564. static void
  3565. compile_f32_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3566. {
  3567. emit_sp_ref_ptr (j, T0, ptr);
  3568. emit_sp_ref_sz (j, T1, idx);
  3569. jit_ldxr_f (JIT_F0, T0, T1);
  3570. record_fpr_clobber (j, JIT_F0);
  3571. jit_extr_f_d (JIT_F0, JIT_F0);
  3572. emit_sp_set_f64 (j, dst, JIT_F0);
  3573. }
  3574. static void
  3575. compile_f64_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3576. {
  3577. emit_sp_ref_ptr (j, T0, ptr);
  3578. emit_sp_ref_sz (j, T1, idx);
  3579. jit_ldxr_d (JIT_F0, T0, T1);
  3580. record_fpr_clobber (j, JIT_F0);
  3581. emit_sp_set_f64 (j, dst, JIT_F0);
  3582. }
  3583. static void
  3584. compile_f32_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3585. {
  3586. emit_sp_ref_ptr (j, T0, ptr);
  3587. emit_sp_ref_sz (j, T1, idx);
  3588. emit_sp_ref_f64 (j, JIT_F0, v);
  3589. jit_extr_d_f (JIT_F0, JIT_F0);
  3590. record_fpr_clobber (j, JIT_F0);
  3591. jit_stxr_d (T0, T1, JIT_F0);
  3592. }
  3593. static void
  3594. compile_f64_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3595. {
  3596. emit_sp_ref_ptr (j, T0, ptr);
  3597. emit_sp_ref_sz (j, T1, idx);
  3598. emit_sp_ref_f64 (j, JIT_F0, v);
  3599. jit_stxr_d (T0, T1, JIT_F0);
  3600. }
  3601. #define UNPACK_8_8_8(op,a,b,c) \
  3602. do \
  3603. { \
  3604. a = (op >> 8) & 0xff; \
  3605. b = (op >> 16) & 0xff; \
  3606. c = op >> 24; \
  3607. } \
  3608. while (0)
  3609. #define UNPACK_8_16(op,a,b) \
  3610. do \
  3611. { \
  3612. a = (op >> 8) & 0xff; \
  3613. b = op >> 16; \
  3614. } \
  3615. while (0)
  3616. #define UNPACK_12_12(op,a,b) \
  3617. do \
  3618. { \
  3619. a = (op >> 8) & 0xfff; \
  3620. b = op >> 20; \
  3621. } \
  3622. while (0)
  3623. #define UNPACK_24(op,a) \
  3624. do \
  3625. { \
  3626. a = op >> 8; \
  3627. } \
  3628. while (0)
  3629. #define UNPACK_8_24(op,a,b) \
  3630. do \
  3631. { \
  3632. a = op & 0xff; \
  3633. b = op >> 8; \
  3634. } \
  3635. while (0)
  3636. #define UNPACK_16_16(op,a,b) \
  3637. do \
  3638. { \
  3639. a = op & 0xffff; \
  3640. b = op >> 16; \
  3641. } \
  3642. while (0)
  3643. #define COMPILE_OP1(t0) \
  3644. COMPILE_##t0
  3645. #define COMPILE_OP2(t0, t1) \
  3646. COMPILE_##t0##__##t1
  3647. #define COMPILE_OP3(t0, t1, t2) \
  3648. COMPILE_##t0##__##t1##__##t2
  3649. #define COMPILE_OP4(t0, t1, t2, t3) \
  3650. COMPILE_##t0##__##t1##__##t2##__##t3
  3651. #define COMPILE_OP5(t0, t1, t2, t3, t4) \
  3652. COMPILE_##t0##__##t1##__##t2##__##t3##__##t4
  3653. #define COMPILE_DOP1(t0) COMPILE_OP1(t0)
  3654. #define COMPILE_DOP2(t0, t1) COMPILE_OP2(t0, t1)
  3655. #define COMPILE_DOP3(t0, t1, t2) COMPILE_OP3(t0, t1, t2)
  3656. #define COMPILE_DOP4(t0, t1, t2, t3) COMPILE_OP4(t0, t1, t2, t3)
  3657. #define COMPILE_DOP5(t0, t1, t2, t3, t4) COMPILE_OP5(t0, t1, t2, t3, t4)
  3658. #define COMPILE_NOP(j, comp) \
  3659. { \
  3660. bad_instruction (j); \
  3661. }
  3662. #define COMPILE_X32(j, comp) \
  3663. { \
  3664. comp (j); \
  3665. }
  3666. #define COMPILE_X8_C24(j, comp) \
  3667. { \
  3668. uint32_t a; \
  3669. UNPACK_24 (j->ip[0], a); \
  3670. comp (j, a); \
  3671. }
  3672. #define COMPILE_X8_F24(j, comp) \
  3673. COMPILE_X8_C24 (j, comp)
  3674. #define COMPILE_X8_S24(j, comp) \
  3675. COMPILE_X8_C24 (j, comp)
  3676. #define COMPILE_X8_L24(j, comp) \
  3677. { \
  3678. int32_t a = j->ip[0]; \
  3679. a >>= 8; /* Sign extension. */ \
  3680. comp (j, j->ip + a); \
  3681. }
  3682. #define COMPILE_X8_C12_C12(j, comp) \
  3683. { \
  3684. uint16_t a, b; \
  3685. UNPACK_12_12 (j->ip[0], a, b); \
  3686. comp (j, a, b); \
  3687. }
  3688. #define COMPILE_X8_S12_C12(j, comp) \
  3689. COMPILE_X8_C12_C12 (j, comp)
  3690. #define COMPILE_X8_S12_S12(j, comp) \
  3691. COMPILE_X8_C12_C12 (j, comp)
  3692. #define COMPILE_X8_F12_F12(j, comp) \
  3693. COMPILE_X8_C12_C12 (j, comp)
  3694. #define COMPILE_X8_S12_Z12(j, comp) \
  3695. { \
  3696. uint16_t a = (j->ip[0] >> 8) & 0xfff; \
  3697. int16_t b = ((int32_t) j->ip[0]) >> 20; /* Sign extension. */ \
  3698. comp (j, a, b); \
  3699. }
  3700. #define COMPILE_X8_S8_C8_S8(j, comp) \
  3701. { \
  3702. uint8_t a, b, c; \
  3703. UNPACK_8_8_8 (j->ip[0], a, b, c); \
  3704. comp (j, a, b, c); \
  3705. }
  3706. #define COMPILE_X8_S8_S8_C8(j, comp) \
  3707. COMPILE_X8_S8_C8_S8 (j, comp)
  3708. #define COMPILE_X8_S8_S8_S8(j, comp) \
  3709. COMPILE_X8_S8_C8_S8 (j, comp)
  3710. #define COMPILE_X8_S8_I16(j, comp) \
  3711. { \
  3712. uint8_t a; \
  3713. scm_t_bits b; \
  3714. UNPACK_8_16 (j->ip[0], a, b); \
  3715. comp (j, a, SCM_PACK (b)); \
  3716. }
  3717. #define COMPILE_X32__C32(j, comp) \
  3718. { \
  3719. comp (j, j->ip[1]); \
  3720. }
  3721. #define COMPILE_X32__L32(j, comp) \
  3722. { \
  3723. int32_t a = j->ip[1]; \
  3724. comp (j, j->ip + a); \
  3725. }
  3726. #define COMPILE_X32__N32(j, comp) \
  3727. COMPILE_X32__L32 (j, comp)
  3728. #define COMPILE_X8_C24__L32(j, comp) \
  3729. { \
  3730. uint32_t a; \
  3731. int32_t b; \
  3732. UNPACK_24 (j->ip[0], a); \
  3733. b = j->ip[1]; \
  3734. comp (j, a, j->ip + b); \
  3735. }
  3736. #define COMPILE_X8_S24__L32(j, comp) \
  3737. COMPILE_X8_C24__L32 (j, comp)
  3738. #define COMPILE_X8_S24__LO32(j, comp) \
  3739. COMPILE_X8_C24__L32 (j, comp)
  3740. #define COMPILE_X8_S24__N32(j, comp) \
  3741. COMPILE_X8_C24__L32 (j, comp)
  3742. #define COMPILE_X8_S24__R32(j, comp) \
  3743. COMPILE_X8_C24__L32 (j, comp)
  3744. #define COMPILE_X8_C24__X8_C24(j, comp) \
  3745. { \
  3746. uint32_t a, b; \
  3747. UNPACK_24 (j->ip[0], a); \
  3748. UNPACK_24 (j->ip[1], b); \
  3749. comp (j, a, b); \
  3750. }
  3751. #define COMPILE_X8_F24__X8_C24(j, comp) \
  3752. COMPILE_X8_C24__X8_C24(j, comp)
  3753. #define COMPILE_X8_F24__X8_F24(j, comp) \
  3754. COMPILE_X8_C24__X8_C24(j, comp)
  3755. #define COMPILE_X8_S24__X8_S24(j, comp) \
  3756. COMPILE_X8_C24__X8_C24(j, comp)
  3757. #define COMPILE_X8_F12_F12__X8_C24(j, comp) \
  3758. { \
  3759. uint16_t a, b; \
  3760. uint32_t c; \
  3761. UNPACK_12_12 (j->ip[0], a, b); \
  3762. UNPACK_24 (j->ip[1], c); \
  3763. comp (j, a, b, c); \
  3764. }
  3765. #define COMPILE_X8_F24__B1_X7_C24(j, comp) \
  3766. { \
  3767. uint32_t a, c; \
  3768. uint8_t b; \
  3769. UNPACK_24 (j->ip[0], a); \
  3770. b = j->ip[1] & 0x1; \
  3771. UNPACK_24 (j->ip[1], c); \
  3772. comp (j, a, b, c); \
  3773. }
  3774. #define COMPILE_X8_S12_S12__C32(j, comp) \
  3775. { \
  3776. uint16_t a, b; \
  3777. uint32_t c; \
  3778. UNPACK_12_12 (j->ip[0], a, b); \
  3779. c = j->ip[1]; \
  3780. comp (j, a, b, c); \
  3781. }
  3782. #define COMPILE_X8_S24__C16_C16(j, comp) \
  3783. { \
  3784. uint32_t a; \
  3785. uint16_t b, c; \
  3786. UNPACK_24 (j->ip[0], a); \
  3787. UNPACK_16_16 (j->ip[1], b, c); \
  3788. comp (j, a, b, c); \
  3789. }
  3790. #define COMPILE_X8_S24__C32(j, comp) \
  3791. { \
  3792. uint32_t a, b; \
  3793. UNPACK_24 (j->ip[0], a); \
  3794. b = j->ip[1]; \
  3795. comp (j, a, b); \
  3796. }
  3797. #define COMPILE_X8_S24__I32(j, comp) \
  3798. { \
  3799. uint32_t a; \
  3800. scm_t_bits b; \
  3801. UNPACK_24 (j->ip[0], a); \
  3802. b = j->ip[1]; \
  3803. comp (j, a, SCM_PACK (b)); \
  3804. }
  3805. #define COMPILE_X8_S8_S8_C8__C32(j, comp) \
  3806. { \
  3807. uint8_t a, b, c; \
  3808. uint32_t d; \
  3809. UNPACK_8_8_8 (j->ip[0], a, b, c); \
  3810. d = j->ip[1]; \
  3811. comp (j, a, b, c, d); \
  3812. }
  3813. #define COMPILE_X8_S8_S8_S8__C32(j, comp) \
  3814. COMPILE_X8_S8_S8_C8__C32(j, comp)
  3815. #define COMPILE_X32__LO32__L32(j, comp) \
  3816. { \
  3817. int32_t a = j->ip[1], b = j->ip[2]; \
  3818. comp (j, j->ip + a, j->ip + b); \
  3819. }
  3820. #define COMPILE_X8_F24__X8_C24__L32(j, comp) \
  3821. { \
  3822. uint32_t a, b; \
  3823. int32_t c; \
  3824. UNPACK_24 (j->ip[0], a); \
  3825. UNPACK_24 (j->ip[1], b); \
  3826. c = j->ip[2]; \
  3827. comp (j, a, b, j->ip + c); \
  3828. }
  3829. #define COMPILE_X8_S24__A32__B32(j, comp) \
  3830. { \
  3831. uint32_t a; \
  3832. uint64_t b; \
  3833. UNPACK_24 (j->ip[0], a); \
  3834. b = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  3835. ASSERT (b <= (uint64_t) UINTPTR_MAX); \
  3836. comp (j, a, SCM_PACK ((uintptr_t) b)); \
  3837. }
  3838. #define COMPILE_X8_S24__AF32__BF32(j, comp) \
  3839. { \
  3840. uint32_t a; \
  3841. union { uint64_t u; double d; } b; \
  3842. UNPACK_24 (j->ip[0], a); \
  3843. b.u = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  3844. comp (j, a, b.d); \
  3845. }
  3846. #define COMPILE_X8_S24__AS32__BS32(j, comp) \
  3847. { \
  3848. uint32_t a; \
  3849. uint64_t b; \
  3850. UNPACK_24 (j->ip[0], a); \
  3851. b = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  3852. comp (j, a, (int64_t) b); \
  3853. }
  3854. #define COMPILE_X8_S24__AU32__BU32(j, comp) \
  3855. { \
  3856. uint32_t a; \
  3857. uint64_t b; \
  3858. UNPACK_24 (j->ip[0], a); \
  3859. b = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  3860. comp (j, a, b); \
  3861. }
  3862. #define COMPILE_X8_S24__B1_X7_F24__X8_L24(j, comp) \
  3863. { \
  3864. uint32_t a, c; \
  3865. uint8_t b; \
  3866. int32_t d; \
  3867. UNPACK_24 (j->ip[0], a); \
  3868. b = j->ip[1] & 0x1; \
  3869. UNPACK_24 (j->ip[1], c); \
  3870. d = j->ip[2]; d >>= 8; /* Sign extension. */ \
  3871. comp (j, a, b, c, j->ip + d); \
  3872. }
  3873. #define COMPILE_X8_S24__X8_S24__C8_S24(j, comp) \
  3874. { \
  3875. uint32_t a, b, d; \
  3876. uint8_t c; \
  3877. UNPACK_24 (j->ip[0], a); \
  3878. UNPACK_24 (j->ip[1], b); \
  3879. UNPACK_8_24 (j->ip[2], c, d); \
  3880. comp (j, a, b, c, d); \
  3881. }
  3882. #define COMPILE_X8_C24__C8_C24__X8_C24__N32(j, comp) \
  3883. { \
  3884. uint32_t a, c, d; \
  3885. uint8_t b; \
  3886. int32_t e; \
  3887. UNPACK_24 (j->ip[0], a); \
  3888. UNPACK_8_24 (j->ip[1], b, c); \
  3889. UNPACK_24 (j->ip[2], d); \
  3890. e = j->ip[3]; \
  3891. comp (j, a, b, c, d, j->ip + e); \
  3892. }
  3893. #define COMPILE_X8_S24__X8_S24__C8_S24__X8_S24(j, comp) \
  3894. { \
  3895. uint32_t a, b, d, e; \
  3896. uint8_t c; \
  3897. UNPACK_24 (j->ip[0], a); \
  3898. UNPACK_24 (j->ip[1], b); \
  3899. UNPACK_8_24 (j->ip[2], c, d); \
  3900. UNPACK_24 (j->ip[3], e); \
  3901. comp (j, a, b, c, d, e); \
  3902. }
  3903. static uint8_t first_seen[256];
  3904. static void
  3905. compile1 (scm_jit_state *j)
  3906. {
  3907. uint8_t opcode = j->ip[0] & 0xff;
  3908. if (!first_seen[opcode])
  3909. {
  3910. const char *n;
  3911. switch (opcode)
  3912. {
  3913. #define NAME(code, cname, name, arity) case code: n = name; break;
  3914. FOR_EACH_VM_OPERATION(NAME)
  3915. #undef NAME
  3916. default:
  3917. UNREACHABLE ();
  3918. }
  3919. first_seen[opcode] = 1;
  3920. DEBUG ("Instruction first seen at vcode %p: %s\n", j->ip, n);
  3921. }
  3922. j->next_ip = j->ip + op_lengths[opcode];
  3923. switch (opcode)
  3924. {
  3925. #define COMPILE1(code, cname, name, arity) \
  3926. case code: COMPILE_##arity(j, compile_##cname); break;
  3927. FOR_EACH_VM_OPERATION(COMPILE1)
  3928. #undef COMPILE1
  3929. default:
  3930. UNREACHABLE ();
  3931. }
  3932. j->ip = j->next_ip;
  3933. }
  3934. static void
  3935. analyze (scm_jit_state *j)
  3936. {
  3937. memset (j->op_attrs, 0, j->end - j->start);
  3938. j->op_attrs[0] = OP_ATTR_BLOCK | OP_ATTR_ENTRY;
  3939. for (j->ip = (uint32_t *) j->start; j->ip < j->end; j->ip = j->next_ip)
  3940. {
  3941. uint8_t opcode = j->ip[0] & 0xff;
  3942. uint8_t attrs = 0;
  3943. uint32_t *target;
  3944. j->next_ip = j->ip + op_lengths[opcode];
  3945. switch (opcode)
  3946. {
  3947. case scm_op_check_arguments:
  3948. case scm_op_check_positional_arguments:
  3949. attrs |= OP_ATTR_ENTRY;
  3950. /* Fall through. */
  3951. case scm_op_u64_numerically_equal:
  3952. case scm_op_u64_less:
  3953. case scm_op_s64_less:
  3954. case scm_op_f64_numerically_equal:
  3955. case scm_op_f64_less:
  3956. case scm_op_numerically_equal:
  3957. case scm_op_less:
  3958. case scm_op_immediate_tag_equals:
  3959. case scm_op_heap_tag_equals:
  3960. case scm_op_eq:
  3961. case scm_op_heap_numbers_equal:
  3962. case scm_op_s64_imm_numerically_equal:
  3963. case scm_op_u64_imm_less:
  3964. case scm_op_imm_u64_less:
  3965. case scm_op_s64_imm_less:
  3966. case scm_op_imm_s64_less:
  3967. attrs |= OP_ATTR_BLOCK;
  3968. fuse_conditional_branch (j, &target);
  3969. j->op_attrs[target - j->start] |= attrs;
  3970. break;
  3971. case scm_op_j:
  3972. target = j->ip + (((int32_t)j->ip[0]) >> 8);
  3973. j->op_attrs[target - j->start] |= OP_ATTR_BLOCK;
  3974. break;
  3975. case scm_op_call:
  3976. case scm_op_call_label:
  3977. attrs = OP_ATTR_BLOCK;
  3978. target = j->next_ip;
  3979. j->op_attrs[target - j->start] |= OP_ATTR_BLOCK | OP_ATTR_ENTRY;
  3980. break;
  3981. case scm_op_prompt:
  3982. target = j->ip + (((int32_t) j->ip[2]) >> 8);
  3983. j->op_attrs[target - j->start] |= OP_ATTR_BLOCK | OP_ATTR_ENTRY;
  3984. break;
  3985. default:
  3986. break;
  3987. }
  3988. }
  3989. /* Even in loops, the entry should be a jump target. */
  3990. ASSERT (j->op_attrs[j->entry - j->start] & OP_ATTR_BLOCK);
  3991. }
  3992. static void
  3993. compile (scm_jit_state *j)
  3994. {
  3995. uint32_t offset;
  3996. jit_prolog ();
  3997. jit_tramp (entry_frame_size);
  3998. analyze (j);
  3999. for (offset = 0; j->start + offset < j->end; offset++)
  4000. if (j->op_attrs[offset] & OP_ATTR_BLOCK)
  4001. j->labels[offset] = jit_forward ();
  4002. j->ip = (uint32_t *) j->start;
  4003. set_register_state (j, SP_IN_REGISTER | FP_IN_REGISTER);
  4004. while (j->ip < j->end)
  4005. {
  4006. ptrdiff_t offset = j->ip - j->start;
  4007. uint8_t attrs = j->op_attrs[offset];
  4008. if (attrs & OP_ATTR_BLOCK)
  4009. {
  4010. uint32_t state = SP_IN_REGISTER;
  4011. if (attrs & OP_ATTR_ENTRY)
  4012. state |= FP_IN_REGISTER;
  4013. j->register_state = state;
  4014. jit_link (j->labels[offset]);
  4015. }
  4016. if (j->ip == j->entry)
  4017. j->entry_label = jit_indirect ();
  4018. compile1 (j);
  4019. }
  4020. }
  4021. static scm_i_pthread_once_t initialize_jit_once = SCM_I_PTHREAD_ONCE_INIT;
  4022. static scm_jit_state *
  4023. initialize_thread_jit_state (scm_thread *thread)
  4024. {
  4025. scm_jit_state *j;
  4026. ASSERT (!thread->jit_state);
  4027. j = scm_gc_malloc_pointerless (sizeof (*j), "jit state");
  4028. memset (j, 0, sizeof (*j));
  4029. thread->jit_state = j;
  4030. return j;
  4031. }
  4032. static void
  4033. initialize_jit (void)
  4034. {
  4035. scm_jit_state *j;
  4036. jit_node_t *exit;
  4037. init_jit (NULL);
  4038. /* Init the thread's jit state so we can emit the entry
  4039. trampoline and the handle-interrupts trampoline. */
  4040. j = initialize_thread_jit_state (SCM_I_CURRENT_THREAD);
  4041. prepare_jit_state (j);
  4042. exit = emit_entry_trampoline (j);
  4043. enter_mcode = emit_code (j);
  4044. ASSERT (enter_mcode);
  4045. exit_mcode = jit_address (exit);
  4046. reset_jit_state (j);
  4047. prepare_jit_state (j);
  4048. emit_handle_interrupts_trampoline (j);
  4049. handle_interrupts_trampoline = emit_code (j);
  4050. reset_jit_state (j);
  4051. }
  4052. static uint8_t *
  4053. compute_mcode (scm_thread *thread, uint32_t *entry_ip,
  4054. struct scm_jit_function_data *data)
  4055. {
  4056. scm_jit_state *j = thread->jit_state;
  4057. uint8_t *entry_mcode;
  4058. if (!j)
  4059. {
  4060. scm_i_pthread_once (&initialize_jit_once, initialize_jit);
  4061. j = thread->jit_state;
  4062. /* It's possible that initialize_jit_once inits this thread's jit
  4063. state. */
  4064. if (!j)
  4065. j = initialize_thread_jit_state (thread);
  4066. }
  4067. j->thread = thread;
  4068. j->start = (const uint32_t *) (((char *)data) + data->start);
  4069. j->end = (const uint32_t *) (((char *)data) + data->end);
  4070. j->entry = entry_ip;
  4071. ASSERT (j->start < j->end);
  4072. ASSERT (j->start <= j->entry);
  4073. ASSERT (j->entry < j->end);
  4074. j->op_attrs = malloc ((j->end - j->start) * sizeof (*j->op_attrs));
  4075. ASSERT (j->op_attrs);
  4076. j->labels = malloc ((j->end - j->start) * sizeof (*j->labels));
  4077. ASSERT (j->labels);
  4078. j->frame_size = -1;
  4079. INFO ("vcode: start=%p,+%zu entry=+%zu\n", j->start, j->end - j->start,
  4080. j->entry - j->start);
  4081. prepare_jit_state (j);
  4082. compile (j);
  4083. data->mcode = emit_code (j);
  4084. if (data->mcode)
  4085. entry_mcode = jit_address (j->entry_label);
  4086. else
  4087. entry_mcode = NULL;
  4088. free (j->op_attrs);
  4089. j->op_attrs = NULL;
  4090. free (j->labels);
  4091. j->labels = NULL;
  4092. reset_jit_state (j);
  4093. j->start = j->end = j->ip = j->entry = NULL;
  4094. j->frame_size = -1;
  4095. return entry_mcode;
  4096. }
  4097. const uint8_t *
  4098. scm_jit_compute_mcode (scm_thread *thread, struct scm_jit_function_data *data)
  4099. {
  4100. const uint32_t *vcode_start = (const uint32_t *) (((char *)data) + data->start);
  4101. if (data->mcode)
  4102. {
  4103. if (vcode_start == thread->vm.ip)
  4104. return data->mcode;
  4105. /* FIXME: The function has mcode, compiled via some other
  4106. activation (possibly in another thread), but right now we're
  4107. currently in an interpreted loop (not at the beginning of the
  4108. function). We should re-compute the offset into the mcode.
  4109. For now though, just punt. */
  4110. return NULL;
  4111. }
  4112. else
  4113. {
  4114. uint8_t *mcode = compute_mcode (thread, thread->vm.ip, data);
  4115. if (!mcode)
  4116. {
  4117. scm_jit_counter_threshold = -1;
  4118. fprintf (stderr, "JIT failed due to resource exhaustion\n");
  4119. fprintf (stderr, "disabling automatic JIT compilation\n");
  4120. }
  4121. else if (--jit_stop_after == 0)
  4122. {
  4123. scm_jit_counter_threshold = -1;
  4124. fprintf (stderr, "stopping automatic JIT compilation, as requested\n");
  4125. if (jit_pause_when_stopping)
  4126. {
  4127. fprintf (stderr, "sleeping for 30s; to debug:\n");
  4128. fprintf (stderr, " gdb -p %d\n\n", getpid ());
  4129. sleep (30);
  4130. }
  4131. }
  4132. return mcode;
  4133. }
  4134. }
  4135. void
  4136. scm_jit_enter_mcode (scm_thread *thread, const uint8_t *mcode)
  4137. {
  4138. LOG ("entering mcode: %p\n", mcode);
  4139. enter_mcode (thread, mcode);
  4140. LOG ("exited mcode\n");
  4141. }
  4142. void
  4143. scm_jit_state_free (scm_jit_state *j)
  4144. {
  4145. /* Nothing to do; we leave j->jit NULL between compilations. */
  4146. }
  4147. void
  4148. scm_init_jit (void)
  4149. {
  4150. scm_jit_counter_threshold = scm_getenv_int ("GUILE_JIT_THRESHOLD",
  4151. default_jit_threshold);
  4152. jit_stop_after = scm_getenv_int ("GUILE_JIT_STOP_AFTER", -1);
  4153. jit_pause_when_stopping = scm_getenv_int ("GUILE_JIT_PAUSE_WHEN_STOPPING", 0);
  4154. jit_log_level = scm_getenv_int ("GUILE_JIT_LOG", 0);
  4155. }
  4156. #endif /* ENABLE_JIT */