jit.c 137 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841
  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_f64_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_DOUBLE, SP, 8 * slot);
  829. }
  830. static jit_operand_t
  831. sp_u64_operand (scm_jit_state *j, uint32_t slot)
  832. {
  833. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  834. return jit_operand_mem (JIT_OPERAND_ABI_UINT64, SP, 8 * slot);
  835. }
  836. #if SIZEOF_UINTPTR_T >= 8
  837. static void
  838. emit_sp_ref_u64 (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  839. {
  840. size_t offset = src * 8;
  841. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  842. emit_ldxi (j, dst, SP, offset);
  843. }
  844. static void
  845. emit_sp_set_u64 (scm_jit_state *j, uint32_t dst, jit_gpr_t src)
  846. {
  847. size_t offset = dst * 8;
  848. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  849. if (dst == 0)
  850. jit_str (j->jit, SP, src);
  851. else
  852. jit_stxi (j->jit, offset, SP, src);
  853. set_sp_cache_gpr (j, dst, src);
  854. }
  855. static void
  856. emit_sp_ref_s64 (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  857. {
  858. emit_sp_ref_u64 (j, dst, src);
  859. }
  860. static void
  861. emit_sp_set_s64 (scm_jit_state *j, uint32_t dst, jit_gpr_t src)
  862. {
  863. emit_sp_set_u64 (j, dst, src);
  864. }
  865. static void
  866. emit_sp_ref_ptr (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  867. {
  868. emit_sp_ref_u64 (j, dst, src);
  869. }
  870. #else /* SCM_SIZEOF_UINTPTR_T >= 8 */
  871. static jit_operand_t
  872. sp_s32_operand (scm_jit_state *j, uint32_t src)
  873. {
  874. return sp_sz_operand (j, src);
  875. }
  876. static void
  877. emit_sp_ref_s32 (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  878. {
  879. emit_sp_ref_sz (j, dst, src);
  880. }
  881. static void
  882. emit_sp_ref_u64 (scm_jit_state *j, jit_gpr_t dst_lo, jit_gpr_t dst_hi,
  883. uint32_t src)
  884. {
  885. size_t offset = src * 8;
  886. jit_gpr_t first, second;
  887. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  888. #if BIGENDIAN
  889. first = dst_hi, second = dst_lo;
  890. #else
  891. first = dst_lo, second = dst_hi;
  892. #endif
  893. emit_ldxi (j, first, SP, offset);
  894. emit_ldxi (j, second, SP, offset + 4);
  895. }
  896. static void
  897. emit_sp_set_u64 (scm_jit_state *j, uint32_t dst, jit_gpr_t lo, jit_gpr_t hi)
  898. {
  899. size_t offset = dst * 8;
  900. jit_gpr_t first, second;
  901. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  902. #if BIGENDIAN
  903. first = hi, second = lo;
  904. #else
  905. first = lo, second = hi;
  906. #endif
  907. if (offset == 0)
  908. jit_str (j->jit, SP, first);
  909. else
  910. jit_stxi (j->jit, offset, SP, first);
  911. jit_stxi (j->jit, offset + 4, SP, second);
  912. clear_register_state (j, SP_CACHE_GPR);
  913. }
  914. static void
  915. emit_sp_ref_s64 (scm_jit_state *j, jit_gpr_t dst_lo, jit_gpr_t dst_hi,
  916. uint32_t src)
  917. {
  918. emit_sp_ref_u64 (j, dst_lo, dst_hi, src);
  919. }
  920. static void
  921. emit_sp_set_s64 (scm_jit_state *j, uint32_t dst, jit_gpr_t lo, jit_gpr_t hi)
  922. {
  923. emit_sp_set_u64 (j, dst, lo, hi);
  924. }
  925. static void
  926. emit_sp_ref_u64_lower_half (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  927. {
  928. size_t offset = src * 8;
  929. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  930. emit_ldxi (j, dst, SP, offset);
  931. }
  932. static void
  933. emit_sp_ref_ptr (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
  934. {
  935. emit_sp_ref_u64_lower_half (j, dst, src);
  936. }
  937. #endif /* SCM_SIZEOF_UINTPTR_T >= 8 */
  938. static void
  939. emit_sp_ref_f64 (scm_jit_state *j, jit_fpr_t dst, uint32_t src)
  940. {
  941. size_t offset = src * 8;
  942. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  943. if (offset == 0)
  944. jit_ldr_d (j->jit, dst, SP);
  945. else
  946. jit_ldxi_d (j->jit, dst, SP, offset);
  947. record_fpr_clobber (j, dst);
  948. }
  949. static void
  950. emit_sp_set_f64 (scm_jit_state *j, uint32_t dst, jit_fpr_t src)
  951. {
  952. size_t offset = dst * 8;
  953. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  954. if (offset == 0)
  955. jit_str_d (j->jit, SP, src);
  956. else
  957. jit_stxi_d (j->jit, offset, SP, src);
  958. set_sp_cache_fpr (j, dst, src);
  959. }
  960. static void
  961. emit_mov (scm_jit_state *j, uint32_t dst, uint32_t src, jit_gpr_t t)
  962. {
  963. emit_sp_ref_scm (j, t, src);
  964. emit_sp_set_scm (j, dst, t);
  965. /* FIXME: The compiler currently emits "push", "mov", etc for SCM,
  966. F64, U64, and S64 variables. However SCM values are the usual
  967. case, and on a 32-bit machine it might be cheaper to move a SCM
  968. than to move a 64-bit number. */
  969. if (sizeof (void*) < sizeof (union scm_vm_stack_element))
  970. {
  971. /* Copy the high word as well. */
  972. uintptr_t src_offset = src * sizeof (union scm_vm_stack_element);
  973. uintptr_t dst_offset = dst * sizeof (union scm_vm_stack_element);
  974. jit_ldxi (j->jit, t, SP, src_offset + sizeof (void*));
  975. jit_stxi (j->jit, dst_offset + sizeof (void*), SP, t);
  976. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  977. }
  978. else
  979. /* In any case since we move the register using GPRs, it won't be in
  980. a cached FPR. */
  981. clear_register_state (j, SP_CACHE_FPR);
  982. }
  983. static jit_reloc_t
  984. emit_branch_if_frame_locals_count_less_than (scm_jit_state *j, jit_gpr_t t,
  985. uint32_t nlocals)
  986. {
  987. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  988. emit_subr (j, t, FP, SP);
  989. return jit_blti (j->jit, t, nlocals * sizeof (union scm_vm_stack_element));
  990. }
  991. static jit_reloc_t
  992. emit_branch_if_frame_locals_count_eq (scm_jit_state *j, jit_gpr_t t,
  993. uint32_t nlocals)
  994. {
  995. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  996. emit_subr (j, t, FP, SP);
  997. return jit_beqi (j->jit, t, nlocals * sizeof (union scm_vm_stack_element));
  998. }
  999. static jit_reloc_t
  1000. emit_branch_if_frame_locals_count_not_eq (scm_jit_state *j, jit_gpr_t t,
  1001. uint32_t nlocals)
  1002. {
  1003. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  1004. emit_subr (j, t, FP, SP);
  1005. return jit_bnei (j->jit, t, nlocals * sizeof (union scm_vm_stack_element));
  1006. }
  1007. static jit_reloc_t
  1008. emit_branch_if_frame_locals_count_greater_than (scm_jit_state *j, jit_gpr_t t,
  1009. uint32_t nlocals)
  1010. {
  1011. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  1012. emit_subr (j, t, FP, SP);
  1013. return jit_bgti (j->jit, t, nlocals * sizeof (union scm_vm_stack_element));
  1014. }
  1015. static void
  1016. emit_load_fp_slot (scm_jit_state *j, jit_gpr_t dst, uint32_t slot)
  1017. {
  1018. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER);
  1019. emit_subi (j, dst, FP, (slot + 1) * sizeof (union scm_vm_stack_element));
  1020. }
  1021. static jit_reloc_t
  1022. emit_branch_if_immediate (scm_jit_state *j, jit_gpr_t r)
  1023. {
  1024. return jit_bmsi (j->jit, r, 7); /* TAGS-SENSITIVE */
  1025. }
  1026. static void
  1027. emit_load_heap_object_word (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t r,
  1028. uint32_t word)
  1029. {
  1030. emit_ldxi (j, dst, r, word * sizeof(SCM));
  1031. }
  1032. static void
  1033. emit_load_heap_object_tc (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t r,
  1034. scm_t_bits mask)
  1035. {
  1036. emit_load_heap_object_word (j, dst, r, 0);
  1037. emit_andi (j, dst, dst, mask);
  1038. }
  1039. static jit_reloc_t
  1040. emit_branch_if_heap_object_has_tc (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
  1041. scm_t_bits mask, scm_t_bits tc)
  1042. {
  1043. emit_load_heap_object_tc (j, t, r, mask);
  1044. return jit_beqi (j->jit, t, tc);
  1045. }
  1046. static jit_reloc_t
  1047. emit_branch_if_heap_object_not_tc (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
  1048. scm_t_bits mask, scm_t_bits tc)
  1049. {
  1050. emit_load_heap_object_tc (j, t, r, mask);
  1051. return jit_bnei (j->jit, t, tc);
  1052. }
  1053. static jit_reloc_t
  1054. emit_branch_if_heap_object_not_tc11 (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
  1055. scm_t_bits tc11)
  1056. {
  1057. return emit_branch_if_heap_object_not_tc (j, r, t, 0x7ff, tc11);
  1058. }
  1059. static void
  1060. emit_entry_trampoline (scm_jit_state *j)
  1061. {
  1062. size_t align = jit_enter_jit_abi(j->jit, 3, 0, 0);
  1063. /* Load our reserved registers: THREAD and SP. Also load IP for the
  1064. mcode jump. */
  1065. jit_load_args_2 (j->jit, thread_operand (),
  1066. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T0));
  1067. emit_reload_sp (j);
  1068. /* Load FP, set during call sequences. */
  1069. emit_reload_fp (j);
  1070. /* Jump to the mcode! */
  1071. jit_jmpr (j->jit, T0);
  1072. /* Initialize global exit_mcode to point here. */
  1073. exit_mcode = jit_address (j->jit);
  1074. jit_leave_jit_abi(j->jit, 3, 0, align);
  1075. /* When mcode finishes, interpreter will continue with vp->ip. */
  1076. jit_ret (j->jit);
  1077. }
  1078. static void
  1079. emit_handle_interrupts_trampoline (scm_jit_state *j)
  1080. {
  1081. /* Precondition: IP synced, MRA in T0. */
  1082. emit_call_2 (j, scm_vm_intrinsics.push_interrupt_frame,
  1083. thread_operand (),
  1084. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T0));
  1085. emit_reload_sp (j);
  1086. emit_reload_fp (j);
  1087. emit_direct_tail_call (j, scm_vm_intrinsics.handle_interrupt_code);
  1088. }
  1089. /* To limit the number of mmap calls and re-emission of JIT code, use
  1090. 256 kB code arenas. Unused pages won't be resident. Assume pages
  1091. are power-of-two-sized and this size is a multiple of the page size
  1092. on all architectures. */
  1093. static const size_t default_code_arena_size = 0x40000;
  1094. static struct code_arena *
  1095. allocate_code_arena (size_t size, struct code_arena *prev)
  1096. {
  1097. struct code_arena *ret = malloc (sizeof (struct code_arena));
  1098. if (!ret) return NULL;
  1099. memset (ret, 0, sizeof (*ret));
  1100. ret->used = 0;
  1101. ret->size = size;
  1102. ret->prev = prev;
  1103. ret->base = mmap (NULL, ret->size,
  1104. PROT_EXEC | PROT_READ | PROT_WRITE,
  1105. MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  1106. if (ret->base == MAP_FAILED)
  1107. {
  1108. perror ("allocating JIT code buffer failed");
  1109. free (ret);
  1110. return NULL;
  1111. }
  1112. INFO ("allocated code arena, %p-%p\n", ret->base, ret->base + ret->size);
  1113. return ret;
  1114. }
  1115. static void *
  1116. emit_code (scm_jit_state *j, void (*emit) (scm_jit_state *))
  1117. {
  1118. if (!j->code_arena)
  1119. j->code_arena = allocate_code_arena (default_code_arena_size, NULL);
  1120. if (!j->code_arena)
  1121. /* Resource exhaustion; turn off JIT. */
  1122. return NULL;
  1123. while (1)
  1124. {
  1125. struct code_arena *arena = j->code_arena;
  1126. jit_begin(j->jit, arena->base + arena->used, arena->size - arena->used);
  1127. uint8_t *ret = jit_address (j->jit);
  1128. emit (j);
  1129. size_t size;
  1130. if (!jit_has_overflow (j->jit) && jit_end (j->jit, &size))
  1131. {
  1132. ASSERT (size <= (arena->size - arena->used));
  1133. DEBUG ("mcode: %p,+%zu\n", ret, size);
  1134. arena->used += size;
  1135. /* Align next JIT to 16-byte boundaries to optimize initial
  1136. icache fetch. */
  1137. arena->used = (arena->used + 15) & ~15;
  1138. /* Assertion should not be invalidated as arena size is a
  1139. multiple of 16. */
  1140. ASSERT (arena->used <= arena->size);
  1141. return ret;
  1142. }
  1143. else
  1144. {
  1145. jit_reset (j->jit);
  1146. if (arena->used == 0)
  1147. {
  1148. /* Code too big to fit into empty arena; allocate a larger
  1149. one. */
  1150. INFO ("code didn't fit in empty arena of size %zu\n", arena->size);
  1151. arena = allocate_code_arena (arena->size * 2, arena->prev);
  1152. if (!arena)
  1153. return NULL;
  1154. munmap (j->code_arena->base, j->code_arena->size);
  1155. free (j->code_arena);
  1156. j->code_arena = arena;
  1157. }
  1158. else
  1159. {
  1160. /* Arena full; allocate another. */
  1161. /* FIXME: If partial code that we wrote crosses a page
  1162. boundary, we could tell the OS to forget about the tail
  1163. pages. */
  1164. INFO ("code didn't fit in arena tail %zu\n",
  1165. arena->size - arena->used);
  1166. arena = allocate_code_arena (arena->size, arena);
  1167. if (!arena)
  1168. return NULL;
  1169. j->code_arena = arena;
  1170. }
  1171. }
  1172. }
  1173. }
  1174. static jit_operand_t
  1175. free_variable_operand (scm_jit_state *j, jit_gpr_t src, size_t n)
  1176. {
  1177. ptrdiff_t offset = (n + program_word_offset_free_variable) * sizeof(SCM);
  1178. return jit_operand_mem (JIT_OPERAND_ABI_POINTER, src, offset);
  1179. }
  1180. static void
  1181. add_inter_instruction_patch (scm_jit_state *j, jit_reloc_t reloc,
  1182. const uint32_t *target)
  1183. {
  1184. ASSERT (j->start <= target && target < j->end);
  1185. ptrdiff_t offset = target - j->start;
  1186. if (j->labels[offset])
  1187. {
  1188. jit_patch_there (j->jit, reloc, j->labels[offset]);
  1189. return;
  1190. }
  1191. if (j->reloc_idx >= j->reloc_count)
  1192. {
  1193. size_t count = j->reloc_count * 2;
  1194. if (!count) count = 10;
  1195. size_t size = sizeof(*j->relocs) * count;
  1196. ASSERT(size / sizeof(*j->relocs) == count);
  1197. struct pending_reloc *relocs = realloc (j->relocs, size);
  1198. if (relocs)
  1199. {
  1200. j->reloc_count = count;
  1201. j->relocs = relocs;
  1202. }
  1203. }
  1204. ASSERT (j->reloc_idx < j->reloc_count);
  1205. j->relocs[j->reloc_idx].reloc = reloc;
  1206. j->relocs[j->reloc_idx].target_vcode_offset = offset;
  1207. j->reloc_idx++;
  1208. }
  1209. static void
  1210. bad_instruction (scm_jit_state *j)
  1211. {
  1212. ASSERT (0);
  1213. }
  1214. static void
  1215. compile_halt (scm_jit_state *j)
  1216. {
  1217. bad_instruction (j);
  1218. }
  1219. static void
  1220. compile_call (scm_jit_state *j, uint32_t proc, uint32_t nlocals)
  1221. {
  1222. /* 2 = size of call inst */
  1223. jit_reloc_t mcont = emit_push_frame (j, proc, nlocals, j->ip + 2);
  1224. emit_indirect_tail_call (j);
  1225. jit_patch_here (j->jit, mcont);
  1226. reset_register_state (j, FP_IN_REGISTER | SP_IN_REGISTER);
  1227. j->frame_size = -1;
  1228. }
  1229. static void
  1230. compile_call_label (scm_jit_state *j, uint32_t proc, uint32_t nlocals, const uint32_t *vcode)
  1231. {
  1232. /* 2 = size of call-label inst */
  1233. jit_reloc_t mcont = emit_push_frame (j, proc, nlocals, j->ip + 3);
  1234. emit_direct_tail_call (j, vcode);
  1235. jit_patch_here (j->jit, mcont);
  1236. reset_register_state (j, FP_IN_REGISTER | SP_IN_REGISTER);
  1237. j->frame_size = -1;
  1238. }
  1239. static void
  1240. compile_tail_call (scm_jit_state *j)
  1241. {
  1242. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  1243. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1244. emit_indirect_tail_call (j);
  1245. j->frame_size = -1;
  1246. }
  1247. static void
  1248. compile_tail_call_label (scm_jit_state *j, const uint32_t *vcode)
  1249. {
  1250. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER);
  1251. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1252. emit_direct_tail_call (j, vcode);
  1253. j->frame_size = -1;
  1254. }
  1255. static void
  1256. compile_instrument_entry (scm_jit_state *j, void *data)
  1257. {
  1258. }
  1259. static void
  1260. compile_instrument_loop (scm_jit_state *j, void *data)
  1261. {
  1262. /* Nothing to do. */
  1263. }
  1264. static void
  1265. compile_receive (scm_jit_state *j, uint16_t dst, uint16_t proc, uint32_t nlocals)
  1266. {
  1267. jit_gpr_t t = T0;
  1268. jit_reloc_t k;
  1269. uint32_t saved_state = j->register_state;
  1270. k = emit_branch_if_frame_locals_count_greater_than (j, t, proc);
  1271. emit_store_current_ip (j, T0);
  1272. emit_call_0 (j, scm_vm_intrinsics.error_no_values);
  1273. j->register_state = saved_state;
  1274. jit_patch_here (j->jit, k);
  1275. emit_fp_ref_scm (j, t, proc);
  1276. emit_fp_set_scm (j, dst, t);
  1277. emit_reset_frame (j, nlocals);
  1278. j->frame_size = nlocals;
  1279. }
  1280. static void
  1281. compile_receive_values (scm_jit_state *j, uint32_t proc, uint8_t allow_extra,
  1282. uint32_t nvalues)
  1283. {
  1284. jit_gpr_t t = T0;
  1285. uint32_t saved_state = j->register_state;
  1286. if (allow_extra)
  1287. {
  1288. jit_reloc_t k;
  1289. k = emit_branch_if_frame_locals_count_greater_than (j, t, proc+nvalues-1);
  1290. emit_store_current_ip (j, T0);
  1291. emit_call_0 (j, scm_vm_intrinsics.error_not_enough_values);
  1292. j->register_state = saved_state;
  1293. jit_patch_here (j->jit, k);
  1294. }
  1295. else
  1296. {
  1297. jit_reloc_t k;
  1298. k = emit_branch_if_frame_locals_count_eq (j, t, proc + nvalues);
  1299. emit_store_current_ip (j, T0);
  1300. emit_call_1 (j, scm_vm_intrinsics.error_wrong_number_of_values,
  1301. jit_operand_imm (JIT_OPERAND_ABI_UINT32, nvalues));
  1302. j->register_state = saved_state;
  1303. jit_patch_here (j->jit, k);
  1304. j->frame_size = proc + nvalues;
  1305. }
  1306. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1307. }
  1308. static void
  1309. compile_shuffle_down (scm_jit_state *j, uint16_t from, uint16_t to)
  1310. {
  1311. jit_gpr_t walk = T0, t = T1;
  1312. size_t offset = (from - to) * sizeof (union scm_vm_stack_element);
  1313. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  1314. emit_load_fp_slot (j, walk, from);
  1315. jit_reloc_t done = jit_bltr (j->jit, walk, SP);
  1316. void *head = jit_address (j->jit);
  1317. jit_ldr (j->jit, t, walk);
  1318. jit_stxi (j->jit, offset, walk, t);
  1319. jit_subi (j->jit, walk, walk, sizeof (union scm_vm_stack_element));
  1320. jit_patch_there (j->jit, jit_bger (j->jit, walk, SP), head);
  1321. jit_patch_here (j->jit, done);
  1322. jit_addi (j->jit, SP, SP, offset);
  1323. emit_store_sp (j);
  1324. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1325. if (j->frame_size >= 0)
  1326. j->frame_size -= (from - to);
  1327. }
  1328. static void
  1329. compile_return_values (scm_jit_state *j)
  1330. {
  1331. jit_gpr_t old_fp = T0, ra = T1;
  1332. jit_reloc_t interp;
  1333. emit_pop_fp (j, old_fp);
  1334. emit_load_mra (j, ra, old_fp);
  1335. interp = jit_beqi (j->jit, ra, 0);
  1336. jit_jmpr (j->jit, ra);
  1337. jit_patch_here (j->jit, interp);
  1338. emit_load_vra (j, ra, old_fp);
  1339. emit_store_ip (j, ra);
  1340. emit_exit (j);
  1341. j->frame_size = -1;
  1342. }
  1343. static void
  1344. compile_subr_call (scm_jit_state *j, uint32_t idx)
  1345. {
  1346. jit_gpr_t t = T0, ret = T1;
  1347. void *subr;
  1348. jit_reloc_t immediate, not_values, k;
  1349. jit_operand_t args[10];
  1350. ASSERT (j->frame_size > 0);
  1351. size_t argc = j->frame_size - 1;
  1352. ASSERT (argc <= 10);
  1353. subr = scm_subr_function_by_index (idx);
  1354. emit_store_current_ip (j, t);
  1355. for (size_t i = 2; i <= j->frame_size; i++)
  1356. args[i - 2] = sp_scm_operand (j, (j->frame_size - i));
  1357. jit_calli (j->jit, subr, argc, args);
  1358. clear_scratch_register_state (j);
  1359. jit_retval (j->jit, ret);
  1360. immediate = emit_branch_if_immediate (j, ret);
  1361. not_values = emit_branch_if_heap_object_not_tc11 (j, ret, t, scm_tc11_values);
  1362. emit_call_2 (j, scm_vm_intrinsics.unpack_values_object, thread_operand (),
  1363. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, ret));
  1364. emit_reload_fp (j);
  1365. emit_reload_sp (j);
  1366. k = jit_jmp (j->jit);
  1367. jit_patch_here (j->jit, immediate);
  1368. jit_patch_here (j->jit, not_values);
  1369. emit_reload_fp (j);
  1370. emit_subtract_stack_slots (j, SP, FP, 1);
  1371. set_register_state (j, SP_IN_REGISTER);
  1372. emit_store_sp (j);
  1373. jit_str (j->jit, SP, ret);
  1374. jit_patch_here (j->jit, k);
  1375. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1376. j->frame_size = -1;
  1377. }
  1378. static void
  1379. compile_foreign_call (scm_jit_state *j, uint16_t cif_idx, uint16_t ptr_idx)
  1380. {
  1381. uint32_t saved_state;
  1382. ASSERT (j->frame_size >= 0);
  1383. emit_store_current_ip (j, T0);
  1384. emit_sp_ref_scm (j, T0, j->frame_size - 1);
  1385. /* FIXME: Inline the foreign call. */
  1386. saved_state = save_reloadable_register_state (j);
  1387. emit_call_3 (j, scm_vm_intrinsics.foreign_call, thread_operand (),
  1388. free_variable_operand (j, T0, cif_idx),
  1389. free_variable_operand (j, T0, ptr_idx));
  1390. restore_reloadable_register_state (j, saved_state);
  1391. j->frame_size = 2; /* Return value and errno. */
  1392. }
  1393. static void
  1394. compile_continuation_call (scm_jit_state *j, uint32_t contregs_idx)
  1395. {
  1396. emit_reload_fp (j);
  1397. emit_store_current_ip (j, T0);
  1398. emit_fp_ref_scm (j, T0, 0);
  1399. emit_call_2 (j, scm_vm_intrinsics.reinstate_continuation_x,
  1400. thread_operand (), free_variable_operand (j, T0, contregs_idx));
  1401. /* Does not fall through. */
  1402. j->frame_size = -1;
  1403. }
  1404. static void
  1405. compile_compose_continuation (scm_jit_state *j, uint32_t cont_idx)
  1406. {
  1407. jit_reloc_t interp;
  1408. ASSERT_HAS_REGISTER_STATE (SP_IN_REGISTER | FP_IN_REGISTER);
  1409. emit_store_current_ip (j, T0);
  1410. emit_fp_ref_scm (j, T0, 0);
  1411. emit_call_2 (j, scm_vm_intrinsics.compose_continuation,
  1412. thread_operand (), free_variable_operand (j, T0, cont_idx));
  1413. jit_retval (j->jit, T0);
  1414. interp = jit_beqi (j->jit, T0, 0);
  1415. emit_reload_sp (j);
  1416. emit_reload_fp (j);
  1417. jit_jmpr (j->jit, T0);
  1418. jit_patch_here (j->jit, interp);
  1419. emit_exit (j);
  1420. j->frame_size = -1;
  1421. }
  1422. static void
  1423. compile_capture_continuation (scm_jit_state *j, uint32_t dst)
  1424. {
  1425. emit_store_current_ip (j, T0);
  1426. emit_call_1 (j, scm_vm_intrinsics.capture_continuation, thread_operand ());
  1427. jit_retval (j->jit, T0);
  1428. emit_reload_sp (j);
  1429. emit_reload_fp (j);
  1430. emit_sp_set_scm (j, dst, T0);
  1431. }
  1432. static void
  1433. compile_abort (scm_jit_state *j)
  1434. {
  1435. jit_reloc_t k, interp;
  1436. jit_movi (j->jit, T0, (intptr_t) (j->ip + 1));
  1437. emit_store_ip (j, T0);
  1438. k = jit_mov_addr (j->jit, T0);
  1439. emit_call_2 (j, scm_vm_intrinsics.abort_to_prompt, thread_operand (),
  1440. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T0));
  1441. jit_retval (j->jit, T1_PRESERVED);
  1442. interp = jit_beqi (j->jit, T1_PRESERVED, 0);
  1443. emit_reload_sp (j);
  1444. emit_reload_fp (j);
  1445. jit_jmpr (j->jit, T1_PRESERVED);
  1446. jit_patch_here (j->jit, interp);
  1447. emit_exit (j);
  1448. jit_patch_here (j->jit, k);
  1449. j->frame_size = -1;
  1450. }
  1451. static void
  1452. compile_builtin_ref (scm_jit_state *j, uint16_t dst, uint16_t idx)
  1453. {
  1454. SCM builtin = scm_vm_builtin_ref (idx);
  1455. emit_movi (j, T0, SCM_UNPACK (builtin));
  1456. emit_sp_set_scm (j, dst, T0);
  1457. }
  1458. static void
  1459. compile_throw (scm_jit_state *j, uint16_t key, uint16_t args)
  1460. {
  1461. emit_store_current_ip (j, T0);
  1462. emit_call_2 (j, scm_vm_intrinsics.throw_, sp_scm_operand (j, key),
  1463. sp_scm_operand (j, args));
  1464. /* throw_ does not return. */
  1465. }
  1466. static void
  1467. compile_throw_value (scm_jit_state *j, uint32_t val,
  1468. const void *key_subr_and_message)
  1469. {
  1470. emit_store_current_ip (j, T0);
  1471. emit_call_2 (j, scm_vm_intrinsics.throw_with_value, sp_scm_operand (j, val),
  1472. jit_operand_imm (JIT_OPERAND_ABI_POINTER,
  1473. (intptr_t) key_subr_and_message));
  1474. /* throw_with_value does not return. */
  1475. }
  1476. static void
  1477. compile_throw_value_and_data (scm_jit_state *j, uint32_t val,
  1478. const void *key_subr_and_message)
  1479. {
  1480. emit_store_current_ip (j, T0);
  1481. emit_call_2 (j, scm_vm_intrinsics.throw_with_value_and_data,
  1482. sp_scm_operand (j, val),
  1483. jit_operand_imm (JIT_OPERAND_ABI_POINTER,
  1484. (intptr_t) key_subr_and_message));
  1485. /* throw_with_value_and_data does not return. */
  1486. }
  1487. static void
  1488. compile_assert_nargs_ee (scm_jit_state *j, uint32_t nlocals)
  1489. {
  1490. jit_reloc_t k;
  1491. jit_gpr_t t = T0;
  1492. uint32_t saved_state = j->register_state;
  1493. k = emit_branch_if_frame_locals_count_eq (j, t, nlocals);
  1494. emit_store_current_ip (j, t);
  1495. emit_call_1 (j, scm_vm_intrinsics.error_wrong_num_args,
  1496. thread_operand ());
  1497. jit_patch_here (j->jit, k);
  1498. j->register_state = saved_state;
  1499. j->frame_size = nlocals;
  1500. }
  1501. static void
  1502. compile_assert_nargs_ge (scm_jit_state *j, uint32_t nlocals)
  1503. {
  1504. if (nlocals > 0)
  1505. {
  1506. jit_gpr_t t = T0;
  1507. jit_reloc_t k;
  1508. uint32_t saved_state = j->register_state;
  1509. k = emit_branch_if_frame_locals_count_greater_than (j, t, nlocals-1);
  1510. emit_store_current_ip (j, t);
  1511. emit_call_1 (j, scm_vm_intrinsics.error_wrong_num_args,
  1512. thread_operand ());
  1513. jit_patch_here (j->jit, k);
  1514. j->register_state = saved_state;
  1515. }
  1516. }
  1517. static void
  1518. compile_assert_nargs_le (scm_jit_state *j, uint32_t nlocals)
  1519. {
  1520. jit_reloc_t k;
  1521. jit_gpr_t t = T0;
  1522. uint32_t saved_state = j->register_state;
  1523. k = emit_branch_if_frame_locals_count_less_than (j, t, nlocals + 1);
  1524. emit_store_current_ip (j, t);
  1525. emit_call_1 (j, scm_vm_intrinsics.error_wrong_num_args,
  1526. thread_operand ());
  1527. jit_patch_here (j->jit, k);
  1528. j->register_state = saved_state;
  1529. }
  1530. static void
  1531. compile_alloc_frame (scm_jit_state *j, uint32_t nlocals)
  1532. {
  1533. jit_gpr_t t = T0, saved_frame_size = T1_PRESERVED;
  1534. if (j->frame_size < 0)
  1535. jit_subr (j->jit, saved_frame_size, FP, SP);
  1536. /* This will clear the regalloc, so no need to track clobbers. */
  1537. emit_alloc_frame (j, t, nlocals);
  1538. if (j->frame_size >= 0)
  1539. {
  1540. int32_t slots = nlocals - j->frame_size;
  1541. if (slots > 0)
  1542. {
  1543. jit_movi (j->jit, t, SCM_UNPACK (SCM_UNDEFINED));
  1544. while (slots-- > 0)
  1545. emit_sp_set_scm (j, slots, t);
  1546. }
  1547. }
  1548. else
  1549. {
  1550. jit_gpr_t walk = saved_frame_size;
  1551. jit_subr (j->jit, walk, FP, saved_frame_size);
  1552. jit_reloc_t k = jit_bler (j->jit, walk, SP);
  1553. jit_movi (j->jit, t, SCM_UNPACK (SCM_UNDEFINED));
  1554. void *head = jit_address (j->jit);
  1555. jit_subi (j->jit, walk, walk, sizeof (union scm_vm_stack_element));
  1556. jit_str (j->jit, walk, t);
  1557. jit_patch_there (j->jit, jit_bner (j->jit, walk, SP), head);
  1558. jit_patch_here (j->jit, k);
  1559. }
  1560. j->frame_size = nlocals;
  1561. }
  1562. static void
  1563. compile_reset_frame (scm_jit_state *j, uint32_t nlocals)
  1564. {
  1565. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1566. emit_reset_frame (j, nlocals);
  1567. j->frame_size = nlocals;
  1568. }
  1569. static void
  1570. compile_push (scm_jit_state *j, uint32_t src)
  1571. {
  1572. jit_gpr_t t = T0;
  1573. jit_subi (j->jit, SP, SP, sizeof (union scm_vm_stack_element));
  1574. emit_alloc_frame_for_sp (j, t);
  1575. emit_mov (j, 0, src + 1, t);
  1576. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1577. if (j->frame_size >= 0)
  1578. j->frame_size++;
  1579. }
  1580. static void
  1581. compile_pop (scm_jit_state *j, uint32_t dst)
  1582. {
  1583. emit_mov (j, dst + 1, 0, T0);
  1584. jit_addi (j->jit, SP, SP, sizeof (union scm_vm_stack_element));
  1585. emit_store_sp (j);
  1586. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1587. if (j->frame_size >= 0)
  1588. j->frame_size--;
  1589. }
  1590. static void
  1591. compile_drop (scm_jit_state *j, uint32_t nvalues)
  1592. {
  1593. jit_addi (j->jit, SP, SP, nvalues * sizeof (union scm_vm_stack_element));
  1594. emit_store_sp (j);
  1595. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  1596. if (j->frame_size >= 0)
  1597. j->frame_size -= nvalues;
  1598. }
  1599. static void
  1600. compile_assert_nargs_ee_locals (scm_jit_state *j, uint16_t expected,
  1601. uint16_t nlocals)
  1602. {
  1603. compile_assert_nargs_ee (j, expected);
  1604. if (nlocals)
  1605. compile_alloc_frame (j, expected + nlocals);
  1606. }
  1607. static void
  1608. compile_expand_apply_argument (scm_jit_state *j)
  1609. {
  1610. emit_store_current_ip (j, T0);
  1611. emit_call_1 (j, scm_vm_intrinsics.expand_apply_argument, thread_operand ());
  1612. emit_reload_sp (j);
  1613. emit_reload_fp (j);
  1614. j->frame_size = -1;
  1615. }
  1616. static void
  1617. compile_bind_kwargs (scm_jit_state *j, uint32_t nreq, uint8_t flags,
  1618. uint32_t nreq_and_opt, uint32_t ntotal, const void *kw)
  1619. {
  1620. uint8_t allow_other_keys = flags & 0x1, has_rest = flags & 0x2;
  1621. jit_gpr_t t = T0, npositional = T1;
  1622. emit_store_current_ip (j, t);
  1623. emit_call_3 (j, scm_vm_intrinsics.compute_kwargs_npositional,
  1624. thread_operand (),
  1625. jit_operand_imm (JIT_OPERAND_ABI_UINT32, nreq),
  1626. jit_operand_imm (JIT_OPERAND_ABI_UINT32, nreq_and_opt - nreq));
  1627. jit_retval_i (j->jit, npositional);
  1628. jit_operand_t args[] =
  1629. { jit_operand_gpr (JIT_OPERAND_ABI_POINTER, THREAD),
  1630. jit_operand_gpr (JIT_OPERAND_ABI_UINT32, npositional),
  1631. jit_operand_imm (JIT_OPERAND_ABI_UINT32, ntotal),
  1632. jit_operand_imm (JIT_OPERAND_ABI_POINTER, (intptr_t)kw),
  1633. jit_operand_imm (JIT_OPERAND_ABI_UINT8, !has_rest),
  1634. jit_operand_imm (JIT_OPERAND_ABI_UINT8, allow_other_keys) };
  1635. jit_calli (j->jit, scm_vm_intrinsics.bind_kwargs, 6, args);
  1636. clear_scratch_register_state (j);
  1637. if (has_rest)
  1638. {
  1639. emit_call_2 (j, scm_vm_intrinsics.cons_rest, thread_operand (),
  1640. jit_operand_imm (JIT_OPERAND_ABI_UINT32, ntotal));
  1641. jit_retval (j->jit, t);
  1642. emit_reload_fp (j);
  1643. emit_fp_set_scm (j, nreq_and_opt, t);
  1644. }
  1645. else
  1646. emit_reload_fp (j);
  1647. emit_reset_frame (j, ntotal);
  1648. j->frame_size = ntotal;
  1649. }
  1650. static void
  1651. compile_bind_rest (scm_jit_state *j, uint32_t dst)
  1652. {
  1653. jit_reloc_t k, cons;
  1654. jit_gpr_t t = T1;
  1655. cons = emit_branch_if_frame_locals_count_greater_than (j, t, dst);
  1656. compile_alloc_frame (j, dst + 1);
  1657. emit_movi (j, t, SCM_UNPACK (SCM_EOL));
  1658. emit_sp_set_scm (j, 0, t);
  1659. k = jit_jmp (j->jit);
  1660. jit_patch_here (j->jit, cons);
  1661. emit_store_current_ip (j, t);
  1662. emit_call_2 (j, scm_vm_intrinsics.cons_rest, thread_operand (),
  1663. jit_operand_imm (JIT_OPERAND_ABI_UINT32, dst));
  1664. emit_retval (j, t);
  1665. compile_reset_frame (j, dst + 1);
  1666. emit_sp_set_scm (j, 0, t);
  1667. jit_patch_here (j->jit, k);
  1668. }
  1669. static void
  1670. compile_allocate_words (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1671. {
  1672. jit_gpr_t t = T0;
  1673. emit_store_current_ip (j, t);
  1674. emit_call_2 (j, scm_vm_intrinsics.allocate_words, thread_operand (),
  1675. sp_sz_operand (j, nwords));
  1676. emit_retval (j, t);
  1677. record_gpr_clobber (j, t);
  1678. emit_reload_sp (j);
  1679. emit_sp_set_scm (j, dst, t);
  1680. }
  1681. static void
  1682. compile_allocate_words_immediate (scm_jit_state *j, uint16_t dst, uint16_t nwords)
  1683. {
  1684. jit_gpr_t t = T0;
  1685. emit_store_current_ip (j, t);
  1686. emit_call_2 (j, scm_vm_intrinsics.allocate_words, thread_operand (),
  1687. jit_operand_imm (JIT_OPERAND_ABI_WORD, nwords));
  1688. emit_retval (j, t);
  1689. emit_reload_sp (j);
  1690. emit_sp_set_scm (j, dst, t);
  1691. }
  1692. static void
  1693. compile_scm_ref (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1694. {
  1695. emit_sp_ref_scm (j, T0, obj);
  1696. emit_sp_ref_sz (j, T1, idx);
  1697. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  1698. emit_ldxr (j, T0, T0, T1);
  1699. emit_sp_set_scm (j, dst, T0);
  1700. }
  1701. static void
  1702. compile_scm_set (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  1703. {
  1704. emit_sp_ref_scm (j, T0, obj);
  1705. emit_sp_ref_sz (j, T1, idx);
  1706. emit_sp_ref_scm (j, T2, val);
  1707. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  1708. jit_stxr (j->jit, T0, T1, T2);
  1709. }
  1710. static void
  1711. compile_scm_ref_tag (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t tag)
  1712. {
  1713. emit_sp_ref_scm (j, T0, obj);
  1714. emit_ldr (j, T0, T0);
  1715. emit_subi (j, T0, T0, tag);
  1716. emit_sp_set_scm (j, dst, T0);
  1717. }
  1718. static void
  1719. compile_scm_set_tag (scm_jit_state *j, uint8_t obj, uint8_t tag, uint8_t val)
  1720. {
  1721. emit_sp_ref_scm (j, T0, obj);
  1722. emit_sp_ref_scm (j, T1, val);
  1723. emit_addi (j, T1, T1, tag);
  1724. jit_str (j->jit, T0, T1);
  1725. }
  1726. static void
  1727. compile_scm_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1728. {
  1729. emit_sp_ref_scm (j, T0, obj);
  1730. emit_ldxi (j, T0, T0, idx * sizeof (SCM));
  1731. emit_sp_set_scm (j, dst, T0);
  1732. }
  1733. static void
  1734. compile_scm_set_immediate (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  1735. {
  1736. emit_sp_ref_scm (j, T0, obj);
  1737. emit_sp_ref_scm (j, T1, val);
  1738. jit_stxi (j->jit, idx * sizeof (SCM), T0, T1);
  1739. }
  1740. static void
  1741. compile_word_ref (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1742. {
  1743. emit_sp_ref_scm (j, T0, obj);
  1744. emit_sp_ref_sz (j, T1, idx);
  1745. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  1746. emit_ldxr (j, T0, T0, T1);
  1747. emit_sp_set_sz (j, dst, T0);
  1748. }
  1749. static void
  1750. compile_word_set (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  1751. {
  1752. emit_sp_ref_scm (j, T0, obj);
  1753. emit_sp_ref_sz (j, T1, idx);
  1754. emit_sp_ref_sz (j, T2, val);
  1755. emit_lshi (j, T1, T1, log2_sizeof_uintptr_t);
  1756. jit_stxr (j->jit, T0, T1, T2);
  1757. }
  1758. static void
  1759. compile_word_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1760. {
  1761. emit_sp_ref_scm (j, T0, obj);
  1762. emit_ldxi (j, T0, T0, idx * sizeof (SCM));
  1763. emit_sp_set_sz (j, dst, T0);
  1764. }
  1765. static void
  1766. compile_word_set_immediate (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  1767. {
  1768. emit_sp_ref_scm (j, T0, obj);
  1769. emit_sp_ref_sz (j, T1, val);
  1770. jit_stxi (j->jit, idx * sizeof (SCM), T0, T1);
  1771. }
  1772. static void
  1773. compile_pointer_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1774. {
  1775. emit_sp_ref_scm (j, T0, obj);
  1776. emit_ldxi (j, T0, T0, idx * sizeof (SCM));
  1777. emit_sp_set_scm (j, dst, T0);
  1778. }
  1779. static void
  1780. compile_pointer_set_immediate (scm_jit_state *j, uint8_t obj, uint8_t idx, uint8_t val)
  1781. {
  1782. emit_sp_ref_scm (j, T0, obj);
  1783. emit_sp_ref_scm (j, T1, val);
  1784. jit_stxi (j->jit, idx * sizeof (SCM), T0, T1);
  1785. }
  1786. static void
  1787. compile_tail_pointer_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
  1788. {
  1789. emit_sp_ref_scm (j, T0, obj);
  1790. emit_addi (j, T0, T0, idx * sizeof (SCM));
  1791. emit_sp_set_scm (j, dst, T0);
  1792. }
  1793. static void
  1794. compile_mov (scm_jit_state *j, uint16_t dst, uint16_t src)
  1795. {
  1796. emit_mov (j, dst, src, T0);
  1797. }
  1798. static void
  1799. compile_long_mov (scm_jit_state *j, uint32_t dst, uint32_t src)
  1800. {
  1801. emit_mov (j, dst, src, T0);
  1802. }
  1803. static void
  1804. compile_long_fmov (scm_jit_state *j, uint32_t dst, uint32_t src)
  1805. {
  1806. jit_gpr_t t = T0;
  1807. restore_reloadable_register_state (j, FP_IN_REGISTER);
  1808. emit_fp_ref_scm (j, t, src);
  1809. emit_fp_set_scm (j, dst, t);
  1810. }
  1811. static void
  1812. compile_call_scm_from_scm_scm (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  1813. {
  1814. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1815. int has_fast = 0;
  1816. jit_reloc_t fast;
  1817. jit_operand_t op_a = sp_scm_operand (j, a);
  1818. jit_operand_t op_b = sp_scm_operand (j, b);
  1819. switch ((enum scm_vm_intrinsic) idx)
  1820. {
  1821. case SCM_VM_INTRINSIC_ADD:
  1822. {
  1823. emit_sp_ref_scm (j, T0, a);
  1824. emit_sp_ref_scm (j, T1, b);
  1825. op_a = jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T0);
  1826. op_b = jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T1);
  1827. jit_subi (j->jit, T0, T0, scm_fixnum_tag);
  1828. jit_subi (j->jit, T2, T1, scm_fixnum_tag);
  1829. jit_orr (j->jit, T2, T2, T0); /* TAGS-SENSITIVE */
  1830. jit_reloc_t not_inum = jit_bmsi (j->jit, T2, scm_fixnum_tag_mask);
  1831. fast = jit_bxaddr (j->jit, T0, T1);
  1832. has_fast = 1;
  1833. /* Restore previous value before slow path. */
  1834. jit_subr (j->jit, T0, T0, T1);
  1835. jit_patch_here (j->jit, not_inum);
  1836. jit_addi (j->jit, T0, T0, scm_fixnum_tag);
  1837. break;
  1838. }
  1839. case SCM_VM_INTRINSIC_SUB:
  1840. {
  1841. emit_sp_ref_scm (j, T0, a);
  1842. emit_sp_ref_scm (j, T1, b);
  1843. op_a = jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T0);
  1844. op_b = jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T1);
  1845. jit_subi (j->jit, T1, T1, scm_fixnum_tag);
  1846. jit_subi (j->jit, T2, T0, scm_fixnum_tag);
  1847. jit_orr (j->jit, T2, T2, T1); /* TAGS-SENSITIVE */
  1848. jit_reloc_t not_inum = jit_bmsi (j->jit, T2, scm_fixnum_tag_mask);
  1849. fast = jit_bxsubr (j->jit, T0, T1);
  1850. has_fast = 1;
  1851. /* Restore previous values before slow path. */
  1852. jit_addr (j->jit, T0, T0, T1);
  1853. jit_patch_here (j->jit, not_inum);
  1854. jit_addi (j->jit, T1, T1, scm_fixnum_tag);
  1855. break;
  1856. }
  1857. default:
  1858. break;
  1859. }
  1860. emit_store_current_ip (j, T2);
  1861. emit_call_2 (j, intrinsic, op_a, op_b);
  1862. emit_retval (j, T0);
  1863. emit_reload_sp (j);
  1864. if (has_fast)
  1865. jit_patch_here (j->jit, fast);
  1866. emit_sp_set_scm (j, dst, T0);
  1867. }
  1868. static void
  1869. compile_call_scm_from_scm_uimm (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  1870. {
  1871. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1872. int has_fast = 0;
  1873. jit_reloc_t fast;
  1874. jit_operand_t op_a = sp_scm_operand (j, a);
  1875. jit_operand_t op_b = jit_operand_imm (JIT_OPERAND_ABI_UINT8, b);
  1876. switch ((enum scm_vm_intrinsic) idx)
  1877. {
  1878. case SCM_VM_INTRINSIC_ADD_IMMEDIATE:
  1879. {
  1880. emit_sp_ref_scm (j, T0, a);
  1881. op_a = jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T0);
  1882. scm_t_bits addend = b << scm_fixnum_tag_size;
  1883. jit_comr (j->jit, T1, T0); /* TAGS-SENSITIVE */
  1884. jit_reloc_t not_inum = jit_bmsi (j->jit, T1, scm_fixnum_tag_mask);
  1885. fast = jit_bxaddi (j->jit, T0, addend);
  1886. has_fast = 1;
  1887. /* Restore previous value before slow path. */
  1888. jit_subi (j->jit, T0, T0, addend);
  1889. jit_patch_here (j->jit, not_inum);
  1890. break;
  1891. }
  1892. case SCM_VM_INTRINSIC_SUB_IMMEDIATE:
  1893. {
  1894. emit_sp_ref_scm (j, T0, a);
  1895. op_a = jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T0);
  1896. scm_t_bits subtrahend = b << scm_fixnum_tag_size;
  1897. jit_comr (j->jit, T1, T0); /* TAGS-SENSITIVE */
  1898. jit_reloc_t not_inum = jit_bmsi (j->jit, T1, scm_fixnum_tag_mask);
  1899. fast = jit_bxsubi (j->jit, T0, subtrahend);
  1900. has_fast = 1;
  1901. /* Restore previous value before slow path. */
  1902. jit_addi (j->jit, T0, T0, subtrahend);
  1903. jit_patch_here (j->jit, not_inum);
  1904. break;
  1905. }
  1906. default:
  1907. break;
  1908. }
  1909. emit_store_current_ip (j, T1);
  1910. emit_call_2 (j, intrinsic, op_a, op_b);
  1911. emit_retval (j, T0);
  1912. emit_reload_sp (j);
  1913. if (has_fast)
  1914. jit_patch_here (j->jit, fast);
  1915. emit_sp_set_scm (j, dst, T0);
  1916. }
  1917. static void
  1918. compile_call_scm_sz_u32 (scm_jit_state *j, uint8_t a, uint8_t b, uint8_t c, uint32_t idx)
  1919. {
  1920. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1921. emit_store_current_ip (j, T0);
  1922. emit_call_3 (j, intrinsic, sp_scm_operand (j, a), sp_sz_operand (j, b),
  1923. sp_sz_operand (j, c));
  1924. emit_reload_sp (j);
  1925. }
  1926. static void
  1927. compile_call_scm_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  1928. {
  1929. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1930. emit_store_current_ip (j, T0);
  1931. emit_call_1 (j, intrinsic, sp_scm_operand (j, a));
  1932. emit_retval (j, T0);
  1933. emit_reload_sp (j);
  1934. emit_sp_set_scm (j, dst, T0);
  1935. }
  1936. static void
  1937. compile_call_f64_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  1938. {
  1939. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1940. emit_store_current_ip (j, T0);
  1941. emit_call_1 (j, intrinsic, sp_scm_operand (j, a));
  1942. emit_retval_d (j, JIT_F0);
  1943. emit_reload_sp (j);
  1944. emit_sp_set_f64 (j, dst, JIT_F0);
  1945. }
  1946. static void
  1947. compile_call_u64_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  1948. {
  1949. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  1950. emit_store_current_ip (j, T0);
  1951. #if INDIRECT_INT64_INTRINSICS
  1952. emit_call_2 (j, intrinsic, sp_slot_operand (j, dst), sp_scm_operand (j, a));
  1953. emit_reload_sp (j);
  1954. #else
  1955. emit_call_1 (j, intrinsic, sp_scm_operand (j, a));
  1956. emit_retval (j, T0);
  1957. emit_reload_sp (j);
  1958. emit_sp_set_u64 (j, dst, T0);
  1959. #endif
  1960. }
  1961. static void
  1962. compile_make_short_immediate (scm_jit_state *j, uint8_t dst, SCM a)
  1963. {
  1964. emit_movi (j, T0, SCM_UNPACK (a));
  1965. emit_sp_set_scm (j, dst, T0);
  1966. }
  1967. static void
  1968. compile_make_long_immediate (scm_jit_state *j, uint32_t dst, SCM a)
  1969. {
  1970. emit_movi (j, T0, SCM_UNPACK (a));
  1971. emit_sp_set_scm (j, dst, T0);
  1972. }
  1973. static void
  1974. compile_make_long_long_immediate (scm_jit_state *j, uint32_t dst, SCM a)
  1975. {
  1976. emit_movi (j, T0, SCM_UNPACK (a));
  1977. emit_sp_set_scm (j, dst, T0);
  1978. }
  1979. static void
  1980. compile_make_non_immediate (scm_jit_state *j, uint32_t dst, const void *data)
  1981. {
  1982. emit_movi (j, T0, (uintptr_t)data);
  1983. emit_sp_set_scm (j, dst, T0);
  1984. }
  1985. static void
  1986. compile_static_ref (scm_jit_state *j, uint32_t dst, void *loc)
  1987. {
  1988. emit_ldi (j, T0, loc);
  1989. emit_sp_set_scm (j, dst, T0);
  1990. }
  1991. static void
  1992. compile_static_set (scm_jit_state *j, uint32_t obj, void *loc)
  1993. {
  1994. emit_sp_ref_scm (j, T0, obj);
  1995. jit_sti (j->jit, loc, T0);
  1996. }
  1997. static void
  1998. compile_static_patch (scm_jit_state *j, void *dst, const void *src)
  1999. {
  2000. emit_movi (j, T0, (uintptr_t) src);
  2001. jit_sti (j->jit, dst, T0);
  2002. }
  2003. static void
  2004. compile_prompt (scm_jit_state *j, uint32_t tag, uint8_t escape_only_p,
  2005. uint32_t proc_slot, const uint32_t *vcode)
  2006. {
  2007. emit_store_current_ip (j, T0);
  2008. emit_reload_fp (j);
  2009. jit_subi (j->jit, FP, FP, proc_slot * sizeof (union scm_vm_stack_element));
  2010. jit_reloc_t mra = emit_mov_addr (j, T2);
  2011. jit_operand_t args[] =
  2012. { thread_operand (),
  2013. jit_operand_imm (JIT_OPERAND_ABI_UINT8, escape_only_p),
  2014. sp_scm_operand (j, tag),
  2015. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, FP),
  2016. jit_operand_imm (JIT_OPERAND_ABI_POINTER, (uintptr_t)vcode),
  2017. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T2) };
  2018. jit_calli (j->jit, scm_vm_intrinsics.push_prompt, 6, args);
  2019. clear_scratch_register_state (j);
  2020. emit_reload_sp (j);
  2021. emit_reload_fp (j);
  2022. add_inter_instruction_patch (j, mra, vcode);
  2023. }
  2024. static void
  2025. compile_load_label (scm_jit_state *j, uint32_t dst, const uint32_t *vcode)
  2026. {
  2027. emit_movi (j, T0, (uintptr_t) vcode);
  2028. #if SIZEOF_UINTPTR_T >= 8
  2029. emit_sp_set_u64 (j, dst, T0);
  2030. #else
  2031. emit_movi (j, T1, 0);
  2032. emit_sp_set_u64 (j, dst, T0, T1);
  2033. #endif
  2034. }
  2035. static void
  2036. compile_call_s64_from_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2037. {
  2038. compile_call_u64_from_scm (j, dst, a, idx);
  2039. }
  2040. static void
  2041. compile_call_scm_from_f64 (scm_jit_state *j, uint16_t dst, uint16_t src, uint32_t idx)
  2042. {
  2043. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2044. emit_store_current_ip (j, T0);
  2045. emit_call_1 (j, intrinsic, sp_f64_operand (j, src));
  2046. emit_retval (j, T0);
  2047. emit_reload_sp (j);
  2048. emit_sp_set_scm (j, dst, T0);
  2049. }
  2050. static void
  2051. compile_call_scm_from_u64 (scm_jit_state *j, uint16_t dst, uint16_t src, uint32_t idx)
  2052. {
  2053. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2054. emit_store_current_ip (j, T0);
  2055. #if INDIRECT_INT64_INTRINSICS
  2056. emit_call_1 (j, intrinsic, sp_slot_operand (j, src));
  2057. #else
  2058. emit_call_1 (j, intrinsic, sp_u64_operand (j, src));
  2059. #endif
  2060. emit_retval (j, T0);
  2061. emit_reload_sp (j);
  2062. emit_sp_set_scm (j, dst, T0);
  2063. }
  2064. static void
  2065. compile_call_scm_from_s64 (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t b)
  2066. {
  2067. compile_call_scm_from_u64 (j, dst, a, b);
  2068. }
  2069. static void
  2070. compile_tag_char (scm_jit_state *j, uint16_t dst, uint16_t src)
  2071. {
  2072. #if SIZEOF_UINTPTR_T >= 8
  2073. emit_sp_ref_u64 (j, T0, src);
  2074. #else
  2075. emit_sp_ref_u64_lower_half (j, T0, src);
  2076. #endif
  2077. emit_lshi (j, T0, T0, 8); /* TAGS-SENSITIVE */
  2078. emit_addi (j, T0, T0, scm_tc8_char);
  2079. emit_sp_set_scm (j, dst, T0);
  2080. }
  2081. static void
  2082. compile_untag_char (scm_jit_state *j, uint16_t dst, uint16_t src)
  2083. {
  2084. emit_sp_ref_scm (j, T0, src);
  2085. emit_rshi (j, T0, T0, 8); /* TAGS-SENSITIVE */
  2086. #if SIZEOF_UINTPTR_T >= 8
  2087. emit_sp_set_u64 (j, dst, T0);
  2088. #else
  2089. emit_movi (j, T1, 0);
  2090. emit_sp_set_u64 (j, dst, T0, T1);
  2091. #endif
  2092. }
  2093. static void
  2094. compile_atomic_scm_ref_immediate (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t offset)
  2095. {
  2096. emit_sp_ref_scm (j, T0, obj);
  2097. emit_addi (j, T0, T0, offset * sizeof (SCM));
  2098. jit_ldr_atomic (j->jit, T0, T0);
  2099. record_gpr_clobber (j, T0);
  2100. emit_sp_set_scm (j, dst, T0);
  2101. }
  2102. static void
  2103. compile_atomic_scm_set_immediate (scm_jit_state *j, uint8_t obj, uint8_t offset, uint8_t val)
  2104. {
  2105. emit_sp_ref_scm (j, T0, obj);
  2106. emit_sp_ref_scm (j, T1, val);
  2107. emit_addi (j, T0, T0, offset * sizeof (SCM));
  2108. jit_str_atomic (j->jit, T0, T1);
  2109. }
  2110. static void
  2111. compile_atomic_scm_swap_immediate (scm_jit_state *j, uint32_t dst, uint32_t obj, uint8_t offset, uint32_t val)
  2112. {
  2113. emit_sp_ref_scm (j, T0, obj);
  2114. emit_sp_ref_scm (j, T1, val);
  2115. emit_addi (j, T0, T0, offset * sizeof (SCM));
  2116. jit_swap_atomic (j->jit, T1, T0, T1);
  2117. record_gpr_clobber (j, T1);
  2118. emit_sp_set_scm (j, dst, T1);
  2119. }
  2120. static void
  2121. compile_atomic_scm_compare_and_swap_immediate (scm_jit_state *j, uint32_t dst,
  2122. uint32_t obj, uint8_t offset,
  2123. uint32_t expected, uint32_t desired)
  2124. {
  2125. emit_sp_ref_scm (j, T0, obj);
  2126. emit_sp_ref_scm (j, T1, expected);
  2127. emit_sp_ref_scm (j, T2, desired);
  2128. emit_addi (j, T0, T0, offset * sizeof (SCM));
  2129. jit_cas_atomic (j->jit, T1, T0, T1, T2);
  2130. record_gpr_clobber (j, T1);
  2131. emit_sp_set_scm (j, dst, T1);
  2132. }
  2133. static void
  2134. compile_call_thread_scm_scm (scm_jit_state *j, uint16_t a, uint16_t b, uint32_t idx)
  2135. {
  2136. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2137. emit_store_current_ip (j, T0);
  2138. emit_call_3 (j, intrinsic, thread_operand (), sp_scm_operand (j, a),
  2139. sp_scm_operand (j, b));
  2140. emit_reload_sp (j);
  2141. }
  2142. static void
  2143. compile_call_thread (scm_jit_state *j, uint32_t idx)
  2144. {
  2145. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2146. emit_store_current_ip (j, T0);
  2147. emit_call_1 (j, intrinsic, thread_operand ());
  2148. emit_reload_sp (j);
  2149. }
  2150. static void
  2151. compile_call_scm_from_thread_scm (scm_jit_state *j, uint16_t dst, uint16_t a, uint32_t idx)
  2152. {
  2153. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2154. emit_store_current_ip (j, T0);
  2155. emit_call_2 (j, intrinsic, thread_operand (), sp_scm_operand (j, a));
  2156. emit_retval (j, T0);
  2157. emit_reload_sp (j);
  2158. emit_sp_set_scm (j, dst, T0);
  2159. }
  2160. static void
  2161. compile_call_thread_scm (scm_jit_state *j, uint32_t a, uint32_t idx)
  2162. {
  2163. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2164. emit_store_current_ip (j, T0);
  2165. emit_call_2 (j, intrinsic, thread_operand (), sp_scm_operand (j, a));
  2166. emit_reload_sp (j);
  2167. }
  2168. static void
  2169. compile_call_scm_from_scm_u64 (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b, uint32_t idx)
  2170. {
  2171. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2172. emit_store_current_ip (j, T0);
  2173. #if INDIRECT_INT64_INTRINSICS
  2174. emit_call_2 (j, intrinsic, sp_scm_operand (j, a), sp_slot_operand (j, b));
  2175. #else
  2176. emit_call_2 (j, intrinsic, sp_scm_operand (j, a), sp_u64_operand (j, b));
  2177. #endif
  2178. emit_retval (j, T0);
  2179. emit_reload_sp (j);
  2180. emit_sp_set_scm (j, dst, T0);
  2181. }
  2182. static void
  2183. compile_call_scm_from_thread (scm_jit_state *j, uint32_t dst, uint32_t idx)
  2184. {
  2185. void *intrinsic = ((void **) &scm_vm_intrinsics)[idx];
  2186. emit_store_current_ip (j, T0);
  2187. emit_call_1 (j, intrinsic, thread_operand ());
  2188. emit_retval (j, T0);
  2189. emit_reload_sp (j);
  2190. emit_sp_set_scm (j, dst, T0);
  2191. }
  2192. static void
  2193. compile_fadd (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2194. {
  2195. emit_sp_ref_f64 (j, JIT_F0, a);
  2196. emit_sp_ref_f64 (j, JIT_F1, b);
  2197. emit_addr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2198. emit_sp_set_f64 (j, dst, JIT_F0);
  2199. }
  2200. static void
  2201. compile_fsub (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2202. {
  2203. emit_sp_ref_f64 (j, JIT_F0, a);
  2204. emit_sp_ref_f64 (j, JIT_F1, b);
  2205. emit_subr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2206. emit_sp_set_f64 (j, dst, JIT_F0);
  2207. }
  2208. static void
  2209. compile_fmul (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2210. {
  2211. emit_sp_ref_f64 (j, JIT_F0, a);
  2212. emit_sp_ref_f64 (j, JIT_F1, b);
  2213. emit_mulr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2214. emit_sp_set_f64 (j, dst, JIT_F0);
  2215. }
  2216. static void
  2217. compile_fdiv (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2218. {
  2219. emit_sp_ref_f64 (j, JIT_F0, a);
  2220. emit_sp_ref_f64 (j, JIT_F1, b);
  2221. emit_divr_d (j, JIT_F0, JIT_F0, JIT_F1);
  2222. emit_sp_set_f64 (j, dst, JIT_F0);
  2223. }
  2224. static void
  2225. compile_uadd (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2226. {
  2227. #if SIZEOF_UINTPTR_T >= 8
  2228. emit_sp_ref_u64 (j, T0, a);
  2229. emit_sp_ref_u64 (j, T1, b);
  2230. emit_addr (j, T0, T0, T1);
  2231. emit_sp_set_u64 (j, dst, T0);
  2232. #else
  2233. emit_sp_ref_u64 (j, T0, T1, a);
  2234. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2235. emit_addcr (j, T0, T0, T2);
  2236. emit_addxr (j, T1, T1, T3_OR_FP);
  2237. emit_sp_set_u64 (j, dst, T0, T1);
  2238. #endif
  2239. }
  2240. static void
  2241. compile_usub (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2242. {
  2243. #if SIZEOF_UINTPTR_T >= 8
  2244. emit_sp_ref_u64 (j, T0, a);
  2245. emit_sp_ref_u64 (j, T1, b);
  2246. emit_subr (j, T0, T0, T1);
  2247. emit_sp_set_u64 (j, dst, T0);
  2248. #else
  2249. emit_sp_ref_u64 (j, T0, T1, a);
  2250. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2251. emit_subcr (j, T0, T0, T2);
  2252. emit_subxr (j, T1, T1, T3_OR_FP);
  2253. emit_sp_set_u64 (j, dst, T0, T1);
  2254. #endif
  2255. }
  2256. static void
  2257. compile_umul (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2258. {
  2259. #if SIZEOF_UINTPTR_T >= 8
  2260. emit_sp_ref_u64 (j, T0, a);
  2261. emit_sp_ref_u64 (j, T1, b);
  2262. emit_mulr (j, T0, T0, T1);
  2263. emit_sp_set_u64 (j, dst, T0);
  2264. #else
  2265. /* FIXME: This is untested! */
  2266. emit_sp_ref_u64 (j, T0, T1, a);
  2267. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2268. emit_mulr (j, T1, T1, T2); /* High A times low B */
  2269. emit_mulr (j, T3_OR_FP, T3_OR_FP, T0); /* High B times low A */
  2270. emit_addr (j, T1, T1, T3_OR_FP); /* Add high results, throw away overflow */
  2271. emit_qmulr_u (j, T0, T2, T0, T2); /* Low A times low B */
  2272. emit_addr (j, T1, T1, T2); /* Add high result of low product */
  2273. emit_sp_set_u64 (j, dst, T0, T1);
  2274. #endif
  2275. }
  2276. static void
  2277. compile_uadd_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2278. {
  2279. #if SIZEOF_UINTPTR_T >= 8
  2280. emit_sp_ref_u64 (j, T0, a);
  2281. emit_addi (j, T0, T0, b);
  2282. emit_sp_set_u64 (j, dst, T0);
  2283. #else
  2284. emit_sp_ref_u64 (j, T0, T1, a);
  2285. emit_addci (j, T0, T0, b);
  2286. emit_addxi (j, T1, T1, 0);
  2287. emit_sp_set_u64 (j, dst, T0, T1);
  2288. #endif
  2289. }
  2290. static void
  2291. compile_usub_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2292. {
  2293. #if SIZEOF_UINTPTR_T >= 8
  2294. emit_sp_ref_u64 (j, T0, a);
  2295. emit_subi (j, T0, T0, b);
  2296. emit_sp_set_u64 (j, dst, T0);
  2297. #else
  2298. emit_sp_ref_u64 (j, T0, T1, a);
  2299. emit_subci (j, T0, T0, b);
  2300. emit_subxi (j, T1, T1, 0);
  2301. emit_sp_set_u64 (j, dst, T0, T1);
  2302. #endif
  2303. }
  2304. static void
  2305. compile_umul_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2306. {
  2307. #if SIZEOF_UINTPTR_T >= 8
  2308. emit_sp_ref_u64 (j, T0, a);
  2309. emit_muli (j, T0, T0, b);
  2310. emit_sp_set_u64 (j, dst, T0);
  2311. #else
  2312. /* FIXME: This is untested! */
  2313. emit_sp_ref_u64 (j, T0, T1, a);
  2314. emit_muli (j, T1, T1, b); /* High A times low B */
  2315. /* High B times low A is 0. */
  2316. emit_movi (j, T2, b);
  2317. emit_qmulr_u (j, T0, T2, T0, T2); /* Low A times low B */
  2318. emit_addr (j, T1, T1, T2); /* Add high result of low product */
  2319. emit_sp_set_u64 (j, dst, T0, T1);
  2320. #endif
  2321. }
  2322. static void
  2323. compile_load_f64 (scm_jit_state *j, uint32_t dst, double a)
  2324. {
  2325. jit_movi_d (j->jit, JIT_F0, a);
  2326. record_fpr_clobber (j, JIT_F0);
  2327. emit_sp_set_f64 (j, dst, JIT_F0);
  2328. }
  2329. static void
  2330. compile_load_u64 (scm_jit_state *j, uint32_t dst, uint64_t a)
  2331. {
  2332. #if SIZEOF_UINTPTR_T >= 8
  2333. emit_movi (j, T0, a);
  2334. emit_sp_set_u64 (j, dst, T0);
  2335. #else
  2336. emit_movi (j, T0, a & 0xffffffff);
  2337. emit_movi (j, T1, a >> 32);
  2338. emit_sp_set_u64 (j, dst, T0, T1);
  2339. #endif
  2340. }
  2341. static void
  2342. compile_load_s64 (scm_jit_state *j, uint32_t dst, int64_t a)
  2343. {
  2344. compile_load_u64 (j, dst, a);
  2345. }
  2346. static void
  2347. compile_current_thread (scm_jit_state *j, uint32_t dst)
  2348. {
  2349. emit_ldxi (j, T0, THREAD, thread_offset_handle);
  2350. emit_sp_set_scm (j, dst, T0);
  2351. }
  2352. static void
  2353. compile_ulogand (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2354. {
  2355. #if SIZEOF_UINTPTR_T >= 8
  2356. emit_sp_ref_u64 (j, T0, a);
  2357. emit_sp_ref_u64 (j, T1, b);
  2358. emit_andr (j, T0, T0, T1);
  2359. emit_sp_set_u64 (j, dst, T0);
  2360. #else
  2361. emit_sp_ref_u64 (j, T0, T1, a);
  2362. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2363. emit_andr (j, T0, T0, T2);
  2364. emit_andr (j, T1, T1, T3_OR_FP);
  2365. emit_sp_set_u64 (j, dst, T0, T1);
  2366. #endif
  2367. }
  2368. static void
  2369. compile_ulogior (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2370. {
  2371. #if SIZEOF_UINTPTR_T >= 8
  2372. emit_sp_ref_u64 (j, T0, a);
  2373. emit_sp_ref_u64 (j, T1, b);
  2374. emit_orr (j, T0, T0, T1);
  2375. emit_sp_set_u64 (j, dst, T0);
  2376. #else
  2377. emit_sp_ref_u64 (j, T0, T1, a);
  2378. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2379. emit_orr (j, T0, T0, T2);
  2380. emit_orr (j, T1, T1, T3_OR_FP);
  2381. emit_sp_set_u64 (j, dst, T0, T1);
  2382. #endif
  2383. }
  2384. static void
  2385. compile_ulogsub (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2386. {
  2387. #if SIZEOF_UINTPTR_T >= 8
  2388. emit_sp_ref_u64 (j, T0, a);
  2389. emit_sp_ref_u64 (j, T1, b);
  2390. emit_comr (j, T1, T1);
  2391. emit_andr (j, T0, T0, T1);
  2392. emit_sp_set_u64 (j, dst, T0);
  2393. #else
  2394. emit_sp_ref_u64 (j, T0, T1, a);
  2395. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2396. emit_comr (j, T2, T2);
  2397. emit_comr (j, T3_OR_FP, T3_OR_FP);
  2398. emit_andr (j, T0, T0, T2);
  2399. emit_andr (j, T1, T1, T3_OR_FP);
  2400. emit_sp_set_u64 (j, dst, T0, T1);
  2401. #endif
  2402. }
  2403. static void
  2404. compile_ursh (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2405. {
  2406. #if SIZEOF_UINTPTR_T >= 8
  2407. emit_sp_ref_u64 (j, T0, a);
  2408. emit_sp_ref_u64 (j, T1, b);
  2409. emit_andi (j, T1, T1, 63);
  2410. emit_rshr_u (j, T0, T0, T1);
  2411. emit_sp_set_u64 (j, dst, T0);
  2412. #else
  2413. /* FIXME: Not tested. */
  2414. jit_reloc_t zero, both, done;
  2415. emit_sp_ref_u64 (j, T0, T1, a);
  2416. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2417. emit_andi (j, T2, T2, 63);
  2418. zero = jit_beqi (j->jit, T2, 0);
  2419. both = jit_blti (j->jit, T2, 32);
  2420. /* 32 <= s < 64: hi = 0, lo = hi >> (s-32) */
  2421. emit_subi (j, T2, T2, 32);
  2422. emit_rshr_u (j, T0, T1, T2);
  2423. emit_movi (j, T1, 0);
  2424. done = jit_jmp (j->jit);
  2425. jit_patch_here (j->jit, both);
  2426. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  2427. emit_negr (j, T3_OR_FP, T2);
  2428. emit_addi (j, T3_OR_FP, T3_OR_FP, 32);
  2429. emit_lshr (j, T3_OR_FP, T1, T3_OR_FP);
  2430. emit_rshr_u (j, T1, T1, T2);
  2431. emit_rshr_u (j, T0, T0, T2);
  2432. emit_addr (j, T0, T0, T3_OR_FP);
  2433. jit_patch_here (j->jit, done);
  2434. jit_patch_here (j->jit, zero);
  2435. emit_sp_set_u64 (j, dst, T0, T1);
  2436. #endif
  2437. }
  2438. static void
  2439. compile_ulsh (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2440. {
  2441. #if SIZEOF_UINTPTR_T >= 8
  2442. emit_sp_ref_u64 (j, T0, a);
  2443. emit_sp_ref_u64 (j, T1, b);
  2444. emit_andi (j, T1, T1, 63);
  2445. emit_lshr (j, T0, T0, T1);
  2446. emit_sp_set_u64 (j, dst, T0);
  2447. #else
  2448. /* FIXME: Not tested. */
  2449. jit_reloc_t zero, both, done;
  2450. emit_sp_ref_u64 (j, T0, T1, a);
  2451. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2452. emit_andi (j, T2, T2, 63);
  2453. zero = jit_beqi (j->jit, T2, 0);
  2454. both = jit_blti (j->jit, T2, 32);
  2455. /* 32 <= s < 64: hi = lo << (s-32), lo = 0 */
  2456. emit_subi (j, T2, T2, 32);
  2457. emit_lshr (j, T1, T0, T2);
  2458. emit_movi (j, T0, 0);
  2459. done = jit_jmp (j->jit);
  2460. jit_patch_here (j->jit, both);
  2461. /* 0 < s < 32: hi = hi << s + lo >> (32-s), lo = lo << s */
  2462. emit_negr (j, T3_OR_FP, T2);
  2463. emit_addi (j, T3_OR_FP, T3_OR_FP, 32);
  2464. emit_rshr_u (j, T3_OR_FP, T0, T3_OR_FP);
  2465. emit_lshr (j, T1, T1, T2);
  2466. emit_lshr (j, T0, T0, T2);
  2467. emit_addr (j, T1, T1, T3_OR_FP);
  2468. jit_patch_here (j->jit, done);
  2469. jit_patch_here (j->jit, zero);
  2470. emit_sp_set_u64 (j, dst, T0, T1);
  2471. #endif
  2472. }
  2473. static void
  2474. compile_ursh_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2475. {
  2476. b &= 63;
  2477. #if SIZEOF_UINTPTR_T >= 8
  2478. emit_sp_ref_u64 (j, T0, a);
  2479. emit_rshi_u (j, T0, T0, b);
  2480. emit_sp_set_u64 (j, dst, T0);
  2481. #else
  2482. /* FIXME: Not tested. */
  2483. emit_sp_ref_u64 (j, T0, T1, a);
  2484. if (b == 0)
  2485. {
  2486. /* Nothing to do. */
  2487. }
  2488. else if (b < 32)
  2489. {
  2490. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  2491. emit_lshi (j, T2, T1, 32 - b);
  2492. emit_rshi_u (j, T1, T1, b);
  2493. emit_rshi_u (j, T0, T0, b);
  2494. emit_addr (j, T0, T0, T2);
  2495. }
  2496. else if (b == 32)
  2497. {
  2498. /* hi = 0, lo = hi */
  2499. emit_movr (j, T0, T1);
  2500. emit_movi (j, T1, 0);
  2501. }
  2502. else /* b > 32 */
  2503. {
  2504. /* hi = 0, lo = hi >> (s-32) */
  2505. emit_rshi_u (j, T0, T1, b - 32);
  2506. emit_movi (j, T1, 0);
  2507. }
  2508. emit_sp_set_u64 (j, dst, T0, T1);
  2509. #endif
  2510. }
  2511. static void
  2512. compile_ulsh_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2513. {
  2514. b &= 63;
  2515. #if SIZEOF_UINTPTR_T >= 8
  2516. emit_sp_ref_u64 (j, T0, a);
  2517. emit_lshi (j, T0, T0, b);
  2518. emit_sp_set_u64 (j, dst, T0);
  2519. #else
  2520. /* FIXME: Not tested. */
  2521. emit_sp_ref_u64 (j, T0, T1, a);
  2522. if (b == 0)
  2523. {
  2524. /* Nothing to do. */
  2525. }
  2526. else if (b < 32)
  2527. {
  2528. /* hi = hi << s + lo >> (32-s), lo = lo << s */
  2529. emit_rshi_u (j, T2, T0, 32 - b);
  2530. emit_lshi (j, T1, T1, b);
  2531. emit_lshi (j, T0, T0, b);
  2532. emit_addr (j, T1, T1, T2);
  2533. }
  2534. else if (b == 32)
  2535. {
  2536. /* hi = lo, lo = 0 */
  2537. emit_movr (j, T1, T0);
  2538. emit_movi (j, T0, 0);
  2539. }
  2540. else /* b > 32 */
  2541. {
  2542. /* hi = lo << (s-32), lo = 0 */
  2543. emit_lshi (j, T1, T0, b - 32);
  2544. emit_movi (j, T0, 0);
  2545. }
  2546. emit_sp_set_u64 (j, dst, T0, T1);
  2547. #endif
  2548. }
  2549. static void
  2550. compile_ulogxor (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  2551. {
  2552. #if SIZEOF_UINTPTR_T >= 8
  2553. emit_sp_ref_u64 (j, T0, a);
  2554. emit_sp_ref_u64 (j, T1, b);
  2555. emit_xorr (j, T0, T0, T1);
  2556. emit_sp_set_u64 (j, dst, T0);
  2557. #else
  2558. emit_sp_ref_u64 (j, T0, T1, a);
  2559. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2560. emit_xorr (j, T0, T0, T2);
  2561. emit_xorr (j, T1, T1, T3_OR_FP);
  2562. emit_sp_set_u64 (j, dst, T0, T1);
  2563. #endif
  2564. }
  2565. static void
  2566. compile_handle_interrupts (scm_jit_state *j)
  2567. {
  2568. uint32_t saved_state = save_reloadable_register_state (j);
  2569. /* This instruction invalidates SP_CACHE_GPR / SP_CACHE_FPR. */
  2570. void *again = jit_address (j->jit);
  2571. jit_addi (j->jit, T0, THREAD, thread_offset_pending_asyncs);
  2572. jit_ldr_atomic (j->jit, T0, T0);
  2573. jit_reloc_t none_pending = jit_beqi (j->jit, T0, SCM_UNPACK (SCM_EOL));
  2574. jit_ldxi_i (j->jit, T0, THREAD, thread_offset_block_asyncs);
  2575. jit_reloc_t blocked = jit_bnei (j->jit, T0, 0);
  2576. emit_store_current_ip (j, T0);
  2577. emit_movi (j, T0, (uintptr_t)again);
  2578. jit_jmpi (j->jit, handle_interrupts_trampoline);
  2579. jit_patch_here (j->jit, none_pending);
  2580. jit_patch_here (j->jit, blocked);
  2581. j->register_state = saved_state;
  2582. }
  2583. static void
  2584. compile_return_from_interrupt (scm_jit_state *j)
  2585. {
  2586. jit_gpr_t old_fp = T0, ra = T1;
  2587. jit_reloc_t interp;
  2588. emit_pop_fp (j, old_fp);
  2589. emit_load_mra (j, ra, old_fp);
  2590. interp = jit_beqi (j->jit, ra, 0);
  2591. jit_addi (j->jit, SP, old_fp, frame_overhead_slots * sizeof (union scm_vm_stack_element));
  2592. set_register_state (j, SP_IN_REGISTER);
  2593. emit_store_sp (j);
  2594. jit_jmpr (j->jit, ra);
  2595. jit_patch_here (j->jit, interp);
  2596. emit_load_vra (j, ra, old_fp);
  2597. emit_store_ip (j, ra);
  2598. jit_addi (j->jit, SP, old_fp, frame_overhead_slots * sizeof (union scm_vm_stack_element));
  2599. set_register_state (j, SP_IN_REGISTER);
  2600. emit_store_sp (j);
  2601. emit_exit (j);
  2602. clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
  2603. }
  2604. static enum scm_opcode
  2605. fuse_conditional_branch (scm_jit_state *j, uint32_t **target)
  2606. {
  2607. uint8_t next = j->next_ip[0] & 0xff;
  2608. switch (next)
  2609. {
  2610. case scm_op_jl:
  2611. case scm_op_je:
  2612. case scm_op_jnl:
  2613. case scm_op_jne:
  2614. case scm_op_jge:
  2615. case scm_op_jnge:
  2616. *target = j->next_ip + (((int32_t) j->next_ip[0]) >> 8);
  2617. j->next_ip += op_lengths[next];
  2618. return next;
  2619. default:
  2620. ASSERT (0);
  2621. }
  2622. }
  2623. static void
  2624. compile_u64_numerically_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  2625. {
  2626. uint32_t *target;
  2627. #if SIZEOF_UINTPTR_T >= 8
  2628. jit_reloc_t k;
  2629. emit_sp_ref_u64 (j, T0, a);
  2630. emit_sp_ref_u64 (j, T1, b);
  2631. switch (fuse_conditional_branch (j, &target))
  2632. {
  2633. case scm_op_je:
  2634. k = jit_beqr (j->jit, T0, T1);
  2635. break;
  2636. case scm_op_jne:
  2637. k = jit_bner (j->jit, T0, T1);
  2638. break;
  2639. default:
  2640. UNREACHABLE ();
  2641. }
  2642. add_inter_instruction_patch (j, k, target);
  2643. #else
  2644. jit_reloc_t k1, k2;
  2645. emit_sp_ref_u64 (j, T0, T1, a);
  2646. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2647. switch (fuse_conditional_branch (j, &target))
  2648. {
  2649. case scm_op_je:
  2650. k1 = jit_bner (j->jit, T0, T2);
  2651. k2 = jit_beqr (j->jit, T1, T3_OR_FP);
  2652. jit_patch_here (j->jit, k1);
  2653. add_inter_instruction_patch (j, k2, target);
  2654. break;
  2655. case scm_op_jne:
  2656. k1 = jit_bner (j->jit, T0, T2);
  2657. k2 = jit_bner (j->jit, T1, T3_OR_FP);
  2658. add_inter_instruction_patch (j, k1, target);
  2659. add_inter_instruction_patch (j, k2, target);
  2660. break;
  2661. default:
  2662. UNREACHABLE ();
  2663. }
  2664. #endif
  2665. }
  2666. static void
  2667. compile_u64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  2668. {
  2669. uint32_t *target;
  2670. #if SIZEOF_UINTPTR_T >= 8
  2671. jit_reloc_t k;
  2672. emit_sp_ref_u64 (j, T0, a);
  2673. emit_sp_ref_u64 (j, T1, b);
  2674. switch (fuse_conditional_branch (j, &target))
  2675. {
  2676. case scm_op_jl:
  2677. k = jit_bltr_u (j->jit, T0, T1);
  2678. break;
  2679. case scm_op_jnl:
  2680. k = jit_bger_u (j->jit, T0, T1);
  2681. break;
  2682. default:
  2683. UNREACHABLE ();
  2684. }
  2685. add_inter_instruction_patch (j, k, target);
  2686. #else
  2687. jit_reloc_t k1, k2, k3;
  2688. emit_sp_ref_u64 (j, T0, T1, a);
  2689. emit_sp_ref_u64 (j, T2, T3_OR_FP, b);
  2690. k1 = jit_bltr_u (j->jit, T1, T3_OR_FP);
  2691. k2 = jit_bner (j->jit, T1, T3_OR_FP);
  2692. switch (fuse_conditional_branch (j, &target))
  2693. {
  2694. case scm_op_jl:
  2695. k3 = jit_bltr_u (j->jit, T0, T2);
  2696. jit_patch_here (j->jit, k2);
  2697. add_inter_instruction_patch (j, k1, target);
  2698. add_inter_instruction_patch (j, k3, target);
  2699. break;
  2700. case scm_op_jnl:
  2701. k3 = jit_bger_u (j->jit, T0, T2);
  2702. jit_patch_here (j->jit, k1);
  2703. add_inter_instruction_patch (j, k2, target);
  2704. add_inter_instruction_patch (j, k3, target);
  2705. break;
  2706. default:
  2707. UNREACHABLE ();
  2708. }
  2709. #endif
  2710. }
  2711. static void
  2712. compile_s64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  2713. {
  2714. uint32_t *target;
  2715. #if SIZEOF_UINTPTR_T >= 8
  2716. jit_reloc_t k;
  2717. emit_sp_ref_s64 (j, T0, a);
  2718. emit_sp_ref_s64 (j, T1, b);
  2719. switch (fuse_conditional_branch (j, &target))
  2720. {
  2721. case scm_op_jl:
  2722. k = jit_bltr (j->jit, T0, T1);
  2723. break;
  2724. case scm_op_jnl:
  2725. k = jit_bger (j->jit, T0, T1);
  2726. break;
  2727. default:
  2728. UNREACHABLE ();
  2729. }
  2730. add_inter_instruction_patch (j, k, target);
  2731. #else
  2732. jit_reloc_t k1, k2, k3;
  2733. emit_sp_ref_s64 (j, T0, T1, a);
  2734. emit_sp_ref_s64 (j, T2, T3_OR_FP, b);
  2735. k1 = jit_bltr (j->jit, T1, T3_OR_FP);
  2736. k2 = jit_bner (j->jit, T1, T3_OR_FP);
  2737. switch (fuse_conditional_branch (j, &target))
  2738. {
  2739. case scm_op_jl:
  2740. k3 = jit_bltr (j->jit, T0, T2);
  2741. jit_patch_here (j->jit, k2);
  2742. add_inter_instruction_patch (j, k1, target);
  2743. add_inter_instruction_patch (j, k3, target);
  2744. break;
  2745. case scm_op_jnl:
  2746. k3 = jit_bger (j->jit, T0, T2);
  2747. jit_patch_here (j->jit, k1);
  2748. add_inter_instruction_patch (j, k2, target);
  2749. add_inter_instruction_patch (j, k3, target);
  2750. break;
  2751. default:
  2752. UNREACHABLE ();
  2753. }
  2754. #endif
  2755. }
  2756. static void
  2757. compile_f64_numerically_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  2758. {
  2759. jit_reloc_t k;
  2760. uint32_t *target;
  2761. emit_sp_ref_f64 (j, JIT_F0, a);
  2762. emit_sp_ref_f64 (j, JIT_F1, b);
  2763. switch (fuse_conditional_branch (j, &target))
  2764. {
  2765. case scm_op_je:
  2766. k = jit_beqr_d (j->jit, JIT_F0, JIT_F1);
  2767. break;
  2768. case scm_op_jne:
  2769. k = jit_bner_d (j->jit, JIT_F0, JIT_F1);
  2770. break;
  2771. default:
  2772. UNREACHABLE ();
  2773. }
  2774. add_inter_instruction_patch (j, k, target);
  2775. }
  2776. static void
  2777. compile_f64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  2778. {
  2779. jit_reloc_t k;
  2780. uint32_t *target;
  2781. emit_sp_ref_f64 (j, JIT_F0, a);
  2782. emit_sp_ref_f64 (j, JIT_F1, b);
  2783. switch (fuse_conditional_branch (j, &target))
  2784. {
  2785. case scm_op_jl:
  2786. k = jit_bltr_d (j->jit, JIT_F0, JIT_F1);
  2787. break;
  2788. case scm_op_jnl:
  2789. k = jit_bunger_d (j->jit, JIT_F0, JIT_F1);
  2790. break;
  2791. case scm_op_jge:
  2792. k = jit_bger_d (j->jit, JIT_F0, JIT_F1);
  2793. break;
  2794. case scm_op_jnge:
  2795. k = jit_bunltr_d (j->jit, JIT_F0, JIT_F1);
  2796. break;
  2797. default:
  2798. UNREACHABLE ();
  2799. }
  2800. add_inter_instruction_patch (j, k, target);
  2801. }
  2802. static void
  2803. compile_numerically_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  2804. {
  2805. jit_reloc_t k;
  2806. uint32_t *target;
  2807. emit_store_current_ip (j, T0);
  2808. emit_call_2 (j, scm_vm_intrinsics.numerically_equal_p,
  2809. sp_scm_operand (j, a), sp_scm_operand (j, b));
  2810. emit_retval (j, T0);
  2811. emit_reload_sp (j);
  2812. switch (fuse_conditional_branch (j, &target))
  2813. {
  2814. case scm_op_je:
  2815. k = jit_bnei (j->jit, T0, 0);
  2816. break;
  2817. case scm_op_jne:
  2818. k = jit_beqi (j->jit, T0, 0);
  2819. break;
  2820. default:
  2821. UNREACHABLE ();
  2822. }
  2823. add_inter_instruction_patch (j, k, target);
  2824. }
  2825. static void
  2826. compile_less (scm_jit_state *j, uint16_t a, uint16_t b)
  2827. {
  2828. jit_reloc_t fast, k2, k3;
  2829. jit_reloc_t k1;
  2830. uint32_t *target;
  2831. enum scm_opcode op = fuse_conditional_branch (j, &target);
  2832. emit_store_current_ip (j, T0);
  2833. emit_sp_ref_scm (j, T0, a);
  2834. emit_sp_ref_scm (j, T1, b);
  2835. /* TAGS-SENSITIVE */
  2836. emit_andr (j, T2, T0, T1);
  2837. emit_comr (j, T2, T2);
  2838. fast = jit_bmci (j->jit, T2, scm_fixnum_tag_mask);
  2839. emit_call_2 (j, scm_vm_intrinsics.less_p,
  2840. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T0),
  2841. jit_operand_gpr (JIT_OPERAND_ABI_POINTER, T1));
  2842. emit_retval (j, T0);
  2843. emit_reload_sp (j);
  2844. switch (op)
  2845. {
  2846. case scm_op_jl:
  2847. k1 = jit_beqi (j->jit, T0, SCM_F_COMPARE_LESS_THAN);
  2848. break;
  2849. case scm_op_jnl:
  2850. k1 = jit_bnei (j->jit, T0, SCM_F_COMPARE_LESS_THAN);
  2851. break;
  2852. case scm_op_jge:
  2853. k1 = jit_beqi (j->jit, T0, SCM_F_COMPARE_NONE);
  2854. break;
  2855. case scm_op_jnge:
  2856. k1 = jit_bnei (j->jit, T0, SCM_F_COMPARE_NONE);
  2857. break;
  2858. default:
  2859. UNREACHABLE ();
  2860. }
  2861. k2 = jit_jmp (j->jit);
  2862. jit_patch_here (j->jit, fast);
  2863. switch (op)
  2864. {
  2865. case scm_op_jl:
  2866. case scm_op_jnge:
  2867. k3 = jit_bltr (j->jit, T0, T1);
  2868. break;
  2869. case scm_op_jnl:
  2870. case scm_op_jge:
  2871. k3 = jit_bger (j->jit, T0, T1);
  2872. break;
  2873. default:
  2874. UNREACHABLE ();
  2875. }
  2876. jit_patch_here (j->jit, k2);
  2877. add_inter_instruction_patch (j, k1, target);
  2878. add_inter_instruction_patch (j, k3, target);
  2879. }
  2880. static void
  2881. compile_check_arguments (scm_jit_state *j, uint32_t expected)
  2882. {
  2883. jit_reloc_t k;
  2884. uint32_t *target;
  2885. jit_gpr_t t = T0;
  2886. emit_reload_fp (j);
  2887. switch (fuse_conditional_branch (j, &target))
  2888. {
  2889. case scm_op_jne:
  2890. k = emit_branch_if_frame_locals_count_not_eq (j, t, expected);
  2891. break;
  2892. case scm_op_jl:
  2893. k = emit_branch_if_frame_locals_count_less_than (j, t, expected);
  2894. break;
  2895. case scm_op_jge:
  2896. /* The arguments<=? instruction sets NONE to indicate
  2897. greater-than, whereas for <, NONE usually indicates
  2898. greater-than-or-equal, hence the name jge. So we need to fuse
  2899. to greater-than, not greater-than-or-equal. Perhaps we just
  2900. need to rename jge to br-if-none. */
  2901. k = emit_branch_if_frame_locals_count_greater_than (j, t, expected);
  2902. break;
  2903. default:
  2904. UNREACHABLE ();
  2905. }
  2906. add_inter_instruction_patch (j, k, target);
  2907. }
  2908. static void
  2909. compile_check_positional_arguments (scm_jit_state *j, uint32_t nreq, uint32_t expected)
  2910. {
  2911. uint32_t *target;
  2912. jit_reloc_t lt, gt;
  2913. jit_gpr_t walk = T0, min = T1, obj = T2;
  2914. ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER | SP_IN_REGISTER);
  2915. switch (fuse_conditional_branch (j, &target))
  2916. {
  2917. case scm_op_jge:
  2918. /* Like arguments<=?, this instruction sets NONE to indicate
  2919. greater-than, whereas for <, NONE usually indicates
  2920. greater-than-or-equal, hence the name jge. So we need to fuse
  2921. to greater-than, not greater-than-or-equal. Perhaps we just
  2922. need to rename jge to br-if-none. */
  2923. /* Break to target if npos > expected. */
  2924. break;
  2925. default:
  2926. UNREACHABLE ();
  2927. }
  2928. emit_subtract_stack_slots (j, min, FP, expected);
  2929. emit_subtract_stack_slots (j, walk, FP, nreq);
  2930. void *head = jit_address (j->jit);
  2931. /* npos > expected if walk < min. */
  2932. gt = jit_bltr (j->jit, walk, min);
  2933. emit_subtract_stack_slots (j, walk, walk, 1);
  2934. lt = jit_bltr (j->jit, walk, SP);
  2935. emit_ldr (j, obj, walk);
  2936. jit_patch_there
  2937. (j->jit,
  2938. emit_branch_if_immediate (j, obj),
  2939. head);
  2940. jit_patch_there
  2941. (j->jit,
  2942. emit_branch_if_heap_object_not_tc11 (j, obj, obj, scm_tc11_keyword),
  2943. head);
  2944. jit_patch_here (j->jit, lt);
  2945. add_inter_instruction_patch (j, gt, target);
  2946. }
  2947. static void
  2948. compile_immediate_tag_equals (scm_jit_state *j, uint32_t a, uint16_t mask,
  2949. uint16_t expected)
  2950. {
  2951. jit_reloc_t k;
  2952. uint32_t *target;
  2953. emit_sp_ref_scm (j, T0, a);
  2954. emit_andi (j, T0, T0, mask);
  2955. switch (fuse_conditional_branch (j, &target))
  2956. {
  2957. case scm_op_je:
  2958. k = jit_beqi (j->jit, T0, expected);
  2959. break;
  2960. case scm_op_jne:
  2961. k = jit_bnei (j->jit, T0, expected);
  2962. break;
  2963. default:
  2964. UNREACHABLE ();
  2965. }
  2966. add_inter_instruction_patch (j, k, target);
  2967. }
  2968. static void
  2969. compile_heap_tag_equals (scm_jit_state *j, uint32_t obj,
  2970. uint16_t mask, uint16_t expected)
  2971. {
  2972. jit_reloc_t k;
  2973. uint32_t *target;
  2974. emit_sp_ref_scm (j, T0, obj);
  2975. switch (fuse_conditional_branch (j, &target))
  2976. {
  2977. case scm_op_je:
  2978. k = emit_branch_if_heap_object_has_tc (j, T0, T0, mask, expected);
  2979. break;
  2980. case scm_op_jne:
  2981. k = emit_branch_if_heap_object_not_tc (j, T0, T0, mask, expected);
  2982. break;
  2983. default:
  2984. UNREACHABLE ();
  2985. }
  2986. add_inter_instruction_patch (j, k, target);
  2987. }
  2988. static void
  2989. compile_eq (scm_jit_state *j, uint16_t a, uint16_t b)
  2990. {
  2991. jit_reloc_t k;
  2992. uint32_t *target;
  2993. emit_sp_ref_scm (j, T0, a);
  2994. emit_sp_ref_scm (j, T1, b);
  2995. switch (fuse_conditional_branch (j, &target))
  2996. {
  2997. case scm_op_je:
  2998. k = jit_beqr (j->jit, T0, T1);
  2999. break;
  3000. case scm_op_jne:
  3001. k = jit_bner (j->jit, T0, T1);
  3002. break;
  3003. default:
  3004. UNREACHABLE ();
  3005. }
  3006. add_inter_instruction_patch (j, k, target);
  3007. }
  3008. static void
  3009. compile_j (scm_jit_state *j, const uint32_t *vcode)
  3010. {
  3011. jit_reloc_t jmp;
  3012. jmp = jit_jmp (j->jit);
  3013. add_inter_instruction_patch (j, jmp, vcode);
  3014. }
  3015. static void
  3016. compile_jl (scm_jit_state *j, const uint32_t *vcode)
  3017. {
  3018. UNREACHABLE (); /* All tests should fuse their following branches. */
  3019. }
  3020. static void
  3021. compile_je (scm_jit_state *j, const uint32_t *vcode)
  3022. {
  3023. UNREACHABLE (); /* All tests should fuse their following branches. */
  3024. }
  3025. static void
  3026. compile_jnl (scm_jit_state *j, const uint32_t *vcode)
  3027. {
  3028. UNREACHABLE (); /* All tests should fuse their following branches. */
  3029. }
  3030. static void
  3031. compile_jne (scm_jit_state *j, const uint32_t *vcode)
  3032. {
  3033. UNREACHABLE (); /* All tests should fuse their following branches. */
  3034. }
  3035. static void
  3036. compile_jge (scm_jit_state *j, const uint32_t *vcode)
  3037. {
  3038. UNREACHABLE (); /* All tests should fuse their following branches. */
  3039. }
  3040. static void
  3041. compile_jnge (scm_jit_state *j, const uint32_t *vcode)
  3042. {
  3043. UNREACHABLE (); /* All tests should fuse their following branches. */
  3044. }
  3045. static void
  3046. compile_heap_numbers_equal (scm_jit_state *j, uint16_t a, uint16_t b)
  3047. {
  3048. jit_reloc_t k;
  3049. uint32_t *target;
  3050. emit_store_current_ip (j, T0);
  3051. emit_call_2 (j, scm_vm_intrinsics.heap_numbers_equal_p, sp_scm_operand (j, a),
  3052. sp_scm_operand (j, b));
  3053. emit_retval (j, T0);
  3054. emit_reload_sp (j);
  3055. switch (fuse_conditional_branch (j, &target))
  3056. {
  3057. case scm_op_je:
  3058. k = jit_bnei (j->jit, T0, 0);
  3059. break;
  3060. case scm_op_jne:
  3061. k = jit_beqi (j->jit, T0, 0);
  3062. break;
  3063. default:
  3064. UNREACHABLE ();
  3065. }
  3066. add_inter_instruction_patch (j, k, target);
  3067. }
  3068. static void
  3069. compile_untag_fixnum (scm_jit_state *j, uint16_t dst, uint16_t a)
  3070. {
  3071. emit_sp_ref_scm (j, T0, a);
  3072. emit_rshi (j, T0, T0, scm_fixnum_tag_size);
  3073. #if SIZEOF_UINTPTR_T >= 8
  3074. emit_sp_set_s64 (j, dst, T0);
  3075. #else
  3076. /* FIXME: Untested!, and also not updated for new tagging XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
  3077. emit_rshi (j, T1, T0, 31);
  3078. emit_sp_set_s64 (j, dst, T0, T1);
  3079. #endif
  3080. }
  3081. static void
  3082. compile_tag_fixnum (scm_jit_state *j, uint16_t dst, uint16_t a)
  3083. {
  3084. #if SIZEOF_UINTPTR_T >= 8
  3085. emit_sp_ref_s64 (j, T0, a);
  3086. #else
  3087. emit_sp_ref_s32 (j, T0, a);
  3088. #endif
  3089. emit_lshi (j, T0, T0, scm_fixnum_tag_size);
  3090. emit_addi (j, T0, T0, scm_fixnum_tag);
  3091. emit_sp_set_scm (j, dst, T0);
  3092. }
  3093. static void
  3094. compile_srsh (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3095. {
  3096. #if SIZEOF_UINTPTR_T >= 8
  3097. emit_sp_ref_s64 (j, T0, a);
  3098. emit_sp_ref_s64 (j, T1, b);
  3099. emit_andi (j, T1, T1, 63);
  3100. emit_rshr (j, T0, T0, T1);
  3101. emit_sp_set_s64 (j, dst, T0);
  3102. #else
  3103. /* FIXME: Not tested. */
  3104. jit_reloc_t zero, both, done;
  3105. emit_sp_ref_s64 (j, T0, T1, a);
  3106. emit_sp_ref_s64 (j, T2, T3_OR_FP, b);
  3107. emit_andi (j, T2, T2, 63);
  3108. zero = jit_beqi (j->jit, T2, 0);
  3109. both = jit_blti (j->jit, T2, 32);
  3110. /* 32 <= s < 64: hi = hi >> 31, lo = hi >> (s-32) */
  3111. emit_subi (j, T2, T2, 32);
  3112. emit_rshr (j, T0, T1, T2);
  3113. emit_rshi (j, T1, T1, 31);
  3114. done = jit_jmp (j->jit);
  3115. jit_patch_here (j->jit, both);
  3116. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  3117. emit_negr (j, T3_OR_FP, T2);
  3118. emit_addi (j, T3_OR_FP, T3_OR_FP, 32);
  3119. emit_lshr (j, T3_OR_FP, T1, T3_OR_FP);
  3120. emit_rshr (j, T1, T1, T2);
  3121. emit_rshr_u (j, T0, T0, T2);
  3122. emit_addr (j, T0, T0, T3_OR_FP);
  3123. jit_patch_here (j->jit, done);
  3124. jit_patch_here (j->jit, zero);
  3125. emit_sp_set_s64 (j, dst, T0, T1);
  3126. #endif
  3127. }
  3128. static void
  3129. compile_srsh_immediate (scm_jit_state *j, uint8_t dst, uint8_t a, uint8_t b)
  3130. {
  3131. b &= 63;
  3132. #if SIZEOF_UINTPTR_T >= 8
  3133. emit_sp_ref_s64 (j, T0, a);
  3134. emit_rshi (j, T0, T0, b);
  3135. emit_sp_set_s64 (j, dst, T0);
  3136. #else
  3137. /* FIXME: Not tested. */
  3138. emit_sp_ref_s64 (j, T0, T1, a);
  3139. if (b == 0)
  3140. {
  3141. /* Nothing to do. */
  3142. }
  3143. else if (b < 32)
  3144. {
  3145. /* 0 < s < 32: hi = hi >> s, lo = lo >> s + hi << (32-s) */
  3146. emit_lshi (j, T2, T1, 32 - b);
  3147. emit_rshi (j, T1, T1, b);
  3148. emit_rshi_u (j, T0, T0, b);
  3149. emit_addr (j, T0, T0, T2);
  3150. }
  3151. else if (b == 32)
  3152. {
  3153. /* hi = sign-ext, lo = hi */
  3154. emit_movr (j, T0, T1);
  3155. emit_rshi (j, T1, T1, 31);
  3156. }
  3157. else /* b > 32 */
  3158. {
  3159. /* hi = sign-ext, lo = hi >> (s-32) */
  3160. emit_rshi (j, T0, T1, b - 32);
  3161. emit_rshi (j, T1, T1, 31);
  3162. }
  3163. emit_sp_set_s64 (j, dst, T0, T1);
  3164. #endif
  3165. }
  3166. static void
  3167. compile_s64_imm_numerically_equal (scm_jit_state *j, uint16_t a, int16_t b)
  3168. {
  3169. #if SIZEOF_UINTPTR_T >= 8
  3170. jit_reloc_t k;
  3171. uint32_t *target;
  3172. emit_sp_ref_s64 (j, T0, a);
  3173. switch (fuse_conditional_branch (j, &target))
  3174. {
  3175. case scm_op_je:
  3176. k = jit_beqi (j->jit, T0, b);
  3177. break;
  3178. case scm_op_jne:
  3179. k = jit_bnei (j->jit, T0, b);
  3180. break;
  3181. default:
  3182. UNREACHABLE ();
  3183. }
  3184. add_inter_instruction_patch (j, k, target);
  3185. #else
  3186. jit_reloc_t k1, k2;
  3187. uint32_t *target;
  3188. emit_sp_ref_s64 (j, T0, T1, a);
  3189. switch (fuse_conditional_branch (j, &target))
  3190. {
  3191. case scm_op_je:
  3192. k1 = jit_bnei (j->jit, T0, b);
  3193. k2 = jit_beqi (j->jit, T1, b < 0 ? -1 : 0);
  3194. jit_patch_here (j->jit, k1);
  3195. add_inter_instruction_patch (j, k2, target);
  3196. break;
  3197. case scm_op_jne:
  3198. k1 = jit_bnei (j->jit, T0, b);
  3199. k2 = jit_bnei (j->jit, T1, b < 0 ? -1 : 0);
  3200. add_inter_instruction_patch (j, k1, target);
  3201. add_inter_instruction_patch (j, k2, target);
  3202. break;
  3203. default:
  3204. UNREACHABLE ();
  3205. }
  3206. #endif
  3207. }
  3208. static void
  3209. compile_u64_imm_less (scm_jit_state *j, uint16_t a, uint16_t b)
  3210. {
  3211. #if SIZEOF_UINTPTR_T >= 8
  3212. jit_reloc_t k;
  3213. uint32_t *target;
  3214. emit_sp_ref_u64 (j, T0, a);
  3215. switch (fuse_conditional_branch (j, &target))
  3216. {
  3217. case scm_op_jl:
  3218. k = jit_blti_u (j->jit, T0, b);
  3219. break;
  3220. case scm_op_jnl:
  3221. k = jit_bgei_u (j->jit, T0, b);
  3222. break;
  3223. default:
  3224. UNREACHABLE ();
  3225. }
  3226. add_inter_instruction_patch (j, k, target);
  3227. #else
  3228. jit_reloc_t k1, k2;
  3229. uint32_t *target;
  3230. emit_sp_ref_u64 (j, T0, T1, a);
  3231. switch (fuse_conditional_branch (j, &target))
  3232. {
  3233. case scm_op_jl:
  3234. k1 = jit_bnei (j->jit, T1, 0);
  3235. k2 = jit_blti_u (j->jit, T0, b);
  3236. jit_patch_here (j->jit, k1);
  3237. add_inter_instruction_patch (j, k2, target);
  3238. break;
  3239. case scm_op_jnl:
  3240. k1 = jit_bnei (j->jit, T1, 0);
  3241. k2 = jit_bgei_u (j->jit, T0, b);
  3242. add_inter_instruction_patch (j, k1, target);
  3243. add_inter_instruction_patch (j, k2, target);
  3244. break;
  3245. default:
  3246. UNREACHABLE ();
  3247. }
  3248. #endif
  3249. }
  3250. static void
  3251. compile_imm_u64_less (scm_jit_state *j, uint16_t a, uint16_t b)
  3252. {
  3253. #if SIZEOF_UINTPTR_T >= 8
  3254. jit_reloc_t k;
  3255. uint32_t *target;
  3256. emit_sp_ref_u64 (j, T0, a);
  3257. switch (fuse_conditional_branch (j, &target))
  3258. {
  3259. case scm_op_jl:
  3260. k = jit_bgti_u (j->jit, T0, b);
  3261. break;
  3262. case scm_op_jnl:
  3263. k = jit_blei_u (j->jit, T0, b);
  3264. break;
  3265. default:
  3266. UNREACHABLE ();
  3267. }
  3268. add_inter_instruction_patch (j, k, target);
  3269. #else
  3270. jit_reloc_t k1, k2;
  3271. uint32_t *target;
  3272. emit_sp_ref_u64 (j, T0, T1, a);
  3273. switch (fuse_conditional_branch (j, &target))
  3274. {
  3275. case scm_op_jl:
  3276. k1 = jit_bnei (j->jit, T1, 0);
  3277. k2 = jit_bgti_u (j->jit, T0, b);
  3278. add_inter_instruction_patch (j, k1, target);
  3279. add_inter_instruction_patch (j, k2, target);
  3280. break;
  3281. case scm_op_jnl:
  3282. k1 = jit_bnei (j->jit, T1, 0);
  3283. k2 = jit_blei_u (j->jit, T0, b);
  3284. jit_patch_here (j->jit, k1);
  3285. add_inter_instruction_patch (j, k2, target);
  3286. break;
  3287. default:
  3288. UNREACHABLE ();
  3289. }
  3290. #endif
  3291. }
  3292. static void
  3293. compile_s64_imm_less (scm_jit_state *j, uint16_t a, int16_t b)
  3294. {
  3295. #if SIZEOF_UINTPTR_T >= 8
  3296. jit_reloc_t k;
  3297. uint32_t *target;
  3298. emit_sp_ref_s64 (j, T0, a);
  3299. switch (fuse_conditional_branch (j, &target))
  3300. {
  3301. case scm_op_jl:
  3302. k = jit_blti (j->jit, T0, b);
  3303. break;
  3304. case scm_op_jnl:
  3305. k = jit_bgei (j->jit, T0, b);
  3306. break;
  3307. default:
  3308. UNREACHABLE ();
  3309. }
  3310. add_inter_instruction_patch (j, k, target);
  3311. #else
  3312. jit_reloc_t k1, k2, k3;
  3313. int32_t sign = b < 0 ? -1 : 0;
  3314. uint32_t *target;
  3315. emit_sp_ref_s64 (j, T0, T1, a);
  3316. switch (fuse_conditional_branch (j, &target))
  3317. {
  3318. case scm_op_jl:
  3319. k1 = jit_blti (j->jit, T1, sign);
  3320. k2 = jit_bnei (j->jit, T1, sign);
  3321. k3 = jit_blti (j->jit, T0, b);
  3322. add_inter_instruction_patch (j, k1, target);
  3323. jit_patch_here (j->jit, k2);
  3324. add_inter_instruction_patch (j, k3, target);
  3325. break;
  3326. case scm_op_jnl:
  3327. k1 = jit_blti (j->jit, T1, sign);
  3328. k2 = jit_bnei (j->jit, T1, sign);
  3329. k3 = jit_bgei (j->jit, T0, b);
  3330. jit_patch_here (j->jit, k1);
  3331. add_inter_instruction_patch (j, k2, target);
  3332. add_inter_instruction_patch (j, k3, target);
  3333. break;
  3334. default:
  3335. UNREACHABLE ();
  3336. }
  3337. #endif
  3338. }
  3339. static void
  3340. compile_imm_s64_less (scm_jit_state *j, uint16_t a, int16_t b)
  3341. {
  3342. #if SIZEOF_UINTPTR_T >= 8
  3343. jit_reloc_t k;
  3344. uint32_t *target;
  3345. emit_sp_ref_s64 (j, T0, a);
  3346. switch (fuse_conditional_branch (j, &target))
  3347. {
  3348. case scm_op_jl:
  3349. k = jit_bgti (j->jit, T0, b);
  3350. break;
  3351. case scm_op_jnl:
  3352. k = jit_blei (j->jit, T0, b);
  3353. break;
  3354. default:
  3355. UNREACHABLE ();
  3356. }
  3357. add_inter_instruction_patch (j, k, target);
  3358. #else
  3359. jit_reloc_t k1, k2, k3;
  3360. int32_t sign = b < 0 ? -1 : 0;
  3361. uint32_t *target;
  3362. emit_sp_ref_s64 (j, T0, T1, a);
  3363. switch (fuse_conditional_branch (j, &target))
  3364. {
  3365. case scm_op_jl:
  3366. k1 = jit_blti (j->jit, T1, sign);
  3367. k2 = jit_bnei (j->jit, T1, sign);
  3368. k3 = jit_bgti (j->jit, T0, b);
  3369. jit_patch_here (j->jit, k1);
  3370. add_inter_instruction_patch (j, k2, target);
  3371. add_inter_instruction_patch (j, k3, target);
  3372. break;
  3373. case scm_op_jnl:
  3374. k1 = jit_blti (j->jit, T1, sign);
  3375. k2 = jit_bnei (j->jit, T1, sign);
  3376. k3 = jit_blei (j->jit, T0, b);
  3377. add_inter_instruction_patch (j, k1, target);
  3378. jit_patch_here (j->jit, k2);
  3379. add_inter_instruction_patch (j, k3, target);
  3380. break;
  3381. default:
  3382. UNREACHABLE ();
  3383. }
  3384. #endif
  3385. }
  3386. static void
  3387. compile_u8_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3388. {
  3389. emit_sp_ref_ptr (j, T0, ptr);
  3390. emit_sp_ref_sz (j, T1, idx);
  3391. jit_ldxr_uc (j->jit, T0, T0, T1);
  3392. record_gpr_clobber (j, T0);
  3393. #if SIZEOF_UINTPTR_T >= 8
  3394. emit_sp_set_u64 (j, dst, T0);
  3395. #else
  3396. emit_movi (j, T1, 0);
  3397. emit_sp_set_u64 (j, dst, T0, T1);
  3398. #endif
  3399. }
  3400. static void
  3401. compile_u16_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3402. {
  3403. emit_sp_ref_ptr (j, T0, ptr);
  3404. emit_sp_ref_sz (j, T1, idx);
  3405. jit_ldxr_us (j->jit, T0, T0, T1);
  3406. record_gpr_clobber (j, T0);
  3407. #if SIZEOF_UINTPTR_T >= 8
  3408. emit_sp_set_u64 (j, dst, T0);
  3409. #else
  3410. emit_movi (j, T1, 0);
  3411. emit_sp_set_u64 (j, dst, T0, T1);
  3412. #endif
  3413. }
  3414. static void
  3415. compile_u32_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3416. {
  3417. emit_sp_ref_ptr (j, T0, ptr);
  3418. emit_sp_ref_sz (j, T1, idx);
  3419. #if SIZEOF_UINTPTR_T >= 8
  3420. jit_ldxr_ui (j->jit, T0, T0, T1);
  3421. record_gpr_clobber (j, T0);
  3422. emit_sp_set_u64 (j, dst, T0);
  3423. #else
  3424. emit_ldxr (j, T0, T0, T1);
  3425. emit_movi (j, T1, 0);
  3426. emit_sp_set_u64 (j, dst, T0, T1);
  3427. #endif
  3428. }
  3429. static void
  3430. compile_u64_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3431. {
  3432. emit_sp_ref_ptr (j, T0, ptr);
  3433. emit_sp_ref_sz (j, T1, idx);
  3434. #if SIZEOF_UINTPTR_T >= 8
  3435. emit_ldxr (j, T0, T0, T1);
  3436. emit_sp_set_u64 (j, dst, T0);
  3437. #else
  3438. emit_addr (j, T0, T0, T1);
  3439. if (BIGENDIAN)
  3440. {
  3441. emit_ldr (j, T1, T0);
  3442. emit_ldxi (j, T0, T0, 4);
  3443. }
  3444. else
  3445. {
  3446. emit_ldxi (j, T1, T0, 4);
  3447. emit_ldr (j, T0, T0);
  3448. }
  3449. emit_sp_set_u64 (j, dst, T0, T1);
  3450. #endif
  3451. }
  3452. static void
  3453. compile_u8_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3454. {
  3455. emit_sp_ref_ptr (j, T0, ptr);
  3456. emit_sp_ref_sz (j, T1, idx);
  3457. #if SIZEOF_UINTPTR_T >= 8
  3458. emit_sp_ref_u64 (j, T2, v);
  3459. #else
  3460. emit_sp_ref_u64_lower_half (j, T2, v);
  3461. #endif
  3462. jit_stxr_c (j->jit, T0, T1, T2);
  3463. }
  3464. static void
  3465. compile_u16_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3466. {
  3467. emit_sp_ref_ptr (j, T0, ptr);
  3468. emit_sp_ref_sz (j, T1, idx);
  3469. #if SIZEOF_UINTPTR_T >= 8
  3470. emit_sp_ref_u64 (j, T2, v);
  3471. #else
  3472. emit_sp_ref_u64_lower_half (j, T2, v);
  3473. #endif
  3474. jit_stxr_s (j->jit, T0, T1, T2);
  3475. }
  3476. static void
  3477. compile_u32_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3478. {
  3479. emit_sp_ref_ptr (j, T0, ptr);
  3480. emit_sp_ref_sz (j, T1, idx);
  3481. #if SIZEOF_UINTPTR_T >= 8
  3482. emit_sp_ref_u64 (j, T2, v);
  3483. jit_stxr_i (j->jit, T0, T1, T2);
  3484. #else
  3485. emit_sp_ref_u64_lower_half (j, T2, v);
  3486. jit_stxr (j->jit, T0, T1, T2);
  3487. #endif
  3488. }
  3489. static void
  3490. compile_u64_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3491. {
  3492. emit_sp_ref_ptr (j, T0, ptr);
  3493. emit_sp_ref_sz (j, T1, idx);
  3494. #if SIZEOF_UINTPTR_T >= 8
  3495. emit_sp_ref_u64 (j, T2, v);
  3496. jit_stxr (j->jit, T0, T1, T2);
  3497. #else
  3498. jit_addr (j->jit, T0, T0, T1);
  3499. emit_sp_ref_u64 (j, T1, T2, v);
  3500. if (BIGENDIAN)
  3501. {
  3502. jit_str (j->jit, T0, T2);
  3503. jit_stxi (j->jit, 4, T0, T1);
  3504. }
  3505. else
  3506. {
  3507. jit_str (j->jit, T0, T1);
  3508. jit_stxi (j->jit, 4, T0, T2);
  3509. }
  3510. #endif
  3511. }
  3512. static void
  3513. compile_s8_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3514. {
  3515. emit_sp_ref_ptr (j, T0, ptr);
  3516. emit_sp_ref_sz (j, T1, idx);
  3517. jit_ldxr_c (j->jit, T0, T0, T1);
  3518. record_gpr_clobber (j, T0);
  3519. #if SIZEOF_UINTPTR_T >= 8
  3520. emit_sp_set_s64 (j, dst, T0);
  3521. #else
  3522. emit_rshi (j, T1, T0, 7);
  3523. emit_sp_set_u64 (j, dst, T0, T1);
  3524. #endif
  3525. }
  3526. static void
  3527. compile_s16_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3528. {
  3529. emit_sp_ref_ptr (j, T0, ptr);
  3530. emit_sp_ref_sz (j, T1, idx);
  3531. jit_ldxr_s (j->jit, T0, T0, T1);
  3532. record_gpr_clobber (j, T0);
  3533. #if SIZEOF_UINTPTR_T >= 8
  3534. emit_sp_set_s64 (j, dst, T0);
  3535. #else
  3536. emit_rshi (j, T1, T0, 15);
  3537. emit_sp_set_u64 (j, dst, T0, T1);
  3538. #endif
  3539. }
  3540. static void
  3541. compile_s32_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3542. {
  3543. emit_sp_ref_ptr (j, T0, ptr);
  3544. emit_sp_ref_sz (j, T1, idx);
  3545. jit_ldxr_i (j->jit, T0, T0, T1);
  3546. record_gpr_clobber (j, T0);
  3547. #if SIZEOF_UINTPTR_T >= 8
  3548. emit_sp_set_s64 (j, dst, T0);
  3549. #else
  3550. emit_rshi (j, T1, T0, 31);
  3551. emit_sp_set_u64 (j, dst, T0, T1);
  3552. #endif
  3553. }
  3554. static void
  3555. compile_s64_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3556. {
  3557. compile_u64_ref (j, dst, ptr, idx);
  3558. }
  3559. static void
  3560. compile_s8_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3561. {
  3562. compile_u8_set (j, ptr, idx, v);
  3563. }
  3564. static void
  3565. compile_s16_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3566. {
  3567. compile_u16_set (j, ptr, idx, v);
  3568. }
  3569. static void
  3570. compile_s32_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3571. {
  3572. compile_u32_set (j, ptr, idx, v);
  3573. }
  3574. static void
  3575. compile_s64_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3576. {
  3577. compile_u64_set (j, ptr, idx, v);
  3578. }
  3579. static void
  3580. compile_f32_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3581. {
  3582. emit_sp_ref_ptr (j, T0, ptr);
  3583. emit_sp_ref_sz (j, T1, idx);
  3584. jit_ldxr_f (j->jit, JIT_F0, T0, T1);
  3585. record_fpr_clobber (j, JIT_F0);
  3586. jit_extr_f_d (j->jit, JIT_F0, JIT_F0);
  3587. emit_sp_set_f64 (j, dst, JIT_F0);
  3588. }
  3589. static void
  3590. compile_f64_ref (scm_jit_state *j, uint8_t dst, uint8_t ptr, uint8_t idx)
  3591. {
  3592. emit_sp_ref_ptr (j, T0, ptr);
  3593. emit_sp_ref_sz (j, T1, idx);
  3594. jit_ldxr_d (j->jit, JIT_F0, T0, T1);
  3595. record_fpr_clobber (j, JIT_F0);
  3596. emit_sp_set_f64 (j, dst, JIT_F0);
  3597. }
  3598. static void
  3599. compile_f32_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3600. {
  3601. emit_sp_ref_ptr (j, T0, ptr);
  3602. emit_sp_ref_sz (j, T1, idx);
  3603. emit_sp_ref_f64 (j, JIT_F0, v);
  3604. jit_extr_d_f (j->jit, JIT_F0, JIT_F0);
  3605. record_fpr_clobber (j, JIT_F0);
  3606. jit_stxr_f (j->jit, T0, T1, JIT_F0);
  3607. }
  3608. static void
  3609. compile_f64_set (scm_jit_state *j, uint8_t ptr, uint8_t idx, uint8_t v)
  3610. {
  3611. emit_sp_ref_ptr (j, T0, ptr);
  3612. emit_sp_ref_sz (j, T1, idx);
  3613. emit_sp_ref_f64 (j, JIT_F0, v);
  3614. jit_stxr_d (j->jit, T0, T1, JIT_F0);
  3615. }
  3616. #define UNPACK_8_8_8(op,a,b,c) \
  3617. do \
  3618. { \
  3619. a = (op >> 8) & 0xff; \
  3620. b = (op >> 16) & 0xff; \
  3621. c = op >> 24; \
  3622. } \
  3623. while (0)
  3624. #define UNPACK_8_16(op,a,b) \
  3625. do \
  3626. { \
  3627. a = (op >> 8) & 0xff; \
  3628. b = op >> 16; \
  3629. } \
  3630. while (0)
  3631. #define UNPACK_12_12(op,a,b) \
  3632. do \
  3633. { \
  3634. a = (op >> 8) & 0xfff; \
  3635. b = op >> 20; \
  3636. } \
  3637. while (0)
  3638. #define UNPACK_24(op,a) \
  3639. do \
  3640. { \
  3641. a = op >> 8; \
  3642. } \
  3643. while (0)
  3644. #define UNPACK_8_24(op,a,b) \
  3645. do \
  3646. { \
  3647. a = op & 0xff; \
  3648. b = op >> 8; \
  3649. } \
  3650. while (0)
  3651. #define UNPACK_16_16(op,a,b) \
  3652. do \
  3653. { \
  3654. a = op & 0xffff; \
  3655. b = op >> 16; \
  3656. } \
  3657. while (0)
  3658. #define COMPILE_OP1(t0) \
  3659. COMPILE_##t0
  3660. #define COMPILE_OP2(t0, t1) \
  3661. COMPILE_##t0##__##t1
  3662. #define COMPILE_OP3(t0, t1, t2) \
  3663. COMPILE_##t0##__##t1##__##t2
  3664. #define COMPILE_OP4(t0, t1, t2, t3) \
  3665. COMPILE_##t0##__##t1##__##t2##__##t3
  3666. #define COMPILE_OP5(t0, t1, t2, t3, t4) \
  3667. COMPILE_##t0##__##t1##__##t2##__##t3##__##t4
  3668. #define COMPILE_DOP1(t0) COMPILE_OP1(t0)
  3669. #define COMPILE_DOP2(t0, t1) COMPILE_OP2(t0, t1)
  3670. #define COMPILE_DOP3(t0, t1, t2) COMPILE_OP3(t0, t1, t2)
  3671. #define COMPILE_DOP4(t0, t1, t2, t3) COMPILE_OP4(t0, t1, t2, t3)
  3672. #define COMPILE_DOP5(t0, t1, t2, t3, t4) COMPILE_OP5(t0, t1, t2, t3, t4)
  3673. #define COMPILE_NOP(j, comp) \
  3674. { \
  3675. bad_instruction (j); \
  3676. }
  3677. #define COMPILE_X32(j, comp) \
  3678. { \
  3679. comp (j); \
  3680. }
  3681. #define COMPILE_X8_C24(j, comp) \
  3682. { \
  3683. uint32_t a; \
  3684. UNPACK_24 (j->ip[0], a); \
  3685. comp (j, a); \
  3686. }
  3687. #define COMPILE_X8_F24(j, comp) \
  3688. COMPILE_X8_C24 (j, comp)
  3689. #define COMPILE_X8_S24(j, comp) \
  3690. COMPILE_X8_C24 (j, comp)
  3691. #define COMPILE_X8_L24(j, comp) \
  3692. { \
  3693. int32_t a = j->ip[0]; \
  3694. a >>= 8; /* Sign extension. */ \
  3695. comp (j, j->ip + a); \
  3696. }
  3697. #define COMPILE_X8_C12_C12(j, comp) \
  3698. { \
  3699. uint16_t a, b; \
  3700. UNPACK_12_12 (j->ip[0], a, b); \
  3701. comp (j, a, b); \
  3702. }
  3703. #define COMPILE_X8_S12_C12(j, comp) \
  3704. COMPILE_X8_C12_C12 (j, comp)
  3705. #define COMPILE_X8_S12_S12(j, comp) \
  3706. COMPILE_X8_C12_C12 (j, comp)
  3707. #define COMPILE_X8_F12_F12(j, comp) \
  3708. COMPILE_X8_C12_C12 (j, comp)
  3709. #define COMPILE_X8_S12_Z12(j, comp) \
  3710. { \
  3711. uint16_t a = (j->ip[0] >> 8) & 0xfff; \
  3712. int16_t b = ((int32_t) j->ip[0]) >> 20; /* Sign extension. */ \
  3713. comp (j, a, b); \
  3714. }
  3715. #define COMPILE_X8_S8_C8_S8(j, comp) \
  3716. { \
  3717. uint8_t a, b, c; \
  3718. UNPACK_8_8_8 (j->ip[0], a, b, c); \
  3719. comp (j, a, b, c); \
  3720. }
  3721. #define COMPILE_X8_S8_S8_C8(j, comp) \
  3722. COMPILE_X8_S8_C8_S8 (j, comp)
  3723. #define COMPILE_X8_S8_S8_S8(j, comp) \
  3724. COMPILE_X8_S8_C8_S8 (j, comp)
  3725. #define COMPILE_X8_S8_I16(j, comp) \
  3726. { \
  3727. uint8_t a; \
  3728. scm_t_bits b; \
  3729. UNPACK_8_16 (j->ip[0], a, b); \
  3730. comp (j, a, SCM_PACK (b)); \
  3731. }
  3732. #define COMPILE_X32__C32(j, comp) \
  3733. { \
  3734. comp (j, j->ip[1]); \
  3735. }
  3736. #define COMPILE_X32__L32(j, comp) \
  3737. { \
  3738. int32_t a = j->ip[1]; \
  3739. comp (j, j->ip + a); \
  3740. }
  3741. #define COMPILE_X32__N32(j, comp) \
  3742. COMPILE_X32__L32 (j, comp)
  3743. #define COMPILE_X8_C24__L32(j, comp) \
  3744. { \
  3745. uint32_t a; \
  3746. int32_t b; \
  3747. UNPACK_24 (j->ip[0], a); \
  3748. b = j->ip[1]; \
  3749. comp (j, a, j->ip + b); \
  3750. }
  3751. #define COMPILE_X8_S24__L32(j, comp) \
  3752. COMPILE_X8_C24__L32 (j, comp)
  3753. #define COMPILE_X8_S24__LO32(j, comp) \
  3754. COMPILE_X8_C24__L32 (j, comp)
  3755. #define COMPILE_X8_S24__N32(j, comp) \
  3756. COMPILE_X8_C24__L32 (j, comp)
  3757. #define COMPILE_X8_S24__R32(j, comp) \
  3758. COMPILE_X8_C24__L32 (j, comp)
  3759. #define COMPILE_X8_C24__X8_C24(j, comp) \
  3760. { \
  3761. uint32_t a, b; \
  3762. UNPACK_24 (j->ip[0], a); \
  3763. UNPACK_24 (j->ip[1], b); \
  3764. comp (j, a, b); \
  3765. }
  3766. #define COMPILE_X8_F24__X8_C24(j, comp) \
  3767. COMPILE_X8_C24__X8_C24(j, comp)
  3768. #define COMPILE_X8_F24__X8_F24(j, comp) \
  3769. COMPILE_X8_C24__X8_C24(j, comp)
  3770. #define COMPILE_X8_S24__X8_S24(j, comp) \
  3771. COMPILE_X8_C24__X8_C24(j, comp)
  3772. #define COMPILE_X8_F12_F12__X8_C24(j, comp) \
  3773. { \
  3774. uint16_t a, b; \
  3775. uint32_t c; \
  3776. UNPACK_12_12 (j->ip[0], a, b); \
  3777. UNPACK_24 (j->ip[1], c); \
  3778. comp (j, a, b, c); \
  3779. }
  3780. #define COMPILE_X8_F24__B1_X7_C24(j, comp) \
  3781. { \
  3782. uint32_t a, c; \
  3783. uint8_t b; \
  3784. UNPACK_24 (j->ip[0], a); \
  3785. b = j->ip[1] & 0x1; \
  3786. UNPACK_24 (j->ip[1], c); \
  3787. comp (j, a, b, c); \
  3788. }
  3789. #define COMPILE_X8_S12_S12__C32(j, comp) \
  3790. { \
  3791. uint16_t a, b; \
  3792. uint32_t c; \
  3793. UNPACK_12_12 (j->ip[0], a, b); \
  3794. c = j->ip[1]; \
  3795. comp (j, a, b, c); \
  3796. }
  3797. #define COMPILE_X8_S24__C16_C16(j, comp) \
  3798. { \
  3799. uint32_t a; \
  3800. uint16_t b, c; \
  3801. UNPACK_24 (j->ip[0], a); \
  3802. UNPACK_16_16 (j->ip[1], b, c); \
  3803. comp (j, a, b, c); \
  3804. }
  3805. #define COMPILE_X8_S24__C32(j, comp) \
  3806. { \
  3807. uint32_t a, b; \
  3808. UNPACK_24 (j->ip[0], a); \
  3809. b = j->ip[1]; \
  3810. comp (j, a, b); \
  3811. }
  3812. #define COMPILE_X8_S24__I32(j, comp) \
  3813. { \
  3814. uint32_t a; \
  3815. scm_t_bits b; \
  3816. UNPACK_24 (j->ip[0], a); \
  3817. b = j->ip[1]; \
  3818. comp (j, a, SCM_PACK (b)); \
  3819. }
  3820. #define COMPILE_X8_S8_S8_C8__C32(j, comp) \
  3821. { \
  3822. uint8_t a, b, c; \
  3823. uint32_t d; \
  3824. UNPACK_8_8_8 (j->ip[0], a, b, c); \
  3825. d = j->ip[1]; \
  3826. comp (j, a, b, c, d); \
  3827. }
  3828. #define COMPILE_X8_S8_S8_S8__C32(j, comp) \
  3829. COMPILE_X8_S8_S8_C8__C32(j, comp)
  3830. #define COMPILE_X32__LO32__L32(j, comp) \
  3831. { \
  3832. int32_t a = j->ip[1], b = j->ip[2]; \
  3833. comp (j, j->ip + a, j->ip + b); \
  3834. }
  3835. #define COMPILE_X8_F24__X8_C24__L32(j, comp) \
  3836. { \
  3837. uint32_t a, b; \
  3838. int32_t c; \
  3839. UNPACK_24 (j->ip[0], a); \
  3840. UNPACK_24 (j->ip[1], b); \
  3841. c = j->ip[2]; \
  3842. comp (j, a, b, j->ip + c); \
  3843. }
  3844. #define COMPILE_X8_S24__A32__B32(j, comp) \
  3845. { \
  3846. uint32_t a; \
  3847. uint64_t b; \
  3848. UNPACK_24 (j->ip[0], a); \
  3849. b = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  3850. ASSERT (b <= (uint64_t) UINTPTR_MAX); \
  3851. comp (j, a, SCM_PACK ((uintptr_t) b)); \
  3852. }
  3853. #define COMPILE_X8_S24__AF32__BF32(j, comp) \
  3854. { \
  3855. uint32_t a; \
  3856. union { uint64_t u; double d; } b; \
  3857. UNPACK_24 (j->ip[0], a); \
  3858. b.u = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  3859. comp (j, a, b.d); \
  3860. }
  3861. #define COMPILE_X8_S24__AS32__BS32(j, comp) \
  3862. { \
  3863. uint32_t a; \
  3864. uint64_t b; \
  3865. UNPACK_24 (j->ip[0], a); \
  3866. b = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  3867. comp (j, a, (int64_t) b); \
  3868. }
  3869. #define COMPILE_X8_S24__AU32__BU32(j, comp) \
  3870. { \
  3871. uint32_t a; \
  3872. uint64_t b; \
  3873. UNPACK_24 (j->ip[0], a); \
  3874. b = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]); \
  3875. comp (j, a, b); \
  3876. }
  3877. #define COMPILE_X8_S24__B1_X7_F24__X8_L24(j, comp) \
  3878. { \
  3879. uint32_t a, c; \
  3880. uint8_t b; \
  3881. int32_t d; \
  3882. UNPACK_24 (j->ip[0], a); \
  3883. b = j->ip[1] & 0x1; \
  3884. UNPACK_24 (j->ip[1], c); \
  3885. d = j->ip[2]; d >>= 8; /* Sign extension. */ \
  3886. comp (j, a, b, c, j->ip + d); \
  3887. }
  3888. #define COMPILE_X8_S24__X8_S24__C8_S24(j, comp) \
  3889. { \
  3890. uint32_t a, b, d; \
  3891. uint8_t c; \
  3892. UNPACK_24 (j->ip[0], a); \
  3893. UNPACK_24 (j->ip[1], b); \
  3894. UNPACK_8_24 (j->ip[2], c, d); \
  3895. comp (j, a, b, c, d); \
  3896. }
  3897. #define COMPILE_X8_C24__C8_C24__X8_C24__N32(j, comp) \
  3898. { \
  3899. uint32_t a, c, d; \
  3900. uint8_t b; \
  3901. int32_t e; \
  3902. UNPACK_24 (j->ip[0], a); \
  3903. UNPACK_8_24 (j->ip[1], b, c); \
  3904. UNPACK_24 (j->ip[2], d); \
  3905. e = j->ip[3]; \
  3906. comp (j, a, b, c, d, j->ip + e); \
  3907. }
  3908. #define COMPILE_X8_S24__X8_S24__C8_S24__X8_S24(j, comp) \
  3909. { \
  3910. uint32_t a, b, d, e; \
  3911. uint8_t c; \
  3912. UNPACK_24 (j->ip[0], a); \
  3913. UNPACK_24 (j->ip[1], b); \
  3914. UNPACK_8_24 (j->ip[2], c, d); \
  3915. UNPACK_24 (j->ip[3], e); \
  3916. comp (j, a, b, c, d, e); \
  3917. }
  3918. static uint8_t first_seen[256];
  3919. static void
  3920. compile1 (scm_jit_state *j)
  3921. {
  3922. uint8_t opcode = j->ip[0] & 0xff;
  3923. if (!first_seen[opcode])
  3924. {
  3925. const char *n;
  3926. switch (opcode)
  3927. {
  3928. #define NAME(code, cname, name, arity) case code: n = name; break;
  3929. FOR_EACH_VM_OPERATION(NAME)
  3930. #undef NAME
  3931. default:
  3932. UNREACHABLE ();
  3933. }
  3934. first_seen[opcode] = 1;
  3935. DEBUG ("Instruction first seen at vcode %p: %s\n", j->ip, n);
  3936. }
  3937. j->next_ip = j->ip + op_lengths[opcode];
  3938. switch (opcode)
  3939. {
  3940. #define COMPILE1(code, cname, name, arity) \
  3941. case code: COMPILE_##arity(j, compile_##cname); break;
  3942. FOR_EACH_VM_OPERATION(COMPILE1)
  3943. #undef COMPILE1
  3944. default:
  3945. UNREACHABLE ();
  3946. }
  3947. j->ip = j->next_ip;
  3948. }
  3949. static void
  3950. analyze (scm_jit_state *j)
  3951. {
  3952. memset (j->op_attrs, 0, j->end - j->start);
  3953. j->op_attrs[0] = OP_ATTR_BLOCK | OP_ATTR_ENTRY;
  3954. for (j->ip = (uint32_t *) j->start; j->ip < j->end; j->ip = j->next_ip)
  3955. {
  3956. uint8_t opcode = j->ip[0] & 0xff;
  3957. uint8_t attrs = 0;
  3958. uint32_t *target;
  3959. j->next_ip = j->ip + op_lengths[opcode];
  3960. switch (opcode)
  3961. {
  3962. case scm_op_check_arguments:
  3963. case scm_op_check_positional_arguments:
  3964. attrs |= OP_ATTR_ENTRY;
  3965. /* Fall through. */
  3966. case scm_op_u64_numerically_equal:
  3967. case scm_op_u64_less:
  3968. case scm_op_s64_less:
  3969. case scm_op_f64_numerically_equal:
  3970. case scm_op_f64_less:
  3971. case scm_op_numerically_equal:
  3972. case scm_op_less:
  3973. case scm_op_immediate_tag_equals:
  3974. case scm_op_heap_tag_equals:
  3975. case scm_op_eq:
  3976. case scm_op_heap_numbers_equal:
  3977. case scm_op_s64_imm_numerically_equal:
  3978. case scm_op_u64_imm_less:
  3979. case scm_op_imm_u64_less:
  3980. case scm_op_s64_imm_less:
  3981. case scm_op_imm_s64_less:
  3982. attrs |= OP_ATTR_BLOCK;
  3983. fuse_conditional_branch (j, &target);
  3984. j->op_attrs[target - j->start] |= attrs;
  3985. break;
  3986. case scm_op_j:
  3987. target = j->ip + (((int32_t)j->ip[0]) >> 8);
  3988. j->op_attrs[target - j->start] |= OP_ATTR_BLOCK;
  3989. break;
  3990. case scm_op_call:
  3991. case scm_op_call_label:
  3992. attrs = OP_ATTR_BLOCK;
  3993. target = j->next_ip;
  3994. j->op_attrs[target - j->start] |= OP_ATTR_BLOCK | OP_ATTR_ENTRY;
  3995. break;
  3996. case scm_op_prompt:
  3997. target = j->ip + (((int32_t) j->ip[2]) >> 8);
  3998. j->op_attrs[target - j->start] |= OP_ATTR_BLOCK | OP_ATTR_ENTRY;
  3999. break;
  4000. default:
  4001. break;
  4002. }
  4003. }
  4004. /* Even in loops, the entry should be a jump target. */
  4005. ASSERT (j->op_attrs[j->entry - j->start] & OP_ATTR_BLOCK);
  4006. }
  4007. static void
  4008. compile (scm_jit_state *j)
  4009. {
  4010. j->ip = (uint32_t *) j->start;
  4011. set_register_state (j, SP_IN_REGISTER | FP_IN_REGISTER);
  4012. j->frame_size = -1;
  4013. for (ptrdiff_t offset = 0; j->ip + offset < j->end; offset++)
  4014. j->labels[offset] = NULL;
  4015. j->reloc_idx = 0;
  4016. while (j->ip < j->end)
  4017. {
  4018. ptrdiff_t offset = j->ip - j->start;
  4019. uint8_t attrs = j->op_attrs[offset];
  4020. j->labels[offset] = jit_address (j->jit);
  4021. if (attrs & OP_ATTR_BLOCK)
  4022. {
  4023. uint32_t state = SP_IN_REGISTER;
  4024. if (attrs & OP_ATTR_ENTRY)
  4025. state |= FP_IN_REGISTER;
  4026. j->register_state = state;
  4027. }
  4028. compile1 (j);
  4029. if (jit_has_overflow (j->jit))
  4030. return;
  4031. }
  4032. for (size_t i = 0; i < j->reloc_idx; i++)
  4033. {
  4034. void *target = j->labels[j->relocs[i].target_vcode_offset];
  4035. ASSERT(target);
  4036. jit_patch_there (j->jit, j->relocs[i].reloc, target);
  4037. }
  4038. }
  4039. static scm_i_pthread_once_t initialize_jit_once = SCM_I_PTHREAD_ONCE_INIT;
  4040. static void*
  4041. jit_alloc_fn (size_t size)
  4042. {
  4043. return scm_gc_malloc (size, "jit state");
  4044. }
  4045. static void
  4046. jit_free_fn (void *unused)
  4047. {
  4048. }
  4049. static scm_jit_state *
  4050. initialize_thread_jit_state (scm_thread *thread)
  4051. {
  4052. scm_jit_state *j;
  4053. ASSERT (!thread->jit_state);
  4054. j = scm_gc_malloc (sizeof (*j), "jit state");
  4055. memset (j, 0, sizeof (*j));
  4056. thread->jit_state = j;
  4057. j->jit = jit_new_state (jit_alloc_fn, jit_free_fn);
  4058. return j;
  4059. }
  4060. static void
  4061. initialize_jit (void)
  4062. {
  4063. scm_jit_state *j;
  4064. if (!init_jit ())
  4065. {
  4066. scm_jit_counter_threshold = -1;
  4067. fprintf (stderr, "JIT failed to initialize\n");
  4068. fprintf (stderr, "disabling automatic JIT compilation\n");
  4069. return;
  4070. }
  4071. /* Init the thread's jit state so we can emit the entry
  4072. trampoline and the handle-interrupts trampoline. */
  4073. j = initialize_thread_jit_state (SCM_I_CURRENT_THREAD);
  4074. jit_pointer_t enter_mcode_addr = emit_code (j, emit_entry_trampoline);
  4075. ASSERT (enter_mcode_addr);
  4076. enter_mcode = jit_address_to_function_pointer (enter_mcode_addr);
  4077. handle_interrupts_trampoline =
  4078. emit_code (j, emit_handle_interrupts_trampoline);
  4079. ASSERT (handle_interrupts_trampoline);
  4080. }
  4081. static uint8_t *
  4082. compute_mcode (scm_thread *thread, uint32_t *entry_ip,
  4083. struct scm_jit_function_data *data)
  4084. {
  4085. scm_jit_state *j = thread->jit_state;
  4086. uint8_t *entry_mcode;
  4087. if (!j)
  4088. {
  4089. scm_i_pthread_once (&initialize_jit_once, initialize_jit);
  4090. if (scm_jit_counter_threshold == -1)
  4091. {
  4092. /* initialization failed! */
  4093. return NULL;
  4094. }
  4095. j = thread->jit_state;
  4096. /* It's possible that initialize_jit_once inits this thread's jit
  4097. state. */
  4098. if (!j)
  4099. j = initialize_thread_jit_state (thread);
  4100. }
  4101. j->thread = thread;
  4102. j->start = (const uint32_t *) (((char *)data) + data->start);
  4103. j->end = (const uint32_t *) (((char *)data) + data->end);
  4104. j->entry = entry_ip;
  4105. ASSERT (j->start < j->end);
  4106. ASSERT (j->start <= j->entry);
  4107. ASSERT (j->entry < j->end);
  4108. j->op_attrs = calloc ((j->end - j->start), sizeof (*j->op_attrs));
  4109. ASSERT (j->op_attrs);
  4110. j->labels = calloc ((j->end - j->start), sizeof (*j->labels));
  4111. ASSERT (j->labels);
  4112. j->frame_size = -1;
  4113. INFO ("vcode: start=%p,+%zu entry=+%zu\n", j->start, j->end - j->start,
  4114. j->entry - j->start);
  4115. analyze (j);
  4116. data->mcode = emit_code (j, compile);
  4117. if (data->mcode)
  4118. entry_mcode = j->labels[j->entry - j->start];
  4119. else
  4120. entry_mcode = NULL;
  4121. free (j->op_attrs);
  4122. j->op_attrs = NULL;
  4123. free (j->labels);
  4124. j->labels = NULL;
  4125. free (j->relocs);
  4126. j->relocs = NULL;
  4127. j->reloc_idx = 0;
  4128. j->reloc_count = 0;
  4129. j->start = j->end = j->ip = j->entry = NULL;
  4130. j->frame_size = -1;
  4131. return entry_mcode;
  4132. }
  4133. const uint8_t *
  4134. scm_jit_compute_mcode (scm_thread *thread, struct scm_jit_function_data *data)
  4135. {
  4136. const uint32_t *vcode_start = (const uint32_t *) (((char *)data) + data->start);
  4137. if (data->mcode)
  4138. {
  4139. if (vcode_start == thread->vm.ip)
  4140. return data->mcode;
  4141. /* FIXME: The function has mcode, compiled via some other
  4142. activation (possibly in another thread), but right now we're
  4143. currently in an interpreted loop (not at the beginning of the
  4144. function). We should re-compute the offset into the mcode.
  4145. For now though, just punt. */
  4146. return NULL;
  4147. }
  4148. else
  4149. {
  4150. uint8_t *mcode = compute_mcode (thread, thread->vm.ip, data);
  4151. if (!mcode)
  4152. {
  4153. scm_jit_counter_threshold = -1;
  4154. fprintf (stderr, "JIT failed due to resource exhaustion\n");
  4155. fprintf (stderr, "disabling automatic JIT compilation\n");
  4156. }
  4157. else if (--jit_stop_after == 0)
  4158. {
  4159. scm_jit_counter_threshold = -1;
  4160. fprintf (stderr, "stopping automatic JIT compilation, as requested\n");
  4161. if (jit_pause_when_stopping)
  4162. {
  4163. fprintf (stderr, "sleeping for 30s; to debug:\n");
  4164. fprintf (stderr, " gdb -p %d\n\n", getpid ());
  4165. sleep (30);
  4166. }
  4167. }
  4168. return mcode;
  4169. }
  4170. }
  4171. void
  4172. scm_jit_enter_mcode (scm_thread *thread, const uint8_t *mcode)
  4173. {
  4174. LOG ("entering mcode: %p\n", mcode);
  4175. enter_mcode (thread, mcode);
  4176. LOG ("exited mcode\n");
  4177. }
  4178. void
  4179. scm_jit_state_free (scm_jit_state *j)
  4180. {
  4181. /* Nothing to do; we leave j->jit NULL between compilations. */
  4182. }
  4183. void
  4184. scm_init_jit (void)
  4185. {
  4186. scm_jit_counter_threshold = scm_getenv_int ("GUILE_JIT_THRESHOLD",
  4187. default_jit_threshold);
  4188. jit_stop_after = scm_getenv_int ("GUILE_JIT_STOP_AFTER", -1);
  4189. jit_pause_when_stopping = scm_getenv_int ("GUILE_JIT_PAUSE_WHEN_STOPPING", 0);
  4190. jit_log_level = scm_getenv_int ("GUILE_JIT_LOG", 0);
  4191. }
  4192. #endif /* ENABLE_JIT */