jit.c 171 KB

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