jit.c 138 KB

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