jit.c 142 KB

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