vm_rv64gc.cpp 472KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369
  1. /*******************************************************************************
  2. * Copyright (C) 2017, 2018 MINRES Technologies GmbH
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * 3. Neither the name of the copyright holder nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  23. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. *
  31. *******************************************************************************/
  32. #include <iss/arch/rv64gc.h>
  33. #include <iss/arch/riscv_hart_msu_vp.h>
  34. #include <iss/debugger/gdb_session.h>
  35. #include <iss/debugger/server.h>
  36. #include <iss/iss.h>
  37. #include <iss/llvm/vm_base.h>
  38. #include <util/logging.h>
  39. #define FMT_HEADER_ONLY
  40. #include <fmt/format.h>
  41. #include <array>
  42. #include <iss/debugger/riscv_target_adapter.h>
  43. namespace iss {
  44. namespace vm {
  45. namespace fp_impl {
  46. void add_fp_functions_2_module(llvm::Module *, unsigned, unsigned);
  47. }
  48. }
  49. namespace rv64gc {
  50. using namespace iss::arch;
  51. using namespace llvm;
  52. using namespace iss::debugger;
  53. using namespace iss::vm::llvm;
  54. template <typename ARCH> class vm_impl : public vm_base<ARCH> {
  55. public:
  56. using super = typename iss::vm::llvm::vm_base<ARCH>;
  57. using virt_addr_t = typename super::virt_addr_t;
  58. using phys_addr_t = typename super::phys_addr_t;
  59. using code_word_t = typename super::code_word_t;
  60. using addr_t = typename super::addr_t;
  61. vm_impl();
  62. vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0);
  63. void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; }
  64. target_adapter_if *accquire_target_adapter(server_if *srv) override {
  65. debugger_if::dbg_enabled = true;
  66. if (vm_base<ARCH>::tgt_adapter == nullptr)
  67. vm_base<ARCH>::tgt_adapter = new riscv_target_adapter<ARCH>(srv, this->get_arch());
  68. return vm_base<ARCH>::tgt_adapter;
  69. }
  70. protected:
  71. using vm_base<ARCH>::get_reg_ptr;
  72. inline const char *name(size_t index){return traits<ARCH>::reg_aliases.at(index);}
  73. template <typename T> inline ConstantInt *size(T type) {
  74. return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits()));
  75. }
  76. void setup_module(Module* m) override {
  77. super::setup_module(m);
  78. iss::vm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE, traits<ARCH>::XLEN);
  79. }
  80. inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) {
  81. return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
  82. }
  83. std::tuple<continuation_e, BasicBlock *> gen_single_inst_behavior(virt_addr_t &, unsigned int &, BasicBlock *) override;
  84. void gen_leave_behavior(BasicBlock *leave_blk) override;
  85. void gen_raise_trap(uint16_t trap_id, uint16_t cause);
  86. void gen_leave_trap(unsigned lvl);
  87. void gen_wait(unsigned type);
  88. void gen_trap_behavior(BasicBlock *) override;
  89. void gen_trap_check(BasicBlock *bb);
  90. inline Value *gen_reg_load(unsigned i, unsigned level = 0) {
  91. return this->builder.CreateLoad(get_reg_ptr(i), false);
  92. }
  93. inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
  94. Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
  95. this->get_type(traits<ARCH>::XLEN));
  96. this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
  97. }
  98. // some compile time constants
  99. // enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
  100. enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
  101. enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 };
  102. enum { LUT_SIZE = 1 << util::bit_count(EXTR_MASK32), LUT_SIZE_C = 1 << util::bit_count(EXTR_MASK16) };
  103. using this_class = vm_impl<ARCH>;
  104. using compile_func = std::tuple<continuation_e, BasicBlock *> (this_class::*)(virt_addr_t &pc,
  105. code_word_t instr,
  106. BasicBlock *bb);
  107. std::array<compile_func, LUT_SIZE> lut;
  108. std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
  109. std::array<compile_func, LUT_SIZE> lut_11;
  110. std::array<compile_func *, 4> qlut;
  111. std::array<const uint32_t, 4> lutmasks = {{EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32}};
  112. void expand_bit_mask(int pos, uint32_t mask, uint32_t value, uint32_t valid, uint32_t idx, compile_func lut[],
  113. compile_func f) {
  114. if (pos < 0) {
  115. lut[idx] = f;
  116. } else {
  117. auto bitmask = 1UL << pos;
  118. if ((mask & bitmask) == 0) {
  119. expand_bit_mask(pos - 1, mask, value, valid, idx, lut, f);
  120. } else {
  121. if ((valid & bitmask) == 0) {
  122. expand_bit_mask(pos - 1, mask, value, valid, (idx << 1), lut, f);
  123. expand_bit_mask(pos - 1, mask, value, valid, (idx << 1) + 1, lut, f);
  124. } else {
  125. auto new_val = idx << 1;
  126. if ((value & bitmask) != 0) new_val++;
  127. expand_bit_mask(pos - 1, mask, value, valid, new_val, lut, f);
  128. }
  129. }
  130. }
  131. }
  132. inline uint32_t extract_fields(uint32_t val) { return extract_fields(29, val >> 2, lutmasks[val & 0x3], 0); }
  133. uint32_t extract_fields(int pos, uint32_t val, uint32_t mask, uint32_t lut_val) {
  134. if (pos >= 0) {
  135. auto bitmask = 1UL << pos;
  136. if ((mask & bitmask) == 0) {
  137. lut_val = extract_fields(pos - 1, val, mask, lut_val);
  138. } else {
  139. auto new_val = lut_val << 1;
  140. if ((val & bitmask) != 0) new_val++;
  141. lut_val = extract_fields(pos - 1, val, mask, new_val);
  142. }
  143. }
  144. return lut_val;
  145. }
  146. private:
  147. /****************************************************************************
  148. * start opcode definitions
  149. ****************************************************************************/
  150. struct InstructionDesriptor {
  151. size_t length;
  152. uint32_t value;
  153. uint32_t mask;
  154. compile_func op;
  155. };
  156. const std::array<InstructionDesriptor, 204> instr_descr = {{
  157. /* entries are: size, valid value, valid mask, function ptr */
  158. /* instruction JALR */
  159. {32, 0b00000000000000000000000001100111, 0b00000000000000000111000001111111, &this_class::__jalr},
  160. /* instruction C.ADDI4SPN */
  161. {16, 0b0000000000000000, 0b1110000000000011, &this_class::__c_addi4spn},
  162. /* instruction C.LW */
  163. {16, 0b0100000000000000, 0b1110000000000011, &this_class::__c_lw},
  164. /* instruction C.SW */
  165. {16, 0b1100000000000000, 0b1110000000000011, &this_class::__c_sw},
  166. /* instruction C.ADDI */
  167. {16, 0b0000000000000001, 0b1110000000000011, &this_class::__c_addi},
  168. /* instruction C.NOP */
  169. {16, 0b0000000000000001, 0b1111111111111111, &this_class::__c_nop},
  170. /* instruction C.JAL */
  171. {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_jal},
  172. /* instruction C.LI */
  173. {16, 0b0100000000000001, 0b1110000000000011, &this_class::__c_li},
  174. /* instruction C.LUI */
  175. {16, 0b0110000000000001, 0b1110000000000011, &this_class::__c_lui},
  176. /* instruction C.ADDI16SP */
  177. {16, 0b0110000100000001, 0b1110111110000011, &this_class::__c_addi16sp},
  178. /* instruction C.SRLI */
  179. {16, 0b1000000000000001, 0b1110110000000011, &this_class::__c_srli},
  180. /* instruction C.SRAI */
  181. {16, 0b1000010000000001, 0b1110110000000011, &this_class::__c_srai},
  182. /* instruction C.ANDI */
  183. {16, 0b1000100000000001, 0b1110110000000011, &this_class::__c_andi},
  184. /* instruction C.SUB */
  185. {16, 0b1000110000000001, 0b1111110001100011, &this_class::__c_sub},
  186. /* instruction C.XOR */
  187. {16, 0b1000110000100001, 0b1111110001100011, &this_class::__c_xor},
  188. /* instruction C.OR */
  189. {16, 0b1000110001000001, 0b1111110001100011, &this_class::__c_or},
  190. /* instruction C.AND */
  191. {16, 0b1000110001100001, 0b1111110001100011, &this_class::__c_and},
  192. /* instruction C.J */
  193. {16, 0b1010000000000001, 0b1110000000000011, &this_class::__c_j},
  194. /* instruction C.BEQZ */
  195. {16, 0b1100000000000001, 0b1110000000000011, &this_class::__c_beqz},
  196. /* instruction C.BNEZ */
  197. {16, 0b1110000000000001, 0b1110000000000011, &this_class::__c_bnez},
  198. /* instruction C.SLLI */
  199. {16, 0b0000000000000010, 0b1110000000000011, &this_class::__c_slli},
  200. /* instruction C.LWSP */
  201. {16, 0b0100000000000010, 0b1110000000000011, &this_class::__c_lwsp},
  202. /* instruction C.MV */
  203. {16, 0b1000000000000010, 0b1111000000000011, &this_class::__c_mv},
  204. /* instruction C.JR */
  205. {16, 0b1000000000000010, 0b1111000001111111, &this_class::__c_jr},
  206. /* instruction C.ADD */
  207. {16, 0b1001000000000010, 0b1111000000000011, &this_class::__c_add},
  208. /* instruction C.JALR */
  209. {16, 0b1001000000000010, 0b1111000001111111, &this_class::__c_jalr},
  210. /* instruction C.EBREAK */
  211. {16, 0b1001000000000010, 0b1111111111111111, &this_class::__c_ebreak},
  212. /* instruction C.SWSP */
  213. {16, 0b1100000000000010, 0b1110000000000011, &this_class::__c_swsp},
  214. /* instruction DII */
  215. {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii},
  216. /* instruction C.FLD */
  217. {16, 0b0010000000000000, 0b1110000000000011, &this_class::__c_fld},
  218. /* instruction C.FSD */
  219. {16, 0b1010000000000000, 0b1110000000000011, &this_class::__c_fsd},
  220. /* instruction C.FLDSP */
  221. {16, 0b0010000000000010, 0b1110000000000011, &this_class::__c_fldsp},
  222. /* instruction C.FSDSP */
  223. {16, 0b1010000000000010, 0b1110000000000011, &this_class::__c_fsdsp},
  224. /* instruction C.FLW */
  225. {16, 0b0110000000000000, 0b1110000000000011, &this_class::__c_flw},
  226. /* instruction C.FSW */
  227. {16, 0b1110000000000000, 0b1110000000000011, &this_class::__c_fsw},
  228. /* instruction C.FLWSP */
  229. {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_flwsp},
  230. /* instruction C.FSWSP */
  231. {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_fswsp},
  232. /* instruction C.LD */
  233. {16, 0b0110000000000000, 0b1110000000000011, &this_class::__c_ld},
  234. /* instruction C.SD */
  235. {16, 0b1110000000000000, 0b1110000000000011, &this_class::__c_sd},
  236. /* instruction C.SUBW */
  237. {16, 0b1001110000000001, 0b1111110001100011, &this_class::__c_subw},
  238. /* instruction C.ADDW */
  239. {16, 0b1001110000100001, 0b1111110001100011, &this_class::__c_addw},
  240. /* instruction C.ADDIW */
  241. {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_addiw},
  242. /* instruction C.LDSP */
  243. {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_ldsp},
  244. /* instruction C.SDSP */
  245. {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_sdsp},
  246. /* instruction FLD */
  247. {32, 0b00000000000000000011000000000111, 0b00000000000000000111000001111111, &this_class::__fld},
  248. /* instruction FSD */
  249. {32, 0b00000000000000000011000000100111, 0b00000000000000000111000001111111, &this_class::__fsd},
  250. /* instruction FMADD.D */
  251. {32, 0b00000010000000000000000001000011, 0b00000110000000000000000001111111, &this_class::__fmadd_d},
  252. /* instruction FMSUB.D */
  253. {32, 0b00000010000000000000000001000111, 0b00000110000000000000000001111111, &this_class::__fmsub_d},
  254. /* instruction FNMADD.D */
  255. {32, 0b00000010000000000000000001001111, 0b00000110000000000000000001111111, &this_class::__fnmadd_d},
  256. /* instruction FNMSUB.D */
  257. {32, 0b00000010000000000000000001001011, 0b00000110000000000000000001111111, &this_class::__fnmsub_d},
  258. /* instruction FADD.D */
  259. {32, 0b00000010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fadd_d},
  260. /* instruction FSUB.D */
  261. {32, 0b00001010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fsub_d},
  262. /* instruction FMUL.D */
  263. {32, 0b00010010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fmul_d},
  264. /* instruction FDIV.D */
  265. {32, 0b00011010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fdiv_d},
  266. /* instruction FSQRT.D */
  267. {32, 0b01011010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fsqrt_d},
  268. /* instruction FSGNJ.D */
  269. {32, 0b00100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnj_d},
  270. /* instruction FSGNJN.D */
  271. {32, 0b00100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjn_d},
  272. /* instruction FSGNJX.D */
  273. {32, 0b00100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjx_d},
  274. /* instruction FMIN.D */
  275. {32, 0b00101010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fmin_d},
  276. /* instruction FMAX.D */
  277. {32, 0b00101010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fmax_d},
  278. /* instruction FCVT.S.D */
  279. {32, 0b01000000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_d},
  280. /* instruction FCVT.D.S */
  281. {32, 0b01000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_s},
  282. /* instruction FEQ.D */
  283. {32, 0b10100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__feq_d},
  284. /* instruction FLT.D */
  285. {32, 0b10100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__flt_d},
  286. /* instruction FLE.D */
  287. {32, 0b10100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fle_d},
  288. /* instruction FCLASS.D */
  289. {32, 0b11100010000000000001000001010011, 0b11111111111100000111000001111111, &this_class::__fclass_d},
  290. /* instruction FCVT.W.D */
  291. {32, 0b11000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_w_d},
  292. /* instruction FCVT.WU.D */
  293. {32, 0b11000010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_wu_d},
  294. /* instruction FCVT.D.W */
  295. {32, 0b11010010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_w},
  296. /* instruction FCVT.D.WU */
  297. {32, 0b11010010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_wu},
  298. /* instruction FCVT.L.D */
  299. {32, 0b11000010001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_l_d},
  300. /* instruction FCVT.LU.D */
  301. {32, 0b11000010001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_lu_d},
  302. /* instruction FCVT.D.L */
  303. {32, 0b11010010001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_l},
  304. /* instruction FCVT.D.LU */
  305. {32, 0b11010010001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_lu},
  306. /* instruction FMV.X.D */
  307. {32, 0b11100010000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_x_d},
  308. /* instruction FMV.D.X */
  309. {32, 0b11110010000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_d_x},
  310. /* instruction LUI */
  311. {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui},
  312. /* instruction AUIPC */
  313. {32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, &this_class::__auipc},
  314. /* instruction JAL */
  315. {32, 0b00000000000000000000000001101111, 0b00000000000000000000000001111111, &this_class::__jal},
  316. /* instruction BEQ */
  317. {32, 0b00000000000000000000000001100011, 0b00000000000000000111000001111111, &this_class::__beq},
  318. /* instruction BNE */
  319. {32, 0b00000000000000000001000001100011, 0b00000000000000000111000001111111, &this_class::__bne},
  320. /* instruction BLT */
  321. {32, 0b00000000000000000100000001100011, 0b00000000000000000111000001111111, &this_class::__blt},
  322. /* instruction BGE */
  323. {32, 0b00000000000000000101000001100011, 0b00000000000000000111000001111111, &this_class::__bge},
  324. /* instruction BLTU */
  325. {32, 0b00000000000000000110000001100011, 0b00000000000000000111000001111111, &this_class::__bltu},
  326. /* instruction BGEU */
  327. {32, 0b00000000000000000111000001100011, 0b00000000000000000111000001111111, &this_class::__bgeu},
  328. /* instruction LB */
  329. {32, 0b00000000000000000000000000000011, 0b00000000000000000111000001111111, &this_class::__lb},
  330. /* instruction LH */
  331. {32, 0b00000000000000000001000000000011, 0b00000000000000000111000001111111, &this_class::__lh},
  332. /* instruction LW */
  333. {32, 0b00000000000000000010000000000011, 0b00000000000000000111000001111111, &this_class::__lw},
  334. /* instruction LBU */
  335. {32, 0b00000000000000000100000000000011, 0b00000000000000000111000001111111, &this_class::__lbu},
  336. /* instruction LHU */
  337. {32, 0b00000000000000000101000000000011, 0b00000000000000000111000001111111, &this_class::__lhu},
  338. /* instruction SB */
  339. {32, 0b00000000000000000000000000100011, 0b00000000000000000111000001111111, &this_class::__sb},
  340. /* instruction SH */
  341. {32, 0b00000000000000000001000000100011, 0b00000000000000000111000001111111, &this_class::__sh},
  342. /* instruction SW */
  343. {32, 0b00000000000000000010000000100011, 0b00000000000000000111000001111111, &this_class::__sw},
  344. /* instruction ADDI */
  345. {32, 0b00000000000000000000000000010011, 0b00000000000000000111000001111111, &this_class::__addi},
  346. /* instruction SLTI */
  347. {32, 0b00000000000000000010000000010011, 0b00000000000000000111000001111111, &this_class::__slti},
  348. /* instruction SLTIU */
  349. {32, 0b00000000000000000011000000010011, 0b00000000000000000111000001111111, &this_class::__sltiu},
  350. /* instruction XORI */
  351. {32, 0b00000000000000000100000000010011, 0b00000000000000000111000001111111, &this_class::__xori},
  352. /* instruction ORI */
  353. {32, 0b00000000000000000110000000010011, 0b00000000000000000111000001111111, &this_class::__ori},
  354. /* instruction ANDI */
  355. {32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, &this_class::__andi},
  356. /* instruction SLLI */
  357. {32, 0b00000000000000000001000000010011, 0b11111100000000000111000001111111, &this_class::__slli},
  358. /* instruction SRLI */
  359. {32, 0b00000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srli},
  360. /* instruction SRAI */
  361. {32, 0b01000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srai},
  362. /* instruction ADD */
  363. {32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__add},
  364. /* instruction SUB */
  365. {32, 0b01000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__sub},
  366. /* instruction SLL */
  367. {32, 0b00000000000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__sll},
  368. /* instruction SLT */
  369. {32, 0b00000000000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__slt},
  370. /* instruction SLTU */
  371. {32, 0b00000000000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__sltu},
  372. /* instruction XOR */
  373. {32, 0b00000000000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__xor},
  374. /* instruction SRL */
  375. {32, 0b00000000000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__srl},
  376. /* instruction SRA */
  377. {32, 0b01000000000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__sra},
  378. /* instruction OR */
  379. {32, 0b00000000000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__or},
  380. /* instruction AND */
  381. {32, 0b00000000000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__and},
  382. /* instruction FENCE */
  383. {32, 0b00000000000000000000000000001111, 0b11110000000000000111000001111111, &this_class::__fence},
  384. /* instruction FENCE_I */
  385. {32, 0b00000000000000000001000000001111, 0b00000000000000000111000001111111, &this_class::__fence_i},
  386. /* instruction ECALL */
  387. {32, 0b00000000000000000000000001110011, 0b11111111111111111111111111111111, &this_class::__ecall},
  388. /* instruction EBREAK */
  389. {32, 0b00000000000100000000000001110011, 0b11111111111111111111111111111111, &this_class::__ebreak},
  390. /* instruction URET */
  391. {32, 0b00000000001000000000000001110011, 0b11111111111111111111111111111111, &this_class::__uret},
  392. /* instruction SRET */
  393. {32, 0b00010000001000000000000001110011, 0b11111111111111111111111111111111, &this_class::__sret},
  394. /* instruction MRET */
  395. {32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, &this_class::__mret},
  396. /* instruction WFI */
  397. {32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, &this_class::__wfi},
  398. /* instruction SFENCE.VMA */
  399. {32, 0b00010010000000000000000001110011, 0b11111110000000000111111111111111, &this_class::__sfence_vma},
  400. /* instruction CSRRW */
  401. {32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, &this_class::__csrrw},
  402. /* instruction CSRRS */
  403. {32, 0b00000000000000000010000001110011, 0b00000000000000000111000001111111, &this_class::__csrrs},
  404. /* instruction CSRRC */
  405. {32, 0b00000000000000000011000001110011, 0b00000000000000000111000001111111, &this_class::__csrrc},
  406. /* instruction CSRRWI */
  407. {32, 0b00000000000000000101000001110011, 0b00000000000000000111000001111111, &this_class::__csrrwi},
  408. /* instruction CSRRSI */
  409. {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi},
  410. /* instruction CSRRCI */
  411. {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci},
  412. /* instruction FLW */
  413. {32, 0b00000000000000000010000000000111, 0b00000000000000000111000001111111, &this_class::__flw},
  414. /* instruction FSW */
  415. {32, 0b00000000000000000010000000100111, 0b00000000000000000111000001111111, &this_class::__fsw},
  416. /* instruction FMADD.S */
  417. {32, 0b00000000000000000000000001000011, 0b00000110000000000000000001111111, &this_class::__fmadd_s},
  418. /* instruction FMSUB.S */
  419. {32, 0b00000000000000000000000001000111, 0b00000110000000000000000001111111, &this_class::__fmsub_s},
  420. /* instruction FNMADD.S */
  421. {32, 0b00000000000000000000000001001111, 0b00000110000000000000000001111111, &this_class::__fnmadd_s},
  422. /* instruction FNMSUB.S */
  423. {32, 0b00000000000000000000000001001011, 0b00000110000000000000000001111111, &this_class::__fnmsub_s},
  424. /* instruction FADD.S */
  425. {32, 0b00000000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fadd_s},
  426. /* instruction FSUB.S */
  427. {32, 0b00001000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fsub_s},
  428. /* instruction FMUL.S */
  429. {32, 0b00010000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fmul_s},
  430. /* instruction FDIV.S */
  431. {32, 0b00011000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fdiv_s},
  432. /* instruction FSQRT.S */
  433. {32, 0b01011000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fsqrt_s},
  434. /* instruction FSGNJ.S */
  435. {32, 0b00100000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnj_s},
  436. /* instruction FSGNJN.S */
  437. {32, 0b00100000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjn_s},
  438. /* instruction FSGNJX.S */
  439. {32, 0b00100000000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjx_s},
  440. /* instruction FMIN.S */
  441. {32, 0b00101000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fmin_s},
  442. /* instruction FMAX.S */
  443. {32, 0b00101000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fmax_s},
  444. /* instruction FCVT.W.S */
  445. {32, 0b11000000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_w_s},
  446. /* instruction FCVT.WU.S */
  447. {32, 0b11000000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_wu_s},
  448. /* instruction FEQ.S */
  449. {32, 0b10100000000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__feq_s},
  450. /* instruction FLT.S */
  451. {32, 0b10100000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__flt_s},
  452. /* instruction FLE.S */
  453. {32, 0b10100000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fle_s},
  454. /* instruction FCLASS.S */
  455. {32, 0b11100000000000000001000001010011, 0b11111111111100000111000001111111, &this_class::__fclass_s},
  456. /* instruction FCVT.S.W */
  457. {32, 0b11010000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_w},
  458. /* instruction FCVT.S.WU */
  459. {32, 0b11010000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_wu},
  460. /* instruction FMV.X.W */
  461. {32, 0b11100000000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_x_w},
  462. /* instruction FMV.W.X */
  463. {32, 0b11110000000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_w_x},
  464. /* instruction FCVT.L.S */
  465. {32, 0b11000000001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_l_s},
  466. /* instruction FCVT.LU.S */
  467. {32, 0b11000000001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_lu_s},
  468. /* instruction FCVT.S.L */
  469. {32, 0b11010000001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_l},
  470. /* instruction FCVT.S.LU */
  471. {32, 0b11010000001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_lu},
  472. /* instruction LR.W */
  473. {32, 0b00010000000000000010000000101111, 0b11111001111100000111000001111111, &this_class::__lr_w},
  474. /* instruction SC.W */
  475. {32, 0b00011000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__sc_w},
  476. /* instruction AMOSWAP.W */
  477. {32, 0b00001000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_w},
  478. /* instruction AMOADD.W */
  479. {32, 0b00000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_w},
  480. /* instruction AMOXOR.W */
  481. {32, 0b00100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_w},
  482. /* instruction AMOAND.W */
  483. {32, 0b01100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_w},
  484. /* instruction AMOOR.W */
  485. {32, 0b01000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_w},
  486. /* instruction AMOMIN.W */
  487. {32, 0b10000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_w},
  488. /* instruction AMOMAX.W */
  489. {32, 0b10100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_w},
  490. /* instruction AMOMINU.W */
  491. {32, 0b11000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_w},
  492. /* instruction AMOMAXU.W */
  493. {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w},
  494. /* instruction LR.D */
  495. {32, 0b00010000000000000011000000101111, 0b11111001111100000111000001111111, &this_class::__lr_d},
  496. /* instruction SC.D */
  497. {32, 0b00011000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__sc_d},
  498. /* instruction AMOSWAP.D */
  499. {32, 0b00001000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_d},
  500. /* instruction AMOADD.D */
  501. {32, 0b00000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_d},
  502. /* instruction AMOXOR.D */
  503. {32, 0b00100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_d},
  504. /* instruction AMOAND.D */
  505. {32, 0b01100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_d},
  506. /* instruction AMOOR.D */
  507. {32, 0b01000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_d},
  508. /* instruction AMOMIN.D */
  509. {32, 0b10000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_d},
  510. /* instruction AMOMAX.D */
  511. {32, 0b10100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_d},
  512. /* instruction AMOMINU.D */
  513. {32, 0b11000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_d},
  514. /* instruction AMOMAXU.D */
  515. {32, 0b11100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_d},
  516. /* instruction MUL */
  517. {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul},
  518. /* instruction MULH */
  519. {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh},
  520. /* instruction MULHSU */
  521. {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu},
  522. /* instruction MULHU */
  523. {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu},
  524. /* instruction DIV */
  525. {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div},
  526. /* instruction DIVU */
  527. {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu},
  528. /* instruction REM */
  529. {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem},
  530. /* instruction REMU */
  531. {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu},
  532. /* instruction MULW */
  533. {32, 0b00000010000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__mulw},
  534. /* instruction DIVW */
  535. {32, 0b00000010000000000100000000111011, 0b11111110000000000111000001111111, &this_class::__divw},
  536. /* instruction DIVUW */
  537. {32, 0b00000010000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__divuw},
  538. /* instruction REMW */
  539. {32, 0b00000010000000000110000000111011, 0b11111110000000000111000001111111, &this_class::__remw},
  540. /* instruction REMUW */
  541. {32, 0b00000010000000000111000000111011, 0b11111110000000000111000001111111, &this_class::__remuw},
  542. /* instruction LWU */
  543. {32, 0b00000000000000000110000000000011, 0b00000000000000000111000001111111, &this_class::__lwu},
  544. /* instruction LD */
  545. {32, 0b00000000000000000011000000000011, 0b00000000000000000111000001111111, &this_class::__ld},
  546. /* instruction SD */
  547. {32, 0b00000000000000000011000000100011, 0b00000000000000000111000001111111, &this_class::__sd},
  548. /* instruction ADDIW */
  549. {32, 0b00000000000000000000000000011011, 0b00000000000000000111000001111111, &this_class::__addiw},
  550. /* instruction SLLIW */
  551. {32, 0b00000000000000000001000000011011, 0b11111110000000000111000001111111, &this_class::__slliw},
  552. /* instruction SRLIW */
  553. {32, 0b00000000000000000101000000011011, 0b11111110000000000111000001111111, &this_class::__srliw},
  554. /* instruction SRAIW */
  555. {32, 0b01000000000000000101000000011011, 0b11111110000000000111000001111111, &this_class::__sraiw},
  556. /* instruction ADDW */
  557. {32, 0b00000000000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__addw},
  558. /* instruction SUBW */
  559. {32, 0b01000000000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__subw},
  560. /* instruction SLLW */
  561. {32, 0b00000000000000000001000000111011, 0b11111110000000000111000001111111, &this_class::__sllw},
  562. /* instruction SRLW */
  563. {32, 0b00000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__srlw},
  564. /* instruction SRAW */
  565. {32, 0b01000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__sraw},
  566. }};
  567. /* instruction definitions */
  568. /* instruction 0: JALR */
  569. std::tuple<continuation_e, BasicBlock*> __jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  570. bb->setName("JALR");
  571. this->gen_sync(PRE_SYNC, 0);
  572. uint8_t rd = ((bit_sub<7,5>(instr)));
  573. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  574. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  575. if(this->disass_enabled){
  576. /* generate console output when executing the command */
  577. auto mnemonic = fmt::format(
  578. "{mnemonic:10} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"),
  579. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
  580. std::vector<Value*> args {
  581. this->core_ptr,
  582. this->gen_const(64, pc.val),
  583. this->builder.CreateGlobalStringPtr(mnemonic),
  584. };
  585. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  586. }
  587. Value* cur_pc_val = this->gen_const(64, pc.val);
  588. pc=pc+4;
  589. Value* new_pc_val = this->builder.CreateAdd(
  590. this->gen_ext(
  591. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  592. 64, true),
  593. this->gen_const(64U, imm));
  594. Value* align_val = this->builder.CreateAnd(
  595. new_pc_val,
  596. this->gen_const(64U, 0x2));
  597. {
  598. BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk);
  599. BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext);
  600. BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext);
  601. // this->builder.SetInsertPoint(bb);
  602. this->gen_cond_branch(this->builder.CreateICmp(
  603. ICmpInst::ICMP_NE,
  604. align_val,
  605. this->gen_const(64U, 0)),
  606. bb_then,
  607. bb_else);
  608. this->builder.SetInsertPoint(bb_then);
  609. {
  610. this->gen_raise_trap(0, 0);
  611. }
  612. this->builder.CreateBr(bbnext);
  613. this->builder.SetInsertPoint(bb_else);
  614. {
  615. if(rd != 0){
  616. Value* Xtmp0_val = this->builder.CreateAdd(
  617. cur_pc_val,
  618. this->gen_const(64U, 4));
  619. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  620. }
  621. Value* PC_val = this->builder.CreateAnd(
  622. new_pc_val,
  623. this->builder.CreateNot(this->gen_const(64U, 0x1)));
  624. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  625. this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  626. }
  627. this->builder.CreateBr(bbnext);
  628. bb=bbnext;
  629. }
  630. this->builder.SetInsertPoint(bb);
  631. this->gen_sync(POST_SYNC, 0);
  632. this->gen_trap_check(this->leave_blk);
  633. return std::make_tuple(BRANCH, nullptr);
  634. }
  635. /* instruction 1: C.ADDI4SPN */
  636. std::tuple<continuation_e, BasicBlock*> __c_addi4spn(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  637. bb->setName("C.ADDI4SPN");
  638. this->gen_sync(PRE_SYNC, 1);
  639. uint8_t rd = ((bit_sub<2,3>(instr)));
  640. uint16_t imm = ((bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4));
  641. if(this->disass_enabled){
  642. /* generate console output when executing the command */
  643. auto mnemonic = fmt::format(
  644. "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.addi4spn"),
  645. fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
  646. std::vector<Value*> args {
  647. this->core_ptr,
  648. this->gen_const(64, pc.val),
  649. this->builder.CreateGlobalStringPtr(mnemonic),
  650. };
  651. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  652. }
  653. Value* cur_pc_val = this->gen_const(64, pc.val);
  654. pc=pc+2;
  655. if(imm == 0){
  656. this->gen_raise_trap(0, 2);
  657. }
  658. Value* Xtmp0_val = this->builder.CreateAdd(
  659. this->gen_reg_load(2 + traits<ARCH>::X0, 0),
  660. this->gen_const(64U, imm));
  661. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits<ARCH>::X0), false);
  662. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  663. this->gen_sync(POST_SYNC, 1);
  664. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  665. this->gen_trap_check(bb);
  666. return std::make_tuple(CONT, bb);
  667. }
  668. /* instruction 2: C.LW */
  669. std::tuple<continuation_e, BasicBlock*> __c_lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  670. bb->setName("C.LW");
  671. this->gen_sync(PRE_SYNC, 2);
  672. uint8_t rd = ((bit_sub<2,3>(instr)));
  673. uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3));
  674. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  675. if(this->disass_enabled){
  676. /* generate console output when executing the command */
  677. auto mnemonic = fmt::format(
  678. "{mnemonic:10} {rd}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.lw"),
  679. fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1)));
  680. std::vector<Value*> args {
  681. this->core_ptr,
  682. this->gen_const(64, pc.val),
  683. this->builder.CreateGlobalStringPtr(mnemonic),
  684. };
  685. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  686. }
  687. Value* cur_pc_val = this->gen_const(64, pc.val);
  688. pc=pc+2;
  689. Value* offs_val = this->builder.CreateAdd(
  690. this->gen_reg_load(rs1 + 8 + traits<ARCH>::X0, 0),
  691. this->gen_const(64U, uimm));
  692. Value* Xtmp0_val = this->gen_ext(
  693. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8),
  694. 64,
  695. true);
  696. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits<ARCH>::X0), false);
  697. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  698. this->gen_sync(POST_SYNC, 2);
  699. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  700. this->gen_trap_check(bb);
  701. return std::make_tuple(CONT, bb);
  702. }
  703. /* instruction 3: C.SW */
  704. std::tuple<continuation_e, BasicBlock*> __c_sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  705. bb->setName("C.SW");
  706. this->gen_sync(PRE_SYNC, 3);
  707. uint8_t rs2 = ((bit_sub<2,3>(instr)));
  708. uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3));
  709. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  710. if(this->disass_enabled){
  711. /* generate console output when executing the command */
  712. auto mnemonic = fmt::format(
  713. "{mnemonic:10} {rs2}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.sw"),
  714. fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1)));
  715. std::vector<Value*> args {
  716. this->core_ptr,
  717. this->gen_const(64, pc.val),
  718. this->builder.CreateGlobalStringPtr(mnemonic),
  719. };
  720. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  721. }
  722. Value* cur_pc_val = this->gen_const(64, pc.val);
  723. pc=pc+2;
  724. Value* offs_val = this->builder.CreateAdd(
  725. this->gen_reg_load(rs1 + 8 + traits<ARCH>::X0, 0),
  726. this->gen_const(64U, uimm));
  727. Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits<ARCH>::X0, 0);
  728. this->gen_write_mem(
  729. traits<ARCH>::MEM,
  730. offs_val,
  731. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32)));
  732. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  733. this->gen_sync(POST_SYNC, 3);
  734. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  735. this->gen_trap_check(bb);
  736. return std::make_tuple(CONT, bb);
  737. }
  738. /* instruction 4: C.ADDI */
  739. std::tuple<continuation_e, BasicBlock*> __c_addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  740. bb->setName("C.ADDI");
  741. this->gen_sync(PRE_SYNC, 4);
  742. int8_t imm = signextend<int8_t,6>((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
  743. uint8_t rs1 = ((bit_sub<7,5>(instr)));
  744. if(this->disass_enabled){
  745. /* generate console output when executing the command */
  746. auto mnemonic = fmt::format(
  747. "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addi"),
  748. fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
  749. std::vector<Value*> args {
  750. this->core_ptr,
  751. this->gen_const(64, pc.val),
  752. this->builder.CreateGlobalStringPtr(mnemonic),
  753. };
  754. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  755. }
  756. Value* cur_pc_val = this->gen_const(64, pc.val);
  757. pc=pc+2;
  758. Value* Xtmp0_val = this->builder.CreateAdd(
  759. this->gen_ext(
  760. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  761. 64, true),
  762. this->gen_const(64U, imm));
  763. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits<ARCH>::X0), false);
  764. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  765. this->gen_sync(POST_SYNC, 4);
  766. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  767. this->gen_trap_check(bb);
  768. return std::make_tuple(CONT, bb);
  769. }
  770. /* instruction 5: C.NOP */
  771. std::tuple<continuation_e, BasicBlock*> __c_nop(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  772. bb->setName("C.NOP");
  773. this->gen_sync(PRE_SYNC, 5);
  774. if(this->disass_enabled){
  775. /* generate console output when executing the command */
  776. std::vector<Value*> args {
  777. this->core_ptr,
  778. this->gen_const(64, pc.val),
  779. this->builder.CreateGlobalStringPtr("c.nop"),
  780. };
  781. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  782. }
  783. Value* cur_pc_val = this->gen_const(64, pc.val);
  784. pc=pc+2;
  785. /* TODO: describe operations for C.NOP ! */
  786. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  787. this->gen_sync(POST_SYNC, 5);
  788. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  789. this->gen_trap_check(bb);
  790. return std::make_tuple(CONT, bb);
  791. }
  792. /* instruction 6: C.JAL */
  793. std::tuple<continuation_e, BasicBlock*> __c_jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  794. bb->setName("C.JAL");
  795. this->gen_sync(PRE_SYNC, 6);
  796. int16_t imm = signextend<int16_t,12>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11));
  797. if(this->disass_enabled){
  798. /* generate console output when executing the command */
  799. auto mnemonic = fmt::format(
  800. "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.jal"),
  801. fmt::arg("imm", imm));
  802. std::vector<Value*> args {
  803. this->core_ptr,
  804. this->gen_const(64, pc.val),
  805. this->builder.CreateGlobalStringPtr(mnemonic),
  806. };
  807. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  808. }
  809. Value* cur_pc_val = this->gen_const(64, pc.val);
  810. pc=pc+2;
  811. Value* Xtmp0_val = this->builder.CreateAdd(
  812. cur_pc_val,
  813. this->gen_const(64U, 2));
  814. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits<ARCH>::X0), false);
  815. Value* PC_val = this->builder.CreateAdd(
  816. this->gen_ext(
  817. cur_pc_val,
  818. 64, true),
  819. this->gen_const(64U, imm));
  820. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  821. Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v");
  822. this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  823. this->gen_sync(POST_SYNC, 6);
  824. this->gen_trap_check(this->leave_blk);
  825. return std::make_tuple(BRANCH, nullptr);
  826. }
  827. /* instruction 7: C.LI */
  828. std::tuple<continuation_e, BasicBlock*> __c_li(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  829. bb->setName("C.LI");
  830. this->gen_sync(PRE_SYNC, 7);
  831. int8_t imm = signextend<int8_t,6>((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
  832. uint8_t rd = ((bit_sub<7,5>(instr)));
  833. if(this->disass_enabled){
  834. /* generate console output when executing the command */
  835. auto mnemonic = fmt::format(
  836. "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.li"),
  837. fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
  838. std::vector<Value*> args {
  839. this->core_ptr,
  840. this->gen_const(64, pc.val),
  841. this->builder.CreateGlobalStringPtr(mnemonic),
  842. };
  843. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  844. }
  845. Value* cur_pc_val = this->gen_const(64, pc.val);
  846. pc=pc+2;
  847. if(rd == 0){
  848. this->gen_raise_trap(0, 2);
  849. }
  850. Value* Xtmp0_val = this->gen_const(64U, imm);
  851. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  852. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  853. this->gen_sync(POST_SYNC, 7);
  854. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  855. this->gen_trap_check(bb);
  856. return std::make_tuple(CONT, bb);
  857. }
  858. /* instruction 8: C.LUI */
  859. std::tuple<continuation_e, BasicBlock*> __c_lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  860. bb->setName("C.LUI");
  861. this->gen_sync(PRE_SYNC, 8);
  862. int32_t imm = signextend<int32_t,18>((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17));
  863. uint8_t rd = ((bit_sub<7,5>(instr)));
  864. if(this->disass_enabled){
  865. /* generate console output when executing the command */
  866. auto mnemonic = fmt::format(
  867. "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.lui"),
  868. fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
  869. std::vector<Value*> args {
  870. this->core_ptr,
  871. this->gen_const(64, pc.val),
  872. this->builder.CreateGlobalStringPtr(mnemonic),
  873. };
  874. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  875. }
  876. Value* cur_pc_val = this->gen_const(64, pc.val);
  877. pc=pc+2;
  878. if(rd == 0){
  879. this->gen_raise_trap(0, 2);
  880. }
  881. if(imm == 0){
  882. this->gen_raise_trap(0, 2);
  883. }
  884. Value* Xtmp0_val = this->gen_const(64U, imm);
  885. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  886. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  887. this->gen_sync(POST_SYNC, 8);
  888. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  889. this->gen_trap_check(bb);
  890. return std::make_tuple(CONT, bb);
  891. }
  892. /* instruction 9: C.ADDI16SP */
  893. std::tuple<continuation_e, BasicBlock*> __c_addi16sp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  894. bb->setName("C.ADDI16SP");
  895. this->gen_sync(PRE_SYNC, 9);
  896. int16_t imm = signextend<int16_t,10>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9));
  897. if(this->disass_enabled){
  898. /* generate console output when executing the command */
  899. auto mnemonic = fmt::format(
  900. "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.addi16sp"),
  901. fmt::arg("imm", imm));
  902. std::vector<Value*> args {
  903. this->core_ptr,
  904. this->gen_const(64, pc.val),
  905. this->builder.CreateGlobalStringPtr(mnemonic),
  906. };
  907. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  908. }
  909. Value* cur_pc_val = this->gen_const(64, pc.val);
  910. pc=pc+2;
  911. Value* Xtmp0_val = this->builder.CreateAdd(
  912. this->gen_ext(
  913. this->gen_reg_load(2 + traits<ARCH>::X0, 0),
  914. 64, true),
  915. this->gen_const(64U, imm));
  916. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(2 + traits<ARCH>::X0), false);
  917. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  918. this->gen_sync(POST_SYNC, 9);
  919. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  920. this->gen_trap_check(bb);
  921. return std::make_tuple(CONT, bb);
  922. }
  923. /* instruction 10: C.SRLI */
  924. std::tuple<continuation_e, BasicBlock*> __c_srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  925. bb->setName("C.SRLI");
  926. this->gen_sync(PRE_SYNC, 10);
  927. uint8_t shamt = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
  928. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  929. if(this->disass_enabled){
  930. /* generate console output when executing the command */
  931. auto mnemonic = fmt::format(
  932. "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srli"),
  933. fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt));
  934. std::vector<Value*> args {
  935. this->core_ptr,
  936. this->gen_const(64, pc.val),
  937. this->builder.CreateGlobalStringPtr(mnemonic),
  938. };
  939. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  940. }
  941. Value* cur_pc_val = this->gen_const(64, pc.val);
  942. pc=pc+2;
  943. uint8_t rs1_idx_val = rs1 + 8;
  944. Value* Xtmp0_val = this->builder.CreateLShr(
  945. this->gen_reg_load(rs1_idx_val + traits<ARCH>::X0, 0),
  946. this->gen_const(64U, shamt));
  947. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits<ARCH>::X0), false);
  948. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  949. this->gen_sync(POST_SYNC, 10);
  950. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  951. this->gen_trap_check(bb);
  952. return std::make_tuple(CONT, bb);
  953. }
  954. /* instruction 11: C.SRAI */
  955. std::tuple<continuation_e, BasicBlock*> __c_srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  956. bb->setName("C.SRAI");
  957. this->gen_sync(PRE_SYNC, 11);
  958. uint8_t shamt = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
  959. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  960. if(this->disass_enabled){
  961. /* generate console output when executing the command */
  962. auto mnemonic = fmt::format(
  963. "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srai"),
  964. fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt));
  965. std::vector<Value*> args {
  966. this->core_ptr,
  967. this->gen_const(64, pc.val),
  968. this->builder.CreateGlobalStringPtr(mnemonic),
  969. };
  970. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  971. }
  972. Value* cur_pc_val = this->gen_const(64, pc.val);
  973. pc=pc+2;
  974. uint8_t rs1_idx_val = rs1 + 8;
  975. Value* Xtmp0_val = this->builder.CreateAShr(
  976. this->gen_reg_load(rs1_idx_val + traits<ARCH>::X0, 0),
  977. this->gen_const(64U, shamt));
  978. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits<ARCH>::X0), false);
  979. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  980. this->gen_sync(POST_SYNC, 11);
  981. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  982. this->gen_trap_check(bb);
  983. return std::make_tuple(CONT, bb);
  984. }
  985. /* instruction 12: C.ANDI */
  986. std::tuple<continuation_e, BasicBlock*> __c_andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  987. bb->setName("C.ANDI");
  988. this->gen_sync(PRE_SYNC, 12);
  989. int8_t imm = signextend<int8_t,6>((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
  990. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  991. if(this->disass_enabled){
  992. /* generate console output when executing the command */
  993. auto mnemonic = fmt::format(
  994. "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.andi"),
  995. fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm));
  996. std::vector<Value*> args {
  997. this->core_ptr,
  998. this->gen_const(64, pc.val),
  999. this->builder.CreateGlobalStringPtr(mnemonic),
  1000. };
  1001. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1002. }
  1003. Value* cur_pc_val = this->gen_const(64, pc.val);
  1004. pc=pc+2;
  1005. uint8_t rs1_idx_val = rs1 + 8;
  1006. Value* Xtmp0_val = this->builder.CreateAnd(
  1007. this->gen_ext(
  1008. this->gen_reg_load(rs1_idx_val + traits<ARCH>::X0, 0),
  1009. 64, true),
  1010. this->gen_const(64U, imm));
  1011. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits<ARCH>::X0), false);
  1012. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1013. this->gen_sync(POST_SYNC, 12);
  1014. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1015. this->gen_trap_check(bb);
  1016. return std::make_tuple(CONT, bb);
  1017. }
  1018. /* instruction 13: C.SUB */
  1019. std::tuple<continuation_e, BasicBlock*> __c_sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1020. bb->setName("C.SUB");
  1021. this->gen_sync(PRE_SYNC, 13);
  1022. uint8_t rs2 = ((bit_sub<2,3>(instr)));
  1023. uint8_t rd = ((bit_sub<7,3>(instr)));
  1024. if(this->disass_enabled){
  1025. /* generate console output when executing the command */
  1026. auto mnemonic = fmt::format(
  1027. "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.sub"),
  1028. fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2)));
  1029. std::vector<Value*> args {
  1030. this->core_ptr,
  1031. this->gen_const(64, pc.val),
  1032. this->builder.CreateGlobalStringPtr(mnemonic),
  1033. };
  1034. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1035. }
  1036. Value* cur_pc_val = this->gen_const(64, pc.val);
  1037. pc=pc+2;
  1038. uint8_t rd_idx_val = rd + 8;
  1039. Value* Xtmp0_val = this->builder.CreateSub(
  1040. this->gen_reg_load(rd_idx_val + traits<ARCH>::X0, 0),
  1041. this->gen_reg_load(rs2 + 8 + traits<ARCH>::X0, 0));
  1042. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits<ARCH>::X0), false);
  1043. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1044. this->gen_sync(POST_SYNC, 13);
  1045. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1046. this->gen_trap_check(bb);
  1047. return std::make_tuple(CONT, bb);
  1048. }
  1049. /* instruction 14: C.XOR */
  1050. std::tuple<continuation_e, BasicBlock*> __c_xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1051. bb->setName("C.XOR");
  1052. this->gen_sync(PRE_SYNC, 14);
  1053. uint8_t rs2 = ((bit_sub<2,3>(instr)));
  1054. uint8_t rd = ((bit_sub<7,3>(instr)));
  1055. if(this->disass_enabled){
  1056. /* generate console output when executing the command */
  1057. auto mnemonic = fmt::format(
  1058. "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.xor"),
  1059. fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2)));
  1060. std::vector<Value*> args {
  1061. this->core_ptr,
  1062. this->gen_const(64, pc.val),
  1063. this->builder.CreateGlobalStringPtr(mnemonic),
  1064. };
  1065. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1066. }
  1067. Value* cur_pc_val = this->gen_const(64, pc.val);
  1068. pc=pc+2;
  1069. uint8_t rd_idx_val = rd + 8;
  1070. Value* Xtmp0_val = this->builder.CreateXor(
  1071. this->gen_reg_load(rd_idx_val + traits<ARCH>::X0, 0),
  1072. this->gen_reg_load(rs2 + 8 + traits<ARCH>::X0, 0));
  1073. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits<ARCH>::X0), false);
  1074. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1075. this->gen_sync(POST_SYNC, 14);
  1076. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1077. this->gen_trap_check(bb);
  1078. return std::make_tuple(CONT, bb);
  1079. }
  1080. /* instruction 15: C.OR */
  1081. std::tuple<continuation_e, BasicBlock*> __c_or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1082. bb->setName("C.OR");
  1083. this->gen_sync(PRE_SYNC, 15);
  1084. uint8_t rs2 = ((bit_sub<2,3>(instr)));
  1085. uint8_t rd = ((bit_sub<7,3>(instr)));
  1086. if(this->disass_enabled){
  1087. /* generate console output when executing the command */
  1088. auto mnemonic = fmt::format(
  1089. "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.or"),
  1090. fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2)));
  1091. std::vector<Value*> args {
  1092. this->core_ptr,
  1093. this->gen_const(64, pc.val),
  1094. this->builder.CreateGlobalStringPtr(mnemonic),
  1095. };
  1096. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1097. }
  1098. Value* cur_pc_val = this->gen_const(64, pc.val);
  1099. pc=pc+2;
  1100. uint8_t rd_idx_val = rd + 8;
  1101. Value* Xtmp0_val = this->builder.CreateOr(
  1102. this->gen_reg_load(rd_idx_val + traits<ARCH>::X0, 0),
  1103. this->gen_reg_load(rs2 + 8 + traits<ARCH>::X0, 0));
  1104. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits<ARCH>::X0), false);
  1105. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1106. this->gen_sync(POST_SYNC, 15);
  1107. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1108. this->gen_trap_check(bb);
  1109. return std::make_tuple(CONT, bb);
  1110. }
  1111. /* instruction 16: C.AND */
  1112. std::tuple<continuation_e, BasicBlock*> __c_and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1113. bb->setName("C.AND");
  1114. this->gen_sync(PRE_SYNC, 16);
  1115. uint8_t rs2 = ((bit_sub<2,3>(instr)));
  1116. uint8_t rd = ((bit_sub<7,3>(instr)));
  1117. if(this->disass_enabled){
  1118. /* generate console output when executing the command */
  1119. auto mnemonic = fmt::format(
  1120. "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.and"),
  1121. fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2)));
  1122. std::vector<Value*> args {
  1123. this->core_ptr,
  1124. this->gen_const(64, pc.val),
  1125. this->builder.CreateGlobalStringPtr(mnemonic),
  1126. };
  1127. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1128. }
  1129. Value* cur_pc_val = this->gen_const(64, pc.val);
  1130. pc=pc+2;
  1131. uint8_t rd_idx_val = rd + 8;
  1132. Value* Xtmp0_val = this->builder.CreateAnd(
  1133. this->gen_reg_load(rd_idx_val + traits<ARCH>::X0, 0),
  1134. this->gen_reg_load(rs2 + 8 + traits<ARCH>::X0, 0));
  1135. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits<ARCH>::X0), false);
  1136. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1137. this->gen_sync(POST_SYNC, 16);
  1138. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1139. this->gen_trap_check(bb);
  1140. return std::make_tuple(CONT, bb);
  1141. }
  1142. /* instruction 17: C.J */
  1143. std::tuple<continuation_e, BasicBlock*> __c_j(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1144. bb->setName("C.J");
  1145. this->gen_sync(PRE_SYNC, 17);
  1146. int16_t imm = signextend<int16_t,12>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11));
  1147. if(this->disass_enabled){
  1148. /* generate console output when executing the command */
  1149. auto mnemonic = fmt::format(
  1150. "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.j"),
  1151. fmt::arg("imm", imm));
  1152. std::vector<Value*> args {
  1153. this->core_ptr,
  1154. this->gen_const(64, pc.val),
  1155. this->builder.CreateGlobalStringPtr(mnemonic),
  1156. };
  1157. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1158. }
  1159. Value* cur_pc_val = this->gen_const(64, pc.val);
  1160. pc=pc+2;
  1161. Value* PC_val = this->builder.CreateAdd(
  1162. this->gen_ext(
  1163. cur_pc_val,
  1164. 64, true),
  1165. this->gen_const(64U, imm));
  1166. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  1167. Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v");
  1168. this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  1169. this->gen_sync(POST_SYNC, 17);
  1170. this->gen_trap_check(this->leave_blk);
  1171. return std::make_tuple(BRANCH, nullptr);
  1172. }
  1173. /* instruction 18: C.BEQZ */
  1174. std::tuple<continuation_e, BasicBlock*> __c_beqz(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1175. bb->setName("C.BEQZ");
  1176. this->gen_sync(PRE_SYNC, 18);
  1177. int16_t imm = signextend<int16_t,9>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8));
  1178. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  1179. if(this->disass_enabled){
  1180. /* generate console output when executing the command */
  1181. auto mnemonic = fmt::format(
  1182. "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.beqz"),
  1183. fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm));
  1184. std::vector<Value*> args {
  1185. this->core_ptr,
  1186. this->gen_const(64, pc.val),
  1187. this->builder.CreateGlobalStringPtr(mnemonic),
  1188. };
  1189. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1190. }
  1191. Value* cur_pc_val = this->gen_const(64, pc.val);
  1192. pc=pc+2;
  1193. Value* PC_val = this->gen_choose(
  1194. this->builder.CreateICmp(
  1195. ICmpInst::ICMP_EQ,
  1196. this->gen_reg_load(rs1 + 8 + traits<ARCH>::X0, 0),
  1197. this->gen_const(64U, 0)),
  1198. this->builder.CreateAdd(
  1199. this->gen_ext(
  1200. cur_pc_val,
  1201. 64, true),
  1202. this->gen_const(64U, imm)),
  1203. this->builder.CreateAdd(
  1204. cur_pc_val,
  1205. this->gen_const(64U, 2)),
  1206. 64);
  1207. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  1208. Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v");
  1209. this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  1210. this->gen_sync(POST_SYNC, 18);
  1211. this->gen_trap_check(this->leave_blk);
  1212. return std::make_tuple(BRANCH, nullptr);
  1213. }
  1214. /* instruction 19: C.BNEZ */
  1215. std::tuple<continuation_e, BasicBlock*> __c_bnez(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1216. bb->setName("C.BNEZ");
  1217. this->gen_sync(PRE_SYNC, 19);
  1218. int16_t imm = signextend<int16_t,9>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8));
  1219. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  1220. if(this->disass_enabled){
  1221. /* generate console output when executing the command */
  1222. auto mnemonic = fmt::format(
  1223. "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.bnez"),
  1224. fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm));
  1225. std::vector<Value*> args {
  1226. this->core_ptr,
  1227. this->gen_const(64, pc.val),
  1228. this->builder.CreateGlobalStringPtr(mnemonic),
  1229. };
  1230. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1231. }
  1232. Value* cur_pc_val = this->gen_const(64, pc.val);
  1233. pc=pc+2;
  1234. Value* PC_val = this->gen_choose(
  1235. this->builder.CreateICmp(
  1236. ICmpInst::ICMP_NE,
  1237. this->gen_reg_load(rs1 + 8 + traits<ARCH>::X0, 0),
  1238. this->gen_const(64U, 0)),
  1239. this->builder.CreateAdd(
  1240. this->gen_ext(
  1241. cur_pc_val,
  1242. 64, true),
  1243. this->gen_const(64U, imm)),
  1244. this->builder.CreateAdd(
  1245. cur_pc_val,
  1246. this->gen_const(64U, 2)),
  1247. 64);
  1248. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  1249. Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v");
  1250. this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  1251. this->gen_sync(POST_SYNC, 19);
  1252. this->gen_trap_check(this->leave_blk);
  1253. return std::make_tuple(BRANCH, nullptr);
  1254. }
  1255. /* instruction 20: C.SLLI */
  1256. std::tuple<continuation_e, BasicBlock*> __c_slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1257. bb->setName("C.SLLI");
  1258. this->gen_sync(PRE_SYNC, 20);
  1259. uint8_t shamt = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
  1260. uint8_t rs1 = ((bit_sub<7,5>(instr)));
  1261. if(this->disass_enabled){
  1262. /* generate console output when executing the command */
  1263. auto mnemonic = fmt::format(
  1264. "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.slli"),
  1265. fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt));
  1266. std::vector<Value*> args {
  1267. this->core_ptr,
  1268. this->gen_const(64, pc.val),
  1269. this->builder.CreateGlobalStringPtr(mnemonic),
  1270. };
  1271. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1272. }
  1273. Value* cur_pc_val = this->gen_const(64, pc.val);
  1274. pc=pc+2;
  1275. if(rs1 == 0){
  1276. this->gen_raise_trap(0, 2);
  1277. }
  1278. Value* Xtmp0_val = this->builder.CreateShl(
  1279. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  1280. this->gen_const(64U, shamt));
  1281. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits<ARCH>::X0), false);
  1282. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1283. this->gen_sync(POST_SYNC, 20);
  1284. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1285. this->gen_trap_check(bb);
  1286. return std::make_tuple(CONT, bb);
  1287. }
  1288. /* instruction 21: C.LWSP */
  1289. std::tuple<continuation_e, BasicBlock*> __c_lwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1290. bb->setName("C.LWSP");
  1291. this->gen_sync(PRE_SYNC, 21);
  1292. uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5));
  1293. uint8_t rd = ((bit_sub<7,5>(instr)));
  1294. if(this->disass_enabled){
  1295. /* generate console output when executing the command */
  1296. auto mnemonic = fmt::format(
  1297. "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "c.lwsp"),
  1298. fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm));
  1299. std::vector<Value*> args {
  1300. this->core_ptr,
  1301. this->gen_const(64, pc.val),
  1302. this->builder.CreateGlobalStringPtr(mnemonic),
  1303. };
  1304. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1305. }
  1306. Value* cur_pc_val = this->gen_const(64, pc.val);
  1307. pc=pc+2;
  1308. Value* offs_val = this->builder.CreateAdd(
  1309. this->gen_reg_load(2 + traits<ARCH>::X0, 0),
  1310. this->gen_const(64U, uimm));
  1311. Value* Xtmp0_val = this->gen_ext(
  1312. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8),
  1313. 64,
  1314. true);
  1315. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  1316. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1317. this->gen_sync(POST_SYNC, 21);
  1318. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1319. this->gen_trap_check(bb);
  1320. return std::make_tuple(CONT, bb);
  1321. }
  1322. /* instruction 22: C.MV */
  1323. std::tuple<continuation_e, BasicBlock*> __c_mv(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1324. bb->setName("C.MV");
  1325. this->gen_sync(PRE_SYNC, 22);
  1326. uint8_t rs2 = ((bit_sub<2,5>(instr)));
  1327. uint8_t rd = ((bit_sub<7,5>(instr)));
  1328. if(this->disass_enabled){
  1329. /* generate console output when executing the command */
  1330. auto mnemonic = fmt::format(
  1331. "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.mv"),
  1332. fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2)));
  1333. std::vector<Value*> args {
  1334. this->core_ptr,
  1335. this->gen_const(64, pc.val),
  1336. this->builder.CreateGlobalStringPtr(mnemonic),
  1337. };
  1338. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1339. }
  1340. Value* cur_pc_val = this->gen_const(64, pc.val);
  1341. pc=pc+2;
  1342. Value* Xtmp0_val = this->gen_reg_load(rs2 + traits<ARCH>::X0, 0);
  1343. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  1344. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1345. this->gen_sync(POST_SYNC, 22);
  1346. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1347. this->gen_trap_check(bb);
  1348. return std::make_tuple(CONT, bb);
  1349. }
  1350. /* instruction 23: C.JR */
  1351. std::tuple<continuation_e, BasicBlock*> __c_jr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1352. bb->setName("C.JR");
  1353. this->gen_sync(PRE_SYNC, 23);
  1354. uint8_t rs1 = ((bit_sub<7,5>(instr)));
  1355. if(this->disass_enabled){
  1356. /* generate console output when executing the command */
  1357. auto mnemonic = fmt::format(
  1358. "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jr"),
  1359. fmt::arg("rs1", name(rs1)));
  1360. std::vector<Value*> args {
  1361. this->core_ptr,
  1362. this->gen_const(64, pc.val),
  1363. this->builder.CreateGlobalStringPtr(mnemonic),
  1364. };
  1365. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1366. }
  1367. Value* cur_pc_val = this->gen_const(64, pc.val);
  1368. pc=pc+2;
  1369. Value* PC_val = this->gen_reg_load(rs1 + traits<ARCH>::X0, 0);
  1370. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  1371. this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  1372. this->gen_sync(POST_SYNC, 23);
  1373. this->gen_trap_check(this->leave_blk);
  1374. return std::make_tuple(BRANCH, nullptr);
  1375. }
  1376. /* instruction 24: C.ADD */
  1377. std::tuple<continuation_e, BasicBlock*> __c_add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1378. bb->setName("C.ADD");
  1379. this->gen_sync(PRE_SYNC, 24);
  1380. uint8_t rs2 = ((bit_sub<2,5>(instr)));
  1381. uint8_t rd = ((bit_sub<7,5>(instr)));
  1382. if(this->disass_enabled){
  1383. /* generate console output when executing the command */
  1384. auto mnemonic = fmt::format(
  1385. "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.add"),
  1386. fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2)));
  1387. std::vector<Value*> args {
  1388. this->core_ptr,
  1389. this->gen_const(64, pc.val),
  1390. this->builder.CreateGlobalStringPtr(mnemonic),
  1391. };
  1392. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1393. }
  1394. Value* cur_pc_val = this->gen_const(64, pc.val);
  1395. pc=pc+2;
  1396. Value* Xtmp0_val = this->builder.CreateAdd(
  1397. this->gen_reg_load(rd + traits<ARCH>::X0, 0),
  1398. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0));
  1399. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  1400. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1401. this->gen_sync(POST_SYNC, 24);
  1402. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1403. this->gen_trap_check(bb);
  1404. return std::make_tuple(CONT, bb);
  1405. }
  1406. /* instruction 25: C.JALR */
  1407. std::tuple<continuation_e, BasicBlock*> __c_jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1408. bb->setName("C.JALR");
  1409. this->gen_sync(PRE_SYNC, 25);
  1410. uint8_t rs1 = ((bit_sub<7,5>(instr)));
  1411. if(this->disass_enabled){
  1412. /* generate console output when executing the command */
  1413. auto mnemonic = fmt::format(
  1414. "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jalr"),
  1415. fmt::arg("rs1", name(rs1)));
  1416. std::vector<Value*> args {
  1417. this->core_ptr,
  1418. this->gen_const(64, pc.val),
  1419. this->builder.CreateGlobalStringPtr(mnemonic),
  1420. };
  1421. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1422. }
  1423. Value* cur_pc_val = this->gen_const(64, pc.val);
  1424. pc=pc+2;
  1425. Value* Xtmp0_val = this->builder.CreateAdd(
  1426. cur_pc_val,
  1427. this->gen_const(64U, 2));
  1428. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits<ARCH>::X0), false);
  1429. Value* PC_val = this->gen_reg_load(rs1 + traits<ARCH>::X0, 0);
  1430. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  1431. this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  1432. this->gen_sync(POST_SYNC, 25);
  1433. this->gen_trap_check(this->leave_blk);
  1434. return std::make_tuple(BRANCH, nullptr);
  1435. }
  1436. /* instruction 26: C.EBREAK */
  1437. std::tuple<continuation_e, BasicBlock*> __c_ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1438. bb->setName("C.EBREAK");
  1439. this->gen_sync(PRE_SYNC, 26);
  1440. if(this->disass_enabled){
  1441. /* generate console output when executing the command */
  1442. std::vector<Value*> args {
  1443. this->core_ptr,
  1444. this->gen_const(64, pc.val),
  1445. this->builder.CreateGlobalStringPtr("c.ebreak"),
  1446. };
  1447. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1448. }
  1449. Value* cur_pc_val = this->gen_const(64, pc.val);
  1450. pc=pc+2;
  1451. this->gen_raise_trap(0, 3);
  1452. this->gen_sync(POST_SYNC, 26);
  1453. this->gen_trap_check(this->leave_blk);
  1454. return std::make_tuple(BRANCH, nullptr);
  1455. }
  1456. /* instruction 27: C.SWSP */
  1457. std::tuple<continuation_e, BasicBlock*> __c_swsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1458. bb->setName("C.SWSP");
  1459. this->gen_sync(PRE_SYNC, 27);
  1460. uint8_t rs2 = ((bit_sub<2,5>(instr)));
  1461. uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2));
  1462. if(this->disass_enabled){
  1463. /* generate console output when executing the command */
  1464. auto mnemonic = fmt::format(
  1465. "{mnemonic:10} {rs2}, {uimm:#05x}(sp)", fmt::arg("mnemonic", "c.swsp"),
  1466. fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm));
  1467. std::vector<Value*> args {
  1468. this->core_ptr,
  1469. this->gen_const(64, pc.val),
  1470. this->builder.CreateGlobalStringPtr(mnemonic),
  1471. };
  1472. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1473. }
  1474. Value* cur_pc_val = this->gen_const(64, pc.val);
  1475. pc=pc+2;
  1476. Value* offs_val = this->builder.CreateAdd(
  1477. this->gen_reg_load(2 + traits<ARCH>::X0, 0),
  1478. this->gen_const(64U, uimm));
  1479. Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits<ARCH>::X0, 0);
  1480. this->gen_write_mem(
  1481. traits<ARCH>::MEM,
  1482. offs_val,
  1483. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32)));
  1484. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1485. this->gen_sync(POST_SYNC, 27);
  1486. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1487. this->gen_trap_check(bb);
  1488. return std::make_tuple(CONT, bb);
  1489. }
  1490. /* instruction 28: DII */
  1491. std::tuple<continuation_e, BasicBlock*> __dii(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1492. bb->setName("DII");
  1493. this->gen_sync(PRE_SYNC, 28);
  1494. if(this->disass_enabled){
  1495. /* generate console output when executing the command */
  1496. std::vector<Value*> args {
  1497. this->core_ptr,
  1498. this->gen_const(64, pc.val),
  1499. this->builder.CreateGlobalStringPtr("dii"),
  1500. };
  1501. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1502. }
  1503. Value* cur_pc_val = this->gen_const(64, pc.val);
  1504. pc=pc+2;
  1505. this->gen_raise_trap(0, 2);
  1506. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1507. this->gen_sync(POST_SYNC, 28);
  1508. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1509. this->gen_trap_check(bb);
  1510. return std::make_tuple(CONT, bb);
  1511. }
  1512. /* instruction 29: C.FLD */
  1513. std::tuple<continuation_e, BasicBlock*> __c_fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1514. bb->setName("C.FLD");
  1515. this->gen_sync(PRE_SYNC, 29);
  1516. uint8_t rd = ((bit_sub<2,3>(instr)));
  1517. uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3));
  1518. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  1519. if(this->disass_enabled){
  1520. /* generate console output when executing the command */
  1521. auto mnemonic = fmt::format(
  1522. "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fld"),
  1523. fmt::arg("rd", rd), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1)));
  1524. std::vector<Value*> args {
  1525. this->core_ptr,
  1526. this->gen_const(64, pc.val),
  1527. this->builder.CreateGlobalStringPtr(mnemonic),
  1528. };
  1529. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1530. }
  1531. Value* cur_pc_val = this->gen_const(64, pc.val);
  1532. pc=pc+2;
  1533. Value* offs_val = this->builder.CreateAdd(
  1534. this->gen_reg_load(rs1 + 8 + traits<ARCH>::X0, 0),
  1535. this->gen_const(64U, uimm));
  1536. Value* res_val = this->gen_read_mem(traits<ARCH>::MEM, offs_val, 64/8);
  1537. if(64 == 64){
  1538. Value* Ftmp0_val = res_val;
  1539. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + 8 + traits<ARCH>::F0), false);
  1540. } else {
  1541. uint64_t upper_val = - 1;
  1542. Value* Ftmp1_val = this->builder.CreateOr(
  1543. this->builder.CreateShl(
  1544. this->gen_const(64U, upper_val),
  1545. this->gen_const(64U, 64)),
  1546. res_val);
  1547. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + 8 + traits<ARCH>::F0), false);
  1548. }
  1549. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1550. this->gen_sync(POST_SYNC, 29);
  1551. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1552. this->gen_trap_check(bb);
  1553. return std::make_tuple(CONT, bb);
  1554. }
  1555. /* instruction 30: C.FSD */
  1556. std::tuple<continuation_e, BasicBlock*> __c_fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1557. bb->setName("C.FSD");
  1558. this->gen_sync(PRE_SYNC, 30);
  1559. uint8_t rs2 = ((bit_sub<2,3>(instr)));
  1560. uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3));
  1561. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  1562. if(this->disass_enabled){
  1563. /* generate console output when executing the command */
  1564. auto mnemonic = fmt::format(
  1565. "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsd"),
  1566. fmt::arg("rs2", rs2), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1)));
  1567. std::vector<Value*> args {
  1568. this->core_ptr,
  1569. this->gen_const(64, pc.val),
  1570. this->builder.CreateGlobalStringPtr(mnemonic),
  1571. };
  1572. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1573. }
  1574. Value* cur_pc_val = this->gen_const(64, pc.val);
  1575. pc=pc+2;
  1576. Value* offs_val = this->builder.CreateAdd(
  1577. this->gen_reg_load(rs1 + 8 + traits<ARCH>::X0, 0),
  1578. this->gen_const(64U, uimm));
  1579. Value* MEMtmp0_val = this->builder.CreateTrunc(
  1580. this->gen_reg_load(rs2 + 8 + traits<ARCH>::F0, 0),
  1581. this-> get_type(64)
  1582. );
  1583. this->gen_write_mem(
  1584. traits<ARCH>::MEM,
  1585. offs_val,
  1586. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64)));
  1587. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1588. this->gen_sync(POST_SYNC, 30);
  1589. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1590. this->gen_trap_check(bb);
  1591. return std::make_tuple(CONT, bb);
  1592. }
  1593. /* instruction 31: C.FLDSP */
  1594. std::tuple<continuation_e, BasicBlock*> __c_fldsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1595. bb->setName("C.FLDSP");
  1596. this->gen_sync(PRE_SYNC, 31);
  1597. uint16_t uimm = ((bit_sub<2,3>(instr) << 6) | (bit_sub<5,2>(instr) << 3) | (bit_sub<12,1>(instr) << 5));
  1598. uint8_t rd = ((bit_sub<7,5>(instr)));
  1599. if(this->disass_enabled){
  1600. /* generate console output when executing the command */
  1601. auto mnemonic = fmt::format(
  1602. "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.fldsp"),
  1603. fmt::arg("rd", rd), fmt::arg("uimm", uimm));
  1604. std::vector<Value*> args {
  1605. this->core_ptr,
  1606. this->gen_const(64, pc.val),
  1607. this->builder.CreateGlobalStringPtr(mnemonic),
  1608. };
  1609. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1610. }
  1611. Value* cur_pc_val = this->gen_const(64, pc.val);
  1612. pc=pc+2;
  1613. Value* offs_val = this->builder.CreateAdd(
  1614. this->gen_reg_load(2 + traits<ARCH>::X0, 0),
  1615. this->gen_const(64U, uimm));
  1616. Value* res_val = this->gen_read_mem(traits<ARCH>::MEM, offs_val, 64/8);
  1617. if(64 == 64){
  1618. Value* Ftmp0_val = res_val;
  1619. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  1620. } else {
  1621. uint64_t upper_val = - 1;
  1622. Value* Ftmp1_val = this->builder.CreateOr(
  1623. this->builder.CreateShl(
  1624. this->gen_const(64U, upper_val),
  1625. this->gen_const(64U, 64)),
  1626. this->gen_ext(
  1627. res_val,
  1628. 64,
  1629. false));
  1630. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  1631. }
  1632. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1633. this->gen_sync(POST_SYNC, 31);
  1634. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1635. this->gen_trap_check(bb);
  1636. return std::make_tuple(CONT, bb);
  1637. }
  1638. /* instruction 32: C.FSDSP */
  1639. std::tuple<continuation_e, BasicBlock*> __c_fsdsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1640. bb->setName("C.FSDSP");
  1641. this->gen_sync(PRE_SYNC, 32);
  1642. uint8_t rs2 = ((bit_sub<2,5>(instr)));
  1643. uint16_t uimm = ((bit_sub<7,3>(instr) << 6) | (bit_sub<10,3>(instr) << 3));
  1644. if(this->disass_enabled){
  1645. /* generate console output when executing the command */
  1646. auto mnemonic = fmt::format(
  1647. "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fsdsp"),
  1648. fmt::arg("rs2", rs2), fmt::arg("uimm", uimm));
  1649. std::vector<Value*> args {
  1650. this->core_ptr,
  1651. this->gen_const(64, pc.val),
  1652. this->builder.CreateGlobalStringPtr(mnemonic),
  1653. };
  1654. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1655. }
  1656. Value* cur_pc_val = this->gen_const(64, pc.val);
  1657. pc=pc+2;
  1658. Value* offs_val = this->builder.CreateAdd(
  1659. this->gen_reg_load(2 + traits<ARCH>::X0, 0),
  1660. this->gen_const(64U, uimm));
  1661. Value* MEMtmp0_val = this->builder.CreateTrunc(
  1662. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  1663. this-> get_type(64)
  1664. );
  1665. this->gen_write_mem(
  1666. traits<ARCH>::MEM,
  1667. offs_val,
  1668. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64)));
  1669. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1670. this->gen_sync(POST_SYNC, 32);
  1671. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1672. this->gen_trap_check(bb);
  1673. return std::make_tuple(CONT, bb);
  1674. }
  1675. /* instruction 33: C.FLW */
  1676. std::tuple<continuation_e, BasicBlock*> __c_flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1677. bb->setName("C.FLW");
  1678. this->gen_sync(PRE_SYNC, 33);
  1679. uint8_t rd = ((bit_sub<2,3>(instr)));
  1680. uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3));
  1681. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  1682. if(this->disass_enabled){
  1683. /* generate console output when executing the command */
  1684. auto mnemonic = fmt::format(
  1685. "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.flw"),
  1686. fmt::arg("rd", rd), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1)));
  1687. std::vector<Value*> args {
  1688. this->core_ptr,
  1689. this->gen_const(64, pc.val),
  1690. this->builder.CreateGlobalStringPtr(mnemonic),
  1691. };
  1692. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1693. }
  1694. Value* cur_pc_val = this->gen_const(64, pc.val);
  1695. pc=pc+2;
  1696. Value* offs_val = this->builder.CreateAdd(
  1697. this->gen_reg_load(rs1 + 8 + traits<ARCH>::X0, 0),
  1698. this->gen_const(64U, uimm));
  1699. Value* res_val = this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8);
  1700. if(64 == 32){
  1701. Value* Ftmp0_val = res_val;
  1702. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + 8 + traits<ARCH>::F0), false);
  1703. } else {
  1704. uint64_t upper_val = - 1;
  1705. Value* Ftmp1_val = this->builder.CreateOr(
  1706. this->builder.CreateShl(
  1707. this->gen_const(64U, upper_val),
  1708. this->gen_const(64U, 32)),
  1709. this->gen_ext(
  1710. res_val,
  1711. 64,
  1712. false));
  1713. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + 8 + traits<ARCH>::F0), false);
  1714. }
  1715. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1716. this->gen_sync(POST_SYNC, 33);
  1717. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1718. this->gen_trap_check(bb);
  1719. return std::make_tuple(CONT, bb);
  1720. }
  1721. /* instruction 34: C.FSW */
  1722. std::tuple<continuation_e, BasicBlock*> __c_fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1723. bb->setName("C.FSW");
  1724. this->gen_sync(PRE_SYNC, 34);
  1725. uint8_t rs2 = ((bit_sub<2,3>(instr)));
  1726. uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3));
  1727. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  1728. if(this->disass_enabled){
  1729. /* generate console output when executing the command */
  1730. auto mnemonic = fmt::format(
  1731. "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsw"),
  1732. fmt::arg("rs2", rs2), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1)));
  1733. std::vector<Value*> args {
  1734. this->core_ptr,
  1735. this->gen_const(64, pc.val),
  1736. this->builder.CreateGlobalStringPtr(mnemonic),
  1737. };
  1738. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1739. }
  1740. Value* cur_pc_val = this->gen_const(64, pc.val);
  1741. pc=pc+2;
  1742. Value* offs_val = this->builder.CreateAdd(
  1743. this->gen_reg_load(rs1 + 8 + traits<ARCH>::X0, 0),
  1744. this->gen_const(64U, uimm));
  1745. Value* MEMtmp0_val = this->builder.CreateTrunc(
  1746. this->gen_reg_load(rs2 + 8 + traits<ARCH>::F0, 0),
  1747. this-> get_type(32)
  1748. );
  1749. this->gen_write_mem(
  1750. traits<ARCH>::MEM,
  1751. offs_val,
  1752. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32)));
  1753. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1754. this->gen_sync(POST_SYNC, 34);
  1755. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1756. this->gen_trap_check(bb);
  1757. return std::make_tuple(CONT, bb);
  1758. }
  1759. /* instruction 35: C.FLWSP */
  1760. std::tuple<continuation_e, BasicBlock*> __c_flwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1761. bb->setName("C.FLWSP");
  1762. this->gen_sync(PRE_SYNC, 35);
  1763. uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5));
  1764. uint8_t rd = ((bit_sub<7,5>(instr)));
  1765. if(this->disass_enabled){
  1766. /* generate console output when executing the command */
  1767. auto mnemonic = fmt::format(
  1768. "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.flwsp"),
  1769. fmt::arg("rd", rd), fmt::arg("uimm", uimm));
  1770. std::vector<Value*> args {
  1771. this->core_ptr,
  1772. this->gen_const(64, pc.val),
  1773. this->builder.CreateGlobalStringPtr(mnemonic),
  1774. };
  1775. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1776. }
  1777. Value* cur_pc_val = this->gen_const(64, pc.val);
  1778. pc=pc+2;
  1779. Value* offs_val = this->builder.CreateAdd(
  1780. this->gen_reg_load(2 + traits<ARCH>::X0, 0),
  1781. this->gen_const(64U, uimm));
  1782. Value* res_val = this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8);
  1783. if(64 == 32){
  1784. Value* Ftmp0_val = res_val;
  1785. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  1786. } else {
  1787. uint64_t upper_val = - 1;
  1788. Value* Ftmp1_val = this->builder.CreateOr(
  1789. this->builder.CreateShl(
  1790. this->gen_const(64U, upper_val),
  1791. this->gen_const(64U, 32)),
  1792. this->gen_ext(
  1793. res_val,
  1794. 64,
  1795. false));
  1796. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  1797. }
  1798. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1799. this->gen_sync(POST_SYNC, 35);
  1800. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1801. this->gen_trap_check(bb);
  1802. return std::make_tuple(CONT, bb);
  1803. }
  1804. /* instruction 36: C.FSWSP */
  1805. std::tuple<continuation_e, BasicBlock*> __c_fswsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1806. bb->setName("C.FSWSP");
  1807. this->gen_sync(PRE_SYNC, 36);
  1808. uint8_t rs2 = ((bit_sub<2,5>(instr)));
  1809. uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2));
  1810. if(this->disass_enabled){
  1811. /* generate console output when executing the command */
  1812. auto mnemonic = fmt::format(
  1813. "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fswsp"),
  1814. fmt::arg("rs2", rs2), fmt::arg("uimm", uimm));
  1815. std::vector<Value*> args {
  1816. this->core_ptr,
  1817. this->gen_const(64, pc.val),
  1818. this->builder.CreateGlobalStringPtr(mnemonic),
  1819. };
  1820. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1821. }
  1822. Value* cur_pc_val = this->gen_const(64, pc.val);
  1823. pc=pc+2;
  1824. Value* offs_val = this->builder.CreateAdd(
  1825. this->gen_reg_load(2 + traits<ARCH>::X0, 0),
  1826. this->gen_const(64U, uimm));
  1827. Value* MEMtmp0_val = this->builder.CreateTrunc(
  1828. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  1829. this-> get_type(32)
  1830. );
  1831. this->gen_write_mem(
  1832. traits<ARCH>::MEM,
  1833. offs_val,
  1834. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32)));
  1835. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1836. this->gen_sync(POST_SYNC, 36);
  1837. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1838. this->gen_trap_check(bb);
  1839. return std::make_tuple(CONT, bb);
  1840. }
  1841. /* instruction 37: C.LD */
  1842. std::tuple<continuation_e, BasicBlock*> __c_ld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1843. bb->setName("C.LD");
  1844. this->gen_sync(PRE_SYNC, 37);
  1845. uint8_t rd = ((bit_sub<2,3>(instr)));
  1846. uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3));
  1847. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  1848. if(this->disass_enabled){
  1849. /* generate console output when executing the command */
  1850. auto mnemonic = fmt::format(
  1851. "{mnemonic:10} {rd}, {uimm},({rs1})", fmt::arg("mnemonic", "c.ld"),
  1852. fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1)));
  1853. std::vector<Value*> args {
  1854. this->core_ptr,
  1855. this->gen_const(64, pc.val),
  1856. this->builder.CreateGlobalStringPtr(mnemonic),
  1857. };
  1858. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1859. }
  1860. Value* cur_pc_val = this->gen_const(64, pc.val);
  1861. pc=pc+2;
  1862. Value* offs_val = this->builder.CreateAdd(
  1863. this->gen_reg_load(rs1 + 8 + traits<ARCH>::X0, 0),
  1864. this->gen_const(64U, uimm));
  1865. Value* Xtmp0_val = this->gen_ext(
  1866. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 64/8),
  1867. 64,
  1868. true);
  1869. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits<ARCH>::X0), false);
  1870. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1871. this->gen_sync(POST_SYNC, 37);
  1872. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1873. this->gen_trap_check(bb);
  1874. return std::make_tuple(CONT, bb);
  1875. }
  1876. /* instruction 38: C.SD */
  1877. std::tuple<continuation_e, BasicBlock*> __c_sd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1878. bb->setName("C.SD");
  1879. this->gen_sync(PRE_SYNC, 38);
  1880. uint8_t rs2 = ((bit_sub<2,3>(instr)));
  1881. uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3));
  1882. uint8_t rs1 = ((bit_sub<7,3>(instr)));
  1883. if(this->disass_enabled){
  1884. /* generate console output when executing the command */
  1885. auto mnemonic = fmt::format(
  1886. "{mnemonic:10} {rs2}, {uimm},({rs1})", fmt::arg("mnemonic", "c.sd"),
  1887. fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1)));
  1888. std::vector<Value*> args {
  1889. this->core_ptr,
  1890. this->gen_const(64, pc.val),
  1891. this->builder.CreateGlobalStringPtr(mnemonic),
  1892. };
  1893. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1894. }
  1895. Value* cur_pc_val = this->gen_const(64, pc.val);
  1896. pc=pc+2;
  1897. Value* offs_val = this->builder.CreateAdd(
  1898. this->gen_reg_load(rs1 + 8 + traits<ARCH>::X0, 0),
  1899. this->gen_const(64U, uimm));
  1900. Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits<ARCH>::X0, 0);
  1901. this->gen_write_mem(
  1902. traits<ARCH>::MEM,
  1903. offs_val,
  1904. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64)));
  1905. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1906. this->gen_sync(POST_SYNC, 38);
  1907. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1908. this->gen_trap_check(bb);
  1909. return std::make_tuple(CONT, bb);
  1910. }
  1911. /* instruction 39: C.SUBW */
  1912. std::tuple<continuation_e, BasicBlock*> __c_subw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1913. bb->setName("C.SUBW");
  1914. this->gen_sync(PRE_SYNC, 39);
  1915. uint8_t rs2 = ((bit_sub<2,3>(instr)));
  1916. uint8_t rd = ((bit_sub<7,3>(instr)));
  1917. if(this->disass_enabled){
  1918. /* generate console output when executing the command */
  1919. auto mnemonic = fmt::format(
  1920. "{mnemonic:10} {rd}, {rd}, {rs2}", fmt::arg("mnemonic", "c.subw"),
  1921. fmt::arg("rd", name(8+rd)), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2)));
  1922. std::vector<Value*> args {
  1923. this->core_ptr,
  1924. this->gen_const(64, pc.val),
  1925. this->builder.CreateGlobalStringPtr(mnemonic),
  1926. };
  1927. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1928. }
  1929. Value* cur_pc_val = this->gen_const(64, pc.val);
  1930. pc=pc+2;
  1931. Value* res_val = this->builder.CreateSub(
  1932. this->builder.CreateTrunc(
  1933. this->gen_reg_load(rd + 8 + traits<ARCH>::X0, 0),
  1934. this-> get_type(32)
  1935. ),
  1936. this->builder.CreateTrunc(
  1937. this->gen_reg_load(rs2 + 8 + traits<ARCH>::X0, 0),
  1938. this-> get_type(32)
  1939. ));
  1940. Value* Xtmp0_val = this->gen_ext(
  1941. res_val,
  1942. 64,
  1943. true);
  1944. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits<ARCH>::X0), false);
  1945. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1946. this->gen_sync(POST_SYNC, 39);
  1947. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1948. this->gen_trap_check(bb);
  1949. return std::make_tuple(CONT, bb);
  1950. }
  1951. /* instruction 40: C.ADDW */
  1952. std::tuple<continuation_e, BasicBlock*> __c_addw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1953. bb->setName("C.ADDW");
  1954. this->gen_sync(PRE_SYNC, 40);
  1955. uint8_t rs2 = ((bit_sub<2,3>(instr)));
  1956. uint8_t rd = ((bit_sub<7,3>(instr)));
  1957. if(this->disass_enabled){
  1958. /* generate console output when executing the command */
  1959. auto mnemonic = fmt::format(
  1960. "{mnemonic:10} {rd}, {rd}, {rs2}", fmt::arg("mnemonic", "c.addw"),
  1961. fmt::arg("rd", name(8+rd)), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2)));
  1962. std::vector<Value*> args {
  1963. this->core_ptr,
  1964. this->gen_const(64, pc.val),
  1965. this->builder.CreateGlobalStringPtr(mnemonic),
  1966. };
  1967. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  1968. }
  1969. Value* cur_pc_val = this->gen_const(64, pc.val);
  1970. pc=pc+2;
  1971. Value* res_val = this->builder.CreateAdd(
  1972. this->builder.CreateTrunc(
  1973. this->gen_reg_load(rd + 8 + traits<ARCH>::X0, 0),
  1974. this-> get_type(32)
  1975. ),
  1976. this->builder.CreateTrunc(
  1977. this->gen_reg_load(rs2 + 8 + traits<ARCH>::X0, 0),
  1978. this-> get_type(32)
  1979. ));
  1980. Value* Xtmp0_val = this->gen_ext(
  1981. res_val,
  1982. 64,
  1983. true);
  1984. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits<ARCH>::X0), false);
  1985. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  1986. this->gen_sync(POST_SYNC, 40);
  1987. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  1988. this->gen_trap_check(bb);
  1989. return std::make_tuple(CONT, bb);
  1990. }
  1991. /* instruction 41: C.ADDIW */
  1992. std::tuple<continuation_e, BasicBlock*> __c_addiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  1993. bb->setName("C.ADDIW");
  1994. this->gen_sync(PRE_SYNC, 41);
  1995. int8_t imm = signextend<int8_t,6>((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
  1996. uint8_t rs1 = ((bit_sub<7,5>(instr)));
  1997. if(this->disass_enabled){
  1998. /* generate console output when executing the command */
  1999. auto mnemonic = fmt::format(
  2000. "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addiw"),
  2001. fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
  2002. std::vector<Value*> args {
  2003. this->core_ptr,
  2004. this->gen_const(64, pc.val),
  2005. this->builder.CreateGlobalStringPtr(mnemonic),
  2006. };
  2007. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2008. }
  2009. Value* cur_pc_val = this->gen_const(64, pc.val);
  2010. pc=pc+2;
  2011. if(rs1 != 0){
  2012. Value* res_val = this->builder.CreateAdd(
  2013. this->gen_ext(
  2014. this->builder.CreateTrunc(
  2015. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  2016. this-> get_type(32)
  2017. ),
  2018. 32, true),
  2019. this->gen_const(32U, imm));
  2020. Value* Xtmp0_val = this->gen_ext(
  2021. res_val,
  2022. 64,
  2023. true);
  2024. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits<ARCH>::X0), false);
  2025. }
  2026. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2027. this->gen_sync(POST_SYNC, 41);
  2028. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2029. this->gen_trap_check(bb);
  2030. return std::make_tuple(CONT, bb);
  2031. }
  2032. /* instruction 42: C.LDSP */
  2033. std::tuple<continuation_e, BasicBlock*> __c_ldsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2034. bb->setName("C.LDSP");
  2035. this->gen_sync(PRE_SYNC, 42);
  2036. uint16_t uimm = ((bit_sub<2,3>(instr) << 6) | (bit_sub<5,2>(instr) << 3) | (bit_sub<12,1>(instr) << 5));
  2037. uint8_t rd = ((bit_sub<7,5>(instr)));
  2038. if(this->disass_enabled){
  2039. /* generate console output when executing the command */
  2040. auto mnemonic = fmt::format(
  2041. "{mnemonic:10} {rd}, {uimm}(sp)", fmt::arg("mnemonic", "c.ldsp"),
  2042. fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm));
  2043. std::vector<Value*> args {
  2044. this->core_ptr,
  2045. this->gen_const(64, pc.val),
  2046. this->builder.CreateGlobalStringPtr(mnemonic),
  2047. };
  2048. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2049. }
  2050. Value* cur_pc_val = this->gen_const(64, pc.val);
  2051. pc=pc+2;
  2052. Value* offs_val = this->builder.CreateAdd(
  2053. this->gen_reg_load(2 + traits<ARCH>::X0, 0),
  2054. this->gen_const(64U, uimm));
  2055. if(rd != 0){
  2056. Value* Xtmp0_val = this->gen_ext(
  2057. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 64/8),
  2058. 64,
  2059. true);
  2060. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  2061. }
  2062. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2063. this->gen_sync(POST_SYNC, 42);
  2064. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2065. this->gen_trap_check(bb);
  2066. return std::make_tuple(CONT, bb);
  2067. }
  2068. /* instruction 43: C.SDSP */
  2069. std::tuple<continuation_e, BasicBlock*> __c_sdsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2070. bb->setName("C.SDSP");
  2071. this->gen_sync(PRE_SYNC, 43);
  2072. uint8_t rs2 = ((bit_sub<2,5>(instr)));
  2073. uint16_t uimm = ((bit_sub<7,3>(instr) << 6) | (bit_sub<10,3>(instr) << 3));
  2074. if(this->disass_enabled){
  2075. /* generate console output when executing the command */
  2076. auto mnemonic = fmt::format(
  2077. "{mnemonic:10} {rs2}, {uimm}(sp)", fmt::arg("mnemonic", "c.sdsp"),
  2078. fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm));
  2079. std::vector<Value*> args {
  2080. this->core_ptr,
  2081. this->gen_const(64, pc.val),
  2082. this->builder.CreateGlobalStringPtr(mnemonic),
  2083. };
  2084. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2085. }
  2086. Value* cur_pc_val = this->gen_const(64, pc.val);
  2087. pc=pc+2;
  2088. Value* offs_val = this->builder.CreateAdd(
  2089. this->gen_reg_load(2 + traits<ARCH>::X0, 0),
  2090. this->gen_const(64U, uimm));
  2091. Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits<ARCH>::X0, 0);
  2092. this->gen_write_mem(
  2093. traits<ARCH>::MEM,
  2094. offs_val,
  2095. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64)));
  2096. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2097. this->gen_sync(POST_SYNC, 43);
  2098. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2099. this->gen_trap_check(bb);
  2100. return std::make_tuple(CONT, bb);
  2101. }
  2102. /* instruction 44: FLD */
  2103. std::tuple<continuation_e, BasicBlock*> __fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2104. bb->setName("FLD");
  2105. this->gen_sync(PRE_SYNC, 44);
  2106. uint8_t rd = ((bit_sub<7,5>(instr)));
  2107. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2108. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  2109. if(this->disass_enabled){
  2110. /* generate console output when executing the command */
  2111. auto mnemonic = fmt::format(
  2112. "{mnemonic:10} f{rd}, {imm}({rs1})", fmt::arg("mnemonic", "fld"),
  2113. fmt::arg("rd", rd), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
  2114. std::vector<Value*> args {
  2115. this->core_ptr,
  2116. this->gen_const(64, pc.val),
  2117. this->builder.CreateGlobalStringPtr(mnemonic),
  2118. };
  2119. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2120. }
  2121. Value* cur_pc_val = this->gen_const(64, pc.val);
  2122. pc=pc+4;
  2123. Value* offs_val = this->builder.CreateAdd(
  2124. this->gen_ext(
  2125. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  2126. 64, true),
  2127. this->gen_const(64U, imm));
  2128. Value* res_val = this->gen_read_mem(traits<ARCH>::MEM, offs_val, 64/8);
  2129. if(64 == 64){
  2130. Value* Ftmp0_val = res_val;
  2131. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2132. } else {
  2133. uint64_t upper_val = - 1;
  2134. Value* Ftmp1_val = this->builder.CreateOr(
  2135. this->builder.CreateShl(
  2136. this->gen_const(64U, upper_val),
  2137. this->gen_const(64U, 64)),
  2138. res_val);
  2139. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2140. }
  2141. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2142. this->gen_sync(POST_SYNC, 44);
  2143. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2144. this->gen_trap_check(bb);
  2145. return std::make_tuple(CONT, bb);
  2146. }
  2147. /* instruction 45: FSD */
  2148. std::tuple<continuation_e, BasicBlock*> __fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2149. bb->setName("FSD");
  2150. this->gen_sync(PRE_SYNC, 45);
  2151. int16_t imm = signextend<int16_t,12>((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5));
  2152. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2153. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2154. if(this->disass_enabled){
  2155. /* generate console output when executing the command */
  2156. auto mnemonic = fmt::format(
  2157. "{mnemonic:10} f{rs2}, {imm}({rs1})", fmt::arg("mnemonic", "fsd"),
  2158. fmt::arg("rs2", rs2), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
  2159. std::vector<Value*> args {
  2160. this->core_ptr,
  2161. this->gen_const(64, pc.val),
  2162. this->builder.CreateGlobalStringPtr(mnemonic),
  2163. };
  2164. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2165. }
  2166. Value* cur_pc_val = this->gen_const(64, pc.val);
  2167. pc=pc+4;
  2168. Value* offs_val = this->builder.CreateAdd(
  2169. this->gen_ext(
  2170. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  2171. 64, true),
  2172. this->gen_const(64U, imm));
  2173. Value* MEMtmp0_val = this->builder.CreateTrunc(
  2174. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2175. this-> get_type(64)
  2176. );
  2177. this->gen_write_mem(
  2178. traits<ARCH>::MEM,
  2179. offs_val,
  2180. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64)));
  2181. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2182. this->gen_sync(POST_SYNC, 45);
  2183. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2184. this->gen_trap_check(bb);
  2185. return std::make_tuple(CONT, bb);
  2186. }
  2187. /* instruction 46: FMADD.D */
  2188. std::tuple<continuation_e, BasicBlock*> __fmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2189. bb->setName("FMADD.D");
  2190. this->gen_sync(PRE_SYNC, 46);
  2191. uint8_t rd = ((bit_sub<7,5>(instr)));
  2192. uint8_t rm = ((bit_sub<12,3>(instr)));
  2193. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2194. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2195. uint8_t rs3 = ((bit_sub<27,5>(instr)));
  2196. if(this->disass_enabled){
  2197. /* generate console output when executing the command */
  2198. auto mnemonic = fmt::format(
  2199. "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmadd.d"),
  2200. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3));
  2201. std::vector<Value*> args {
  2202. this->core_ptr,
  2203. this->gen_const(64, pc.val),
  2204. this->builder.CreateGlobalStringPtr(mnemonic),
  2205. };
  2206. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2207. }
  2208. Value* cur_pc_val = this->gen_const(64, pc.val);
  2209. pc=pc+4;
  2210. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector<Value*>{
  2211. this->builder.CreateTrunc(
  2212. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2213. this-> get_type(64)
  2214. ),
  2215. this->builder.CreateTrunc(
  2216. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2217. this-> get_type(64)
  2218. ),
  2219. this->builder.CreateTrunc(
  2220. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0),
  2221. this-> get_type(64)
  2222. ),
  2223. this->gen_ext(
  2224. this->gen_const(64U, 0LL),
  2225. 64,
  2226. false),
  2227. this->gen_choose(
  2228. this->builder.CreateICmp(
  2229. ICmpInst::ICMP_ULT,
  2230. this->gen_const(8U, rm),
  2231. this->gen_const(8U, 7)),
  2232. this->gen_const(8U, rm),
  2233. this->builder.CreateTrunc(
  2234. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2235. this-> get_type(8)
  2236. ),
  2237. 8)
  2238. });
  2239. if(64 == 64){
  2240. Value* Ftmp0_val = res_val;
  2241. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2242. } else {
  2243. uint64_t upper_val = - 1;
  2244. Value* Ftmp1_val = this->builder.CreateOr(
  2245. this->builder.CreateShl(
  2246. this->gen_const(64U, upper_val),
  2247. this->gen_const(64U, 64)),
  2248. res_val);
  2249. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2250. }
  2251. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  2252. });
  2253. Value* FCSR_val = this->builder.CreateAdd(
  2254. this->builder.CreateAnd(
  2255. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2256. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  2257. flags_val);
  2258. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  2259. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2260. this->gen_sync(POST_SYNC, 46);
  2261. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2262. this->gen_trap_check(bb);
  2263. return std::make_tuple(CONT, bb);
  2264. }
  2265. /* instruction 47: FMSUB.D */
  2266. std::tuple<continuation_e, BasicBlock*> __fmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2267. bb->setName("FMSUB.D");
  2268. this->gen_sync(PRE_SYNC, 47);
  2269. uint8_t rd = ((bit_sub<7,5>(instr)));
  2270. uint8_t rm = ((bit_sub<12,3>(instr)));
  2271. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2272. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2273. uint8_t rs3 = ((bit_sub<27,5>(instr)));
  2274. if(this->disass_enabled){
  2275. /* generate console output when executing the command */
  2276. auto mnemonic = fmt::format(
  2277. "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmsub.d"),
  2278. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3));
  2279. std::vector<Value*> args {
  2280. this->core_ptr,
  2281. this->gen_const(64, pc.val),
  2282. this->builder.CreateGlobalStringPtr(mnemonic),
  2283. };
  2284. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2285. }
  2286. Value* cur_pc_val = this->gen_const(64, pc.val);
  2287. pc=pc+4;
  2288. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector<Value*>{
  2289. this->builder.CreateTrunc(
  2290. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2291. this-> get_type(64)
  2292. ),
  2293. this->builder.CreateTrunc(
  2294. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2295. this-> get_type(64)
  2296. ),
  2297. this->builder.CreateTrunc(
  2298. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0),
  2299. this-> get_type(64)
  2300. ),
  2301. this->gen_ext(
  2302. this->gen_const(64U, 1LL),
  2303. 32,
  2304. false),
  2305. this->gen_choose(
  2306. this->builder.CreateICmp(
  2307. ICmpInst::ICMP_ULT,
  2308. this->gen_const(8U, rm),
  2309. this->gen_const(8U, 7)),
  2310. this->gen_const(8U, rm),
  2311. this->builder.CreateTrunc(
  2312. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2313. this-> get_type(8)
  2314. ),
  2315. 8)
  2316. });
  2317. if(64 == 64){
  2318. Value* Ftmp0_val = res_val;
  2319. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2320. } else {
  2321. uint64_t upper_val = - 1;
  2322. Value* Ftmp1_val = this->builder.CreateOr(
  2323. this->builder.CreateShl(
  2324. this->gen_const(64U, upper_val),
  2325. this->gen_const(64U, 64)),
  2326. res_val);
  2327. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2328. }
  2329. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  2330. });
  2331. Value* FCSR_val = this->builder.CreateAdd(
  2332. this->builder.CreateAnd(
  2333. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2334. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  2335. flags_val);
  2336. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  2337. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2338. this->gen_sync(POST_SYNC, 47);
  2339. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2340. this->gen_trap_check(bb);
  2341. return std::make_tuple(CONT, bb);
  2342. }
  2343. /* instruction 48: FNMADD.D */
  2344. std::tuple<continuation_e, BasicBlock*> __fnmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2345. bb->setName("FNMADD.D");
  2346. this->gen_sync(PRE_SYNC, 48);
  2347. uint8_t rd = ((bit_sub<7,5>(instr)));
  2348. uint8_t rm = ((bit_sub<12,3>(instr)));
  2349. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2350. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2351. uint8_t rs3 = ((bit_sub<27,5>(instr)));
  2352. if(this->disass_enabled){
  2353. /* generate console output when executing the command */
  2354. auto mnemonic = fmt::format(
  2355. "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmadd.d"),
  2356. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3));
  2357. std::vector<Value*> args {
  2358. this->core_ptr,
  2359. this->gen_const(64, pc.val),
  2360. this->builder.CreateGlobalStringPtr(mnemonic),
  2361. };
  2362. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2363. }
  2364. Value* cur_pc_val = this->gen_const(64, pc.val);
  2365. pc=pc+4;
  2366. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector<Value*>{
  2367. this->builder.CreateTrunc(
  2368. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2369. this-> get_type(64)
  2370. ),
  2371. this->builder.CreateTrunc(
  2372. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2373. this-> get_type(64)
  2374. ),
  2375. this->builder.CreateTrunc(
  2376. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0),
  2377. this-> get_type(64)
  2378. ),
  2379. this->gen_ext(
  2380. this->gen_const(64U, 2LL),
  2381. 32,
  2382. false),
  2383. this->gen_choose(
  2384. this->builder.CreateICmp(
  2385. ICmpInst::ICMP_ULT,
  2386. this->gen_const(8U, rm),
  2387. this->gen_const(8U, 7)),
  2388. this->gen_const(8U, rm),
  2389. this->builder.CreateTrunc(
  2390. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2391. this-> get_type(8)
  2392. ),
  2393. 8)
  2394. });
  2395. if(64 == 64){
  2396. Value* Ftmp0_val = res_val;
  2397. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2398. } else {
  2399. uint64_t upper_val = - 1;
  2400. Value* Ftmp1_val = this->builder.CreateOr(
  2401. this->builder.CreateShl(
  2402. this->gen_const(64U, upper_val),
  2403. this->gen_const(64U, 64)),
  2404. res_val);
  2405. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2406. }
  2407. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  2408. });
  2409. Value* FCSR_val = this->builder.CreateAdd(
  2410. this->builder.CreateAnd(
  2411. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2412. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  2413. flags_val);
  2414. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  2415. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2416. this->gen_sync(POST_SYNC, 48);
  2417. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2418. this->gen_trap_check(bb);
  2419. return std::make_tuple(CONT, bb);
  2420. }
  2421. /* instruction 49: FNMSUB.D */
  2422. std::tuple<continuation_e, BasicBlock*> __fnmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2423. bb->setName("FNMSUB.D");
  2424. this->gen_sync(PRE_SYNC, 49);
  2425. uint8_t rd = ((bit_sub<7,5>(instr)));
  2426. uint8_t rm = ((bit_sub<12,3>(instr)));
  2427. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2428. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2429. uint8_t rs3 = ((bit_sub<27,5>(instr)));
  2430. if(this->disass_enabled){
  2431. /* generate console output when executing the command */
  2432. auto mnemonic = fmt::format(
  2433. "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmsub.d"),
  2434. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3));
  2435. std::vector<Value*> args {
  2436. this->core_ptr,
  2437. this->gen_const(64, pc.val),
  2438. this->builder.CreateGlobalStringPtr(mnemonic),
  2439. };
  2440. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2441. }
  2442. Value* cur_pc_val = this->gen_const(64, pc.val);
  2443. pc=pc+4;
  2444. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector<Value*>{
  2445. this->builder.CreateTrunc(
  2446. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2447. this-> get_type(64)
  2448. ),
  2449. this->builder.CreateTrunc(
  2450. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2451. this-> get_type(64)
  2452. ),
  2453. this->builder.CreateTrunc(
  2454. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0),
  2455. this-> get_type(64)
  2456. ),
  2457. this->gen_ext(
  2458. this->gen_const(64U, 3LL),
  2459. 32,
  2460. false),
  2461. this->gen_choose(
  2462. this->builder.CreateICmp(
  2463. ICmpInst::ICMP_ULT,
  2464. this->gen_const(8U, rm),
  2465. this->gen_const(8U, 7)),
  2466. this->gen_const(8U, rm),
  2467. this->builder.CreateTrunc(
  2468. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2469. this-> get_type(8)
  2470. ),
  2471. 8)
  2472. });
  2473. if(64 == 64){
  2474. Value* Ftmp0_val = res_val;
  2475. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2476. } else {
  2477. uint64_t upper_val = - 1;
  2478. Value* Ftmp1_val = this->builder.CreateOr(
  2479. this->builder.CreateShl(
  2480. this->gen_const(64U, upper_val),
  2481. this->gen_const(64U, 64)),
  2482. res_val);
  2483. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2484. }
  2485. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  2486. });
  2487. Value* FCSR_val = this->builder.CreateAdd(
  2488. this->builder.CreateAnd(
  2489. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2490. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  2491. flags_val);
  2492. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  2493. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2494. this->gen_sync(POST_SYNC, 49);
  2495. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2496. this->gen_trap_check(bb);
  2497. return std::make_tuple(CONT, bb);
  2498. }
  2499. /* instruction 50: FADD.D */
  2500. std::tuple<continuation_e, BasicBlock*> __fadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2501. bb->setName("FADD.D");
  2502. this->gen_sync(PRE_SYNC, 50);
  2503. uint8_t rd = ((bit_sub<7,5>(instr)));
  2504. uint8_t rm = ((bit_sub<12,3>(instr)));
  2505. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2506. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2507. if(this->disass_enabled){
  2508. /* generate console output when executing the command */
  2509. auto mnemonic = fmt::format(
  2510. "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fadd.d"),
  2511. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  2512. std::vector<Value*> args {
  2513. this->core_ptr,
  2514. this->gen_const(64, pc.val),
  2515. this->builder.CreateGlobalStringPtr(mnemonic),
  2516. };
  2517. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2518. }
  2519. Value* cur_pc_val = this->gen_const(64, pc.val);
  2520. pc=pc+4;
  2521. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fadd_d"), std::vector<Value*>{
  2522. this->builder.CreateTrunc(
  2523. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2524. this-> get_type(64)
  2525. ),
  2526. this->builder.CreateTrunc(
  2527. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2528. this-> get_type(64)
  2529. ),
  2530. this->gen_choose(
  2531. this->builder.CreateICmp(
  2532. ICmpInst::ICMP_ULT,
  2533. this->gen_const(8U, rm),
  2534. this->gen_const(8U, 7)),
  2535. this->gen_const(8U, rm),
  2536. this->builder.CreateTrunc(
  2537. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2538. this-> get_type(8)
  2539. ),
  2540. 8)
  2541. });
  2542. if(64 == 64){
  2543. Value* Ftmp0_val = res_val;
  2544. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2545. } else {
  2546. uint64_t upper_val = - 1;
  2547. Value* Ftmp1_val = this->builder.CreateOr(
  2548. this->builder.CreateShl(
  2549. this->gen_const(64U, upper_val),
  2550. this->gen_const(64U, 64)),
  2551. res_val);
  2552. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2553. }
  2554. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  2555. });
  2556. Value* FCSR_val = this->builder.CreateAdd(
  2557. this->builder.CreateAnd(
  2558. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2559. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  2560. flags_val);
  2561. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  2562. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2563. this->gen_sync(POST_SYNC, 50);
  2564. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2565. this->gen_trap_check(bb);
  2566. return std::make_tuple(CONT, bb);
  2567. }
  2568. /* instruction 51: FSUB.D */
  2569. std::tuple<continuation_e, BasicBlock*> __fsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2570. bb->setName("FSUB.D");
  2571. this->gen_sync(PRE_SYNC, 51);
  2572. uint8_t rd = ((bit_sub<7,5>(instr)));
  2573. uint8_t rm = ((bit_sub<12,3>(instr)));
  2574. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2575. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2576. if(this->disass_enabled){
  2577. /* generate console output when executing the command */
  2578. auto mnemonic = fmt::format(
  2579. "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsub.d"),
  2580. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  2581. std::vector<Value*> args {
  2582. this->core_ptr,
  2583. this->gen_const(64, pc.val),
  2584. this->builder.CreateGlobalStringPtr(mnemonic),
  2585. };
  2586. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2587. }
  2588. Value* cur_pc_val = this->gen_const(64, pc.val);
  2589. pc=pc+4;
  2590. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsub_d"), std::vector<Value*>{
  2591. this->builder.CreateTrunc(
  2592. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2593. this-> get_type(64)
  2594. ),
  2595. this->builder.CreateTrunc(
  2596. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2597. this-> get_type(64)
  2598. ),
  2599. this->gen_choose(
  2600. this->builder.CreateICmp(
  2601. ICmpInst::ICMP_ULT,
  2602. this->gen_const(8U, rm),
  2603. this->gen_const(8U, 7)),
  2604. this->gen_const(8U, rm),
  2605. this->builder.CreateTrunc(
  2606. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2607. this-> get_type(8)
  2608. ),
  2609. 8)
  2610. });
  2611. if(64 == 64){
  2612. Value* Ftmp0_val = res_val;
  2613. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2614. } else {
  2615. uint64_t upper_val = - 1;
  2616. Value* Ftmp1_val = this->builder.CreateOr(
  2617. this->builder.CreateShl(
  2618. this->gen_const(64U, upper_val),
  2619. this->gen_const(64U, 64)),
  2620. res_val);
  2621. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2622. }
  2623. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  2624. });
  2625. Value* FCSR_val = this->builder.CreateAdd(
  2626. this->builder.CreateAnd(
  2627. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2628. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  2629. flags_val);
  2630. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  2631. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2632. this->gen_sync(POST_SYNC, 51);
  2633. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2634. this->gen_trap_check(bb);
  2635. return std::make_tuple(CONT, bb);
  2636. }
  2637. /* instruction 52: FMUL.D */
  2638. std::tuple<continuation_e, BasicBlock*> __fmul_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2639. bb->setName("FMUL.D");
  2640. this->gen_sync(PRE_SYNC, 52);
  2641. uint8_t rd = ((bit_sub<7,5>(instr)));
  2642. uint8_t rm = ((bit_sub<12,3>(instr)));
  2643. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2644. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2645. if(this->disass_enabled){
  2646. /* generate console output when executing the command */
  2647. auto mnemonic = fmt::format(
  2648. "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmul.d"),
  2649. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  2650. std::vector<Value*> args {
  2651. this->core_ptr,
  2652. this->gen_const(64, pc.val),
  2653. this->builder.CreateGlobalStringPtr(mnemonic),
  2654. };
  2655. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2656. }
  2657. Value* cur_pc_val = this->gen_const(64, pc.val);
  2658. pc=pc+4;
  2659. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmul_d"), std::vector<Value*>{
  2660. this->builder.CreateTrunc(
  2661. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2662. this-> get_type(64)
  2663. ),
  2664. this->builder.CreateTrunc(
  2665. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2666. this-> get_type(64)
  2667. ),
  2668. this->gen_choose(
  2669. this->builder.CreateICmp(
  2670. ICmpInst::ICMP_ULT,
  2671. this->gen_const(8U, rm),
  2672. this->gen_const(8U, 7)),
  2673. this->gen_const(8U, rm),
  2674. this->builder.CreateTrunc(
  2675. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2676. this-> get_type(8)
  2677. ),
  2678. 8)
  2679. });
  2680. if(64 == 64){
  2681. Value* Ftmp0_val = res_val;
  2682. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2683. } else {
  2684. uint64_t upper_val = - 1;
  2685. Value* Ftmp1_val = this->builder.CreateOr(
  2686. this->builder.CreateShl(
  2687. this->gen_const(64U, upper_val),
  2688. this->gen_const(64U, 64)),
  2689. res_val);
  2690. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2691. }
  2692. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  2693. });
  2694. Value* FCSR_val = this->builder.CreateAdd(
  2695. this->builder.CreateAnd(
  2696. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2697. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  2698. flags_val);
  2699. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  2700. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2701. this->gen_sync(POST_SYNC, 52);
  2702. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2703. this->gen_trap_check(bb);
  2704. return std::make_tuple(CONT, bb);
  2705. }
  2706. /* instruction 53: FDIV.D */
  2707. std::tuple<continuation_e, BasicBlock*> __fdiv_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2708. bb->setName("FDIV.D");
  2709. this->gen_sync(PRE_SYNC, 53);
  2710. uint8_t rd = ((bit_sub<7,5>(instr)));
  2711. uint8_t rm = ((bit_sub<12,3>(instr)));
  2712. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2713. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2714. if(this->disass_enabled){
  2715. /* generate console output when executing the command */
  2716. auto mnemonic = fmt::format(
  2717. "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fdiv.d"),
  2718. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  2719. std::vector<Value*> args {
  2720. this->core_ptr,
  2721. this->gen_const(64, pc.val),
  2722. this->builder.CreateGlobalStringPtr(mnemonic),
  2723. };
  2724. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2725. }
  2726. Value* cur_pc_val = this->gen_const(64, pc.val);
  2727. pc=pc+4;
  2728. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fdiv_d"), std::vector<Value*>{
  2729. this->builder.CreateTrunc(
  2730. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2731. this-> get_type(64)
  2732. ),
  2733. this->builder.CreateTrunc(
  2734. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2735. this-> get_type(64)
  2736. ),
  2737. this->gen_choose(
  2738. this->builder.CreateICmp(
  2739. ICmpInst::ICMP_ULT,
  2740. this->gen_const(8U, rm),
  2741. this->gen_const(8U, 7)),
  2742. this->gen_const(8U, rm),
  2743. this->builder.CreateTrunc(
  2744. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2745. this-> get_type(8)
  2746. ),
  2747. 8)
  2748. });
  2749. if(64 == 64){
  2750. Value* Ftmp0_val = res_val;
  2751. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2752. } else {
  2753. uint64_t upper_val = - 1;
  2754. Value* Ftmp1_val = this->builder.CreateOr(
  2755. this->builder.CreateShl(
  2756. this->gen_const(64U, upper_val),
  2757. this->gen_const(64U, 64)),
  2758. res_val);
  2759. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2760. }
  2761. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  2762. });
  2763. Value* FCSR_val = this->builder.CreateAdd(
  2764. this->builder.CreateAnd(
  2765. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2766. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  2767. flags_val);
  2768. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  2769. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2770. this->gen_sync(POST_SYNC, 53);
  2771. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2772. this->gen_trap_check(bb);
  2773. return std::make_tuple(CONT, bb);
  2774. }
  2775. /* instruction 54: FSQRT.D */
  2776. std::tuple<continuation_e, BasicBlock*> __fsqrt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2777. bb->setName("FSQRT.D");
  2778. this->gen_sync(PRE_SYNC, 54);
  2779. uint8_t rd = ((bit_sub<7,5>(instr)));
  2780. uint8_t rm = ((bit_sub<12,3>(instr)));
  2781. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2782. if(this->disass_enabled){
  2783. /* generate console output when executing the command */
  2784. auto mnemonic = fmt::format(
  2785. "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fsqrt.d"),
  2786. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1));
  2787. std::vector<Value*> args {
  2788. this->core_ptr,
  2789. this->gen_const(64, pc.val),
  2790. this->builder.CreateGlobalStringPtr(mnemonic),
  2791. };
  2792. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2793. }
  2794. Value* cur_pc_val = this->gen_const(64, pc.val);
  2795. pc=pc+4;
  2796. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_d"), std::vector<Value*>{
  2797. this->builder.CreateTrunc(
  2798. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2799. this-> get_type(64)
  2800. ),
  2801. this->gen_choose(
  2802. this->builder.CreateICmp(
  2803. ICmpInst::ICMP_ULT,
  2804. this->gen_const(8U, rm),
  2805. this->gen_const(8U, 7)),
  2806. this->gen_const(8U, rm),
  2807. this->builder.CreateTrunc(
  2808. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2809. this-> get_type(8)
  2810. ),
  2811. 8)
  2812. });
  2813. if(64 == 64){
  2814. Value* Ftmp0_val = res_val;
  2815. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2816. } else {
  2817. uint64_t upper_val = - 1;
  2818. Value* Ftmp1_val = this->builder.CreateOr(
  2819. this->builder.CreateShl(
  2820. this->gen_const(64U, upper_val),
  2821. this->gen_const(64U, 64)),
  2822. res_val);
  2823. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2824. }
  2825. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  2826. });
  2827. Value* FCSR_val = this->builder.CreateAdd(
  2828. this->builder.CreateAnd(
  2829. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  2830. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  2831. flags_val);
  2832. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  2833. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2834. this->gen_sync(POST_SYNC, 54);
  2835. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2836. this->gen_trap_check(bb);
  2837. return std::make_tuple(CONT, bb);
  2838. }
  2839. /* instruction 55: FSGNJ.D */
  2840. std::tuple<continuation_e, BasicBlock*> __fsgnj_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2841. bb->setName("FSGNJ.D");
  2842. this->gen_sync(PRE_SYNC, 55);
  2843. uint8_t rd = ((bit_sub<7,5>(instr)));
  2844. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2845. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2846. if(this->disass_enabled){
  2847. /* generate console output when executing the command */
  2848. auto mnemonic = fmt::format(
  2849. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnj.d"),
  2850. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  2851. std::vector<Value*> args {
  2852. this->core_ptr,
  2853. this->gen_const(64, pc.val),
  2854. this->builder.CreateGlobalStringPtr(mnemonic),
  2855. };
  2856. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2857. }
  2858. Value* cur_pc_val = this->gen_const(64, pc.val);
  2859. pc=pc+4;
  2860. uint64_t ONE_val = 1;
  2861. uint64_t MSK1_val = ONE_val << 63;
  2862. uint64_t MSK2_val = MSK1_val - 1;
  2863. Value* res_val = this->builder.CreateOr(
  2864. this->builder.CreateAnd(
  2865. this->builder.CreateTrunc(
  2866. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2867. this-> get_type(64)
  2868. ),
  2869. this->gen_const(64U, MSK2_val)),
  2870. this->builder.CreateAnd(
  2871. this->builder.CreateTrunc(
  2872. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2873. this-> get_type(64)
  2874. ),
  2875. this->gen_const(64U, MSK1_val)));
  2876. if(64 == 64){
  2877. Value* Ftmp0_val = res_val;
  2878. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2879. } else {
  2880. uint64_t upper_val = - 1;
  2881. Value* Ftmp1_val = this->builder.CreateOr(
  2882. this->builder.CreateShl(
  2883. this->gen_const(64U, upper_val),
  2884. this->gen_const(64U, 64)),
  2885. res_val);
  2886. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2887. }
  2888. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2889. this->gen_sync(POST_SYNC, 55);
  2890. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2891. this->gen_trap_check(bb);
  2892. return std::make_tuple(CONT, bb);
  2893. }
  2894. /* instruction 56: FSGNJN.D */
  2895. std::tuple<continuation_e, BasicBlock*> __fsgnjn_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2896. bb->setName("FSGNJN.D");
  2897. this->gen_sync(PRE_SYNC, 56);
  2898. uint8_t rd = ((bit_sub<7,5>(instr)));
  2899. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2900. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2901. if(this->disass_enabled){
  2902. /* generate console output when executing the command */
  2903. auto mnemonic = fmt::format(
  2904. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjn.d"),
  2905. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  2906. std::vector<Value*> args {
  2907. this->core_ptr,
  2908. this->gen_const(64, pc.val),
  2909. this->builder.CreateGlobalStringPtr(mnemonic),
  2910. };
  2911. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2912. }
  2913. Value* cur_pc_val = this->gen_const(64, pc.val);
  2914. pc=pc+4;
  2915. uint64_t ONE_val = 1;
  2916. uint64_t MSK1_val = ONE_val << 63;
  2917. uint64_t MSK2_val = MSK1_val - 1;
  2918. Value* res_val = this->builder.CreateOr(
  2919. this->builder.CreateAnd(
  2920. this->builder.CreateTrunc(
  2921. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2922. this-> get_type(64)
  2923. ),
  2924. this->gen_const(64U, MSK2_val)),
  2925. this->builder.CreateAnd(
  2926. this->builder.CreateNot(this->builder.CreateTrunc(
  2927. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2928. this-> get_type(64)
  2929. )),
  2930. this->gen_const(64U, MSK1_val)));
  2931. if(64 == 64){
  2932. Value* Ftmp0_val = res_val;
  2933. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2934. } else {
  2935. uint64_t upper_val = - 1;
  2936. Value* Ftmp1_val = this->builder.CreateOr(
  2937. this->builder.CreateShl(
  2938. this->gen_const(64U, upper_val),
  2939. this->gen_const(64U, 64)),
  2940. res_val);
  2941. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2942. }
  2943. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2944. this->gen_sync(POST_SYNC, 56);
  2945. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2946. this->gen_trap_check(bb);
  2947. return std::make_tuple(CONT, bb);
  2948. }
  2949. /* instruction 57: FSGNJX.D */
  2950. std::tuple<continuation_e, BasicBlock*> __fsgnjx_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  2951. bb->setName("FSGNJX.D");
  2952. this->gen_sync(PRE_SYNC, 57);
  2953. uint8_t rd = ((bit_sub<7,5>(instr)));
  2954. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  2955. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  2956. if(this->disass_enabled){
  2957. /* generate console output when executing the command */
  2958. auto mnemonic = fmt::format(
  2959. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjx.d"),
  2960. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  2961. std::vector<Value*> args {
  2962. this->core_ptr,
  2963. this->gen_const(64, pc.val),
  2964. this->builder.CreateGlobalStringPtr(mnemonic),
  2965. };
  2966. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  2967. }
  2968. Value* cur_pc_val = this->gen_const(64, pc.val);
  2969. pc=pc+4;
  2970. uint64_t ONE_val = 1;
  2971. uint64_t MSK1_val = ONE_val << 63;
  2972. Value* res_val = this->builder.CreateXor(
  2973. this->builder.CreateTrunc(
  2974. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  2975. this-> get_type(64)
  2976. ),
  2977. this->builder.CreateAnd(
  2978. this->builder.CreateTrunc(
  2979. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  2980. this-> get_type(64)
  2981. ),
  2982. this->gen_const(64U, MSK1_val)));
  2983. if(64 == 64){
  2984. Value* Ftmp0_val = res_val;
  2985. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2986. } else {
  2987. uint64_t upper_val = - 1;
  2988. Value* Ftmp1_val = this->builder.CreateOr(
  2989. this->builder.CreateShl(
  2990. this->gen_const(64U, upper_val),
  2991. this->gen_const(64U, 64)),
  2992. res_val);
  2993. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  2994. }
  2995. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  2996. this->gen_sync(POST_SYNC, 57);
  2997. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  2998. this->gen_trap_check(bb);
  2999. return std::make_tuple(CONT, bb);
  3000. }
  3001. /* instruction 58: FMIN.D */
  3002. std::tuple<continuation_e, BasicBlock*> __fmin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3003. bb->setName("FMIN.D");
  3004. this->gen_sync(PRE_SYNC, 58);
  3005. uint8_t rd = ((bit_sub<7,5>(instr)));
  3006. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3007. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  3008. if(this->disass_enabled){
  3009. /* generate console output when executing the command */
  3010. auto mnemonic = fmt::format(
  3011. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmin.d"),
  3012. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  3013. std::vector<Value*> args {
  3014. this->core_ptr,
  3015. this->gen_const(64, pc.val),
  3016. this->builder.CreateGlobalStringPtr(mnemonic),
  3017. };
  3018. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3019. }
  3020. Value* cur_pc_val = this->gen_const(64, pc.val);
  3021. pc=pc+4;
  3022. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector<Value*>{
  3023. this->builder.CreateTrunc(
  3024. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3025. this-> get_type(64)
  3026. ),
  3027. this->builder.CreateTrunc(
  3028. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  3029. this-> get_type(64)
  3030. ),
  3031. this->gen_ext(
  3032. this->gen_const(64U, 0LL),
  3033. 32,
  3034. false)
  3035. });
  3036. if(64 == 64){
  3037. Value* Ftmp0_val = res_val;
  3038. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3039. } else {
  3040. uint64_t upper_val = - 1;
  3041. Value* Ftmp1_val = this->builder.CreateOr(
  3042. this->builder.CreateShl(
  3043. this->gen_const(64U, upper_val),
  3044. this->gen_const(64U, 64)),
  3045. res_val);
  3046. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3047. }
  3048. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  3049. });
  3050. Value* FCSR_val = this->builder.CreateAdd(
  3051. this->builder.CreateAnd(
  3052. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  3053. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  3054. flags_val);
  3055. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  3056. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3057. this->gen_sync(POST_SYNC, 58);
  3058. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3059. this->gen_trap_check(bb);
  3060. return std::make_tuple(CONT, bb);
  3061. }
  3062. /* instruction 59: FMAX.D */
  3063. std::tuple<continuation_e, BasicBlock*> __fmax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3064. bb->setName("FMAX.D");
  3065. this->gen_sync(PRE_SYNC, 59);
  3066. uint8_t rd = ((bit_sub<7,5>(instr)));
  3067. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3068. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  3069. if(this->disass_enabled){
  3070. /* generate console output when executing the command */
  3071. auto mnemonic = fmt::format(
  3072. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmax.d"),
  3073. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  3074. std::vector<Value*> args {
  3075. this->core_ptr,
  3076. this->gen_const(64, pc.val),
  3077. this->builder.CreateGlobalStringPtr(mnemonic),
  3078. };
  3079. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3080. }
  3081. Value* cur_pc_val = this->gen_const(64, pc.val);
  3082. pc=pc+4;
  3083. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector<Value*>{
  3084. this->builder.CreateTrunc(
  3085. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3086. this-> get_type(64)
  3087. ),
  3088. this->builder.CreateTrunc(
  3089. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  3090. this-> get_type(64)
  3091. ),
  3092. this->gen_ext(
  3093. this->gen_const(64U, 1LL),
  3094. 32,
  3095. false)
  3096. });
  3097. if(64 == 64){
  3098. Value* Ftmp0_val = res_val;
  3099. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3100. } else {
  3101. uint64_t upper_val = - 1;
  3102. Value* Ftmp1_val = this->builder.CreateOr(
  3103. this->builder.CreateShl(
  3104. this->gen_const(64U, upper_val),
  3105. this->gen_const(64U, 64)),
  3106. res_val);
  3107. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3108. }
  3109. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  3110. });
  3111. Value* FCSR_val = this->builder.CreateAdd(
  3112. this->builder.CreateAnd(
  3113. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  3114. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  3115. flags_val);
  3116. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  3117. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3118. this->gen_sync(POST_SYNC, 59);
  3119. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3120. this->gen_trap_check(bb);
  3121. return std::make_tuple(CONT, bb);
  3122. }
  3123. /* instruction 60: FCVT.S.D */
  3124. std::tuple<continuation_e, BasicBlock*> __fcvt_s_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3125. bb->setName("FCVT.S.D");
  3126. this->gen_sync(PRE_SYNC, 60);
  3127. uint8_t rd = ((bit_sub<7,5>(instr)));
  3128. uint8_t rm = ((bit_sub<12,3>(instr)));
  3129. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3130. if(this->disass_enabled){
  3131. /* generate console output when executing the command */
  3132. auto mnemonic = fmt::format(
  3133. "{mnemonic:10} f{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.s.d"),
  3134. fmt::arg("rd", rd), fmt::arg("rs1", rs1));
  3135. std::vector<Value*> args {
  3136. this->core_ptr,
  3137. this->gen_const(64, pc.val),
  3138. this->builder.CreateGlobalStringPtr(mnemonic),
  3139. };
  3140. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3141. }
  3142. Value* cur_pc_val = this->gen_const(64, pc.val);
  3143. pc=pc+4;
  3144. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fconv_d2f"), std::vector<Value*>{
  3145. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3146. this->gen_const(8U, rm)
  3147. });
  3148. uint64_t upper_val = - 1;
  3149. Value* Ftmp0_val = this->builder.CreateOr(
  3150. this->builder.CreateShl(
  3151. this->gen_const(64U, upper_val),
  3152. this->gen_const(64U, 32)),
  3153. this->gen_ext(
  3154. res_val,
  3155. 64,
  3156. false));
  3157. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3158. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3159. this->gen_sync(POST_SYNC, 60);
  3160. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3161. this->gen_trap_check(bb);
  3162. return std::make_tuple(CONT, bb);
  3163. }
  3164. /* instruction 61: FCVT.D.S */
  3165. std::tuple<continuation_e, BasicBlock*> __fcvt_d_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3166. bb->setName("FCVT.D.S");
  3167. this->gen_sync(PRE_SYNC, 61);
  3168. uint8_t rd = ((bit_sub<7,5>(instr)));
  3169. uint8_t rm = ((bit_sub<12,3>(instr)));
  3170. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3171. if(this->disass_enabled){
  3172. /* generate console output when executing the command */
  3173. auto mnemonic = fmt::format(
  3174. "{mnemonic:10} f{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.d.s"),
  3175. fmt::arg("rd", rd), fmt::arg("rs1", rs1));
  3176. std::vector<Value*> args {
  3177. this->core_ptr,
  3178. this->gen_const(64, pc.val),
  3179. this->builder.CreateGlobalStringPtr(mnemonic),
  3180. };
  3181. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3182. }
  3183. Value* cur_pc_val = this->gen_const(64, pc.val);
  3184. pc=pc+4;
  3185. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fconv_f2d"), std::vector<Value*>{
  3186. this->builder.CreateTrunc(
  3187. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3188. this-> get_type(32)
  3189. ),
  3190. this->gen_const(8U, rm)
  3191. });
  3192. if(64 == 64){
  3193. Value* Ftmp0_val = res_val;
  3194. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3195. } else {
  3196. uint64_t upper_val = - 1;
  3197. Value* Ftmp1_val = this->builder.CreateOr(
  3198. this->builder.CreateShl(
  3199. this->gen_const(64U, upper_val),
  3200. this->gen_const(64U, 64)),
  3201. res_val);
  3202. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3203. }
  3204. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3205. this->gen_sync(POST_SYNC, 61);
  3206. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3207. this->gen_trap_check(bb);
  3208. return std::make_tuple(CONT, bb);
  3209. }
  3210. /* instruction 62: FEQ.D */
  3211. std::tuple<continuation_e, BasicBlock*> __feq_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3212. bb->setName("FEQ.D");
  3213. this->gen_sync(PRE_SYNC, 62);
  3214. uint8_t rd = ((bit_sub<7,5>(instr)));
  3215. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3216. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  3217. if(this->disass_enabled){
  3218. /* generate console output when executing the command */
  3219. auto mnemonic = fmt::format(
  3220. "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "feq.d"),
  3221. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  3222. std::vector<Value*> args {
  3223. this->core_ptr,
  3224. this->gen_const(64, pc.val),
  3225. this->builder.CreateGlobalStringPtr(mnemonic),
  3226. };
  3227. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3228. }
  3229. Value* cur_pc_val = this->gen_const(64, pc.val);
  3230. pc=pc+4;
  3231. Value* Xtmp0_val = this->gen_ext(
  3232. this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector<Value*>{
  3233. this->builder.CreateTrunc(
  3234. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3235. this-> get_type(64)
  3236. ),
  3237. this->builder.CreateTrunc(
  3238. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  3239. this-> get_type(64)
  3240. ),
  3241. this->gen_ext(
  3242. this->gen_const(64U, 0LL),
  3243. 32,
  3244. false)
  3245. }),
  3246. 64,
  3247. false);
  3248. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3249. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  3250. });
  3251. Value* FCSR_val = this->builder.CreateAdd(
  3252. this->builder.CreateAnd(
  3253. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  3254. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  3255. flags_val);
  3256. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  3257. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3258. this->gen_sync(POST_SYNC, 62);
  3259. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3260. this->gen_trap_check(bb);
  3261. return std::make_tuple(CONT, bb);
  3262. }
  3263. /* instruction 63: FLT.D */
  3264. std::tuple<continuation_e, BasicBlock*> __flt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3265. bb->setName("FLT.D");
  3266. this->gen_sync(PRE_SYNC, 63);
  3267. uint8_t rd = ((bit_sub<7,5>(instr)));
  3268. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3269. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  3270. if(this->disass_enabled){
  3271. /* generate console output when executing the command */
  3272. auto mnemonic = fmt::format(
  3273. "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "flt.d"),
  3274. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  3275. std::vector<Value*> args {
  3276. this->core_ptr,
  3277. this->gen_const(64, pc.val),
  3278. this->builder.CreateGlobalStringPtr(mnemonic),
  3279. };
  3280. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3281. }
  3282. Value* cur_pc_val = this->gen_const(64, pc.val);
  3283. pc=pc+4;
  3284. Value* Xtmp0_val = this->gen_ext(
  3285. this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector<Value*>{
  3286. this->builder.CreateTrunc(
  3287. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3288. this-> get_type(64)
  3289. ),
  3290. this->builder.CreateTrunc(
  3291. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  3292. this-> get_type(64)
  3293. ),
  3294. this->gen_ext(
  3295. this->gen_const(64U, 2LL),
  3296. 32,
  3297. false)
  3298. }),
  3299. 64,
  3300. false);
  3301. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3302. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  3303. });
  3304. Value* FCSR_val = this->builder.CreateAdd(
  3305. this->builder.CreateAnd(
  3306. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  3307. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  3308. flags_val);
  3309. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  3310. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3311. this->gen_sync(POST_SYNC, 63);
  3312. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3313. this->gen_trap_check(bb);
  3314. return std::make_tuple(CONT, bb);
  3315. }
  3316. /* instruction 64: FLE.D */
  3317. std::tuple<continuation_e, BasicBlock*> __fle_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3318. bb->setName("FLE.D");
  3319. this->gen_sync(PRE_SYNC, 64);
  3320. uint8_t rd = ((bit_sub<7,5>(instr)));
  3321. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3322. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  3323. if(this->disass_enabled){
  3324. /* generate console output when executing the command */
  3325. auto mnemonic = fmt::format(
  3326. "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fle.d"),
  3327. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  3328. std::vector<Value*> args {
  3329. this->core_ptr,
  3330. this->gen_const(64, pc.val),
  3331. this->builder.CreateGlobalStringPtr(mnemonic),
  3332. };
  3333. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3334. }
  3335. Value* cur_pc_val = this->gen_const(64, pc.val);
  3336. pc=pc+4;
  3337. Value* Xtmp0_val = this->gen_ext(
  3338. this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector<Value*>{
  3339. this->builder.CreateTrunc(
  3340. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3341. this-> get_type(64)
  3342. ),
  3343. this->builder.CreateTrunc(
  3344. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  3345. this-> get_type(64)
  3346. ),
  3347. this->gen_ext(
  3348. this->gen_const(64U, 1LL),
  3349. 32,
  3350. false)
  3351. }),
  3352. 64,
  3353. false);
  3354. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3355. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  3356. });
  3357. Value* FCSR_val = this->builder.CreateAdd(
  3358. this->builder.CreateAnd(
  3359. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  3360. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  3361. flags_val);
  3362. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  3363. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3364. this->gen_sync(POST_SYNC, 64);
  3365. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3366. this->gen_trap_check(bb);
  3367. return std::make_tuple(CONT, bb);
  3368. }
  3369. /* instruction 65: FCLASS.D */
  3370. std::tuple<continuation_e, BasicBlock*> __fclass_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3371. bb->setName("FCLASS.D");
  3372. this->gen_sync(PRE_SYNC, 65);
  3373. uint8_t rd = ((bit_sub<7,5>(instr)));
  3374. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3375. if(this->disass_enabled){
  3376. /* generate console output when executing the command */
  3377. auto mnemonic = fmt::format(
  3378. "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fclass.d"),
  3379. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1));
  3380. std::vector<Value*> args {
  3381. this->core_ptr,
  3382. this->gen_const(64, pc.val),
  3383. this->builder.CreateGlobalStringPtr(mnemonic),
  3384. };
  3385. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3386. }
  3387. Value* cur_pc_val = this->gen_const(64, pc.val);
  3388. pc=pc+4;
  3389. Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_d"), std::vector<Value*>{
  3390. this->builder.CreateTrunc(
  3391. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3392. this-> get_type(64)
  3393. )
  3394. });
  3395. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3396. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3397. this->gen_sync(POST_SYNC, 65);
  3398. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3399. this->gen_trap_check(bb);
  3400. return std::make_tuple(CONT, bb);
  3401. }
  3402. /* instruction 66: FCVT.W.D */
  3403. std::tuple<continuation_e, BasicBlock*> __fcvt_w_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3404. bb->setName("FCVT.W.D");
  3405. this->gen_sync(PRE_SYNC, 66);
  3406. uint8_t rd = ((bit_sub<7,5>(instr)));
  3407. uint8_t rm = ((bit_sub<12,3>(instr)));
  3408. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3409. if(this->disass_enabled){
  3410. /* generate console output when executing the command */
  3411. auto mnemonic = fmt::format(
  3412. "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.w.d"),
  3413. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1));
  3414. std::vector<Value*> args {
  3415. this->core_ptr,
  3416. this->gen_const(64, pc.val),
  3417. this->builder.CreateGlobalStringPtr(mnemonic),
  3418. };
  3419. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3420. }
  3421. Value* cur_pc_val = this->gen_const(64, pc.val);
  3422. pc=pc+4;
  3423. Value* Xtmp0_val = this->gen_ext(
  3424. this->builder.CreateCall(this->mod->getFunction("fcvt_64_32"), std::vector<Value*>{
  3425. this->builder.CreateTrunc(
  3426. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3427. this-> get_type(64)
  3428. ),
  3429. this->gen_ext(
  3430. this->gen_const(64U, 0LL),
  3431. 32,
  3432. false),
  3433. this->gen_const(8U, rm)
  3434. }),
  3435. 64,
  3436. true);
  3437. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3438. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  3439. });
  3440. Value* FCSR_val = this->builder.CreateAdd(
  3441. this->builder.CreateAnd(
  3442. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  3443. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  3444. flags_val);
  3445. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  3446. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3447. this->gen_sync(POST_SYNC, 66);
  3448. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3449. this->gen_trap_check(bb);
  3450. return std::make_tuple(CONT, bb);
  3451. }
  3452. /* instruction 67: FCVT.WU.D */
  3453. std::tuple<continuation_e, BasicBlock*> __fcvt_wu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3454. bb->setName("FCVT.WU.D");
  3455. this->gen_sync(PRE_SYNC, 67);
  3456. uint8_t rd = ((bit_sub<7,5>(instr)));
  3457. uint8_t rm = ((bit_sub<12,3>(instr)));
  3458. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3459. if(this->disass_enabled){
  3460. /* generate console output when executing the command */
  3461. auto mnemonic = fmt::format(
  3462. "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.wu.d"),
  3463. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1));
  3464. std::vector<Value*> args {
  3465. this->core_ptr,
  3466. this->gen_const(64, pc.val),
  3467. this->builder.CreateGlobalStringPtr(mnemonic),
  3468. };
  3469. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3470. }
  3471. Value* cur_pc_val = this->gen_const(64, pc.val);
  3472. pc=pc+4;
  3473. Value* Xtmp0_val = this->gen_ext(
  3474. this->builder.CreateCall(this->mod->getFunction("fcvt_64_32"), std::vector<Value*>{
  3475. this->builder.CreateTrunc(
  3476. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3477. this-> get_type(64)
  3478. ),
  3479. this->gen_ext(
  3480. this->gen_const(64U, 1LL),
  3481. 32,
  3482. false),
  3483. this->gen_const(8U, rm)
  3484. }),
  3485. 64,
  3486. true);
  3487. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3488. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  3489. });
  3490. Value* FCSR_val = this->builder.CreateAdd(
  3491. this->builder.CreateAnd(
  3492. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  3493. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  3494. flags_val);
  3495. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  3496. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3497. this->gen_sync(POST_SYNC, 67);
  3498. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3499. this->gen_trap_check(bb);
  3500. return std::make_tuple(CONT, bb);
  3501. }
  3502. /* instruction 68: FCVT.D.W */
  3503. std::tuple<continuation_e, BasicBlock*> __fcvt_d_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3504. bb->setName("FCVT.D.W");
  3505. this->gen_sync(PRE_SYNC, 68);
  3506. uint8_t rd = ((bit_sub<7,5>(instr)));
  3507. uint8_t rm = ((bit_sub<12,3>(instr)));
  3508. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3509. if(this->disass_enabled){
  3510. /* generate console output when executing the command */
  3511. auto mnemonic = fmt::format(
  3512. "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.w"),
  3513. fmt::arg("rd", rd), fmt::arg("rs1", name(rs1)));
  3514. std::vector<Value*> args {
  3515. this->core_ptr,
  3516. this->gen_const(64, pc.val),
  3517. this->builder.CreateGlobalStringPtr(mnemonic),
  3518. };
  3519. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3520. }
  3521. Value* cur_pc_val = this->gen_const(64, pc.val);
  3522. pc=pc+4;
  3523. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_32_64"), std::vector<Value*>{
  3524. this->gen_ext(
  3525. this->builder.CreateTrunc(
  3526. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  3527. this-> get_type(32)
  3528. ),
  3529. 64,
  3530. true),
  3531. this->gen_ext(
  3532. this->gen_const(64U, 2LL),
  3533. 32,
  3534. false),
  3535. this->gen_const(8U, rm)
  3536. });
  3537. if(64 == 64){
  3538. Value* Ftmp0_val = res_val;
  3539. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3540. } else {
  3541. uint64_t upper_val = - 1;
  3542. Value* Ftmp1_val = this->builder.CreateOr(
  3543. this->builder.CreateShl(
  3544. this->gen_const(64U, upper_val),
  3545. this->gen_const(64U, 64)),
  3546. res_val);
  3547. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3548. }
  3549. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3550. this->gen_sync(POST_SYNC, 68);
  3551. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3552. this->gen_trap_check(bb);
  3553. return std::make_tuple(CONT, bb);
  3554. }
  3555. /* instruction 69: FCVT.D.WU */
  3556. std::tuple<continuation_e, BasicBlock*> __fcvt_d_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3557. bb->setName("FCVT.D.WU");
  3558. this->gen_sync(PRE_SYNC, 69);
  3559. uint8_t rd = ((bit_sub<7,5>(instr)));
  3560. uint8_t rm = ((bit_sub<12,3>(instr)));
  3561. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3562. if(this->disass_enabled){
  3563. /* generate console output when executing the command */
  3564. auto mnemonic = fmt::format(
  3565. "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.wu"),
  3566. fmt::arg("rd", rd), fmt::arg("rs1", name(rs1)));
  3567. std::vector<Value*> args {
  3568. this->core_ptr,
  3569. this->gen_const(64, pc.val),
  3570. this->builder.CreateGlobalStringPtr(mnemonic),
  3571. };
  3572. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3573. }
  3574. Value* cur_pc_val = this->gen_const(64, pc.val);
  3575. pc=pc+4;
  3576. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_32_64"), std::vector<Value*>{
  3577. this->gen_ext(
  3578. this->builder.CreateTrunc(
  3579. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  3580. this-> get_type(32)
  3581. ),
  3582. 64,
  3583. false),
  3584. this->gen_ext(
  3585. this->gen_const(64U, 3LL),
  3586. 32,
  3587. false),
  3588. this->gen_const(8U, rm)
  3589. });
  3590. if(64 == 64){
  3591. Value* Ftmp0_val = res_val;
  3592. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3593. } else {
  3594. uint64_t upper_val = - 1;
  3595. Value* Ftmp1_val = this->builder.CreateOr(
  3596. this->builder.CreateShl(
  3597. this->gen_const(64U, upper_val),
  3598. this->gen_const(64U, 64)),
  3599. res_val);
  3600. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3601. }
  3602. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3603. this->gen_sync(POST_SYNC, 69);
  3604. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3605. this->gen_trap_check(bb);
  3606. return std::make_tuple(CONT, bb);
  3607. }
  3608. /* instruction 70: FCVT.L.D */
  3609. std::tuple<continuation_e, BasicBlock*> __fcvt_l_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3610. bb->setName("FCVT.L.D");
  3611. this->gen_sync(PRE_SYNC, 70);
  3612. uint8_t rd = ((bit_sub<7,5>(instr)));
  3613. uint8_t rm = ((bit_sub<12,3>(instr)));
  3614. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3615. if(this->disass_enabled){
  3616. /* generate console output when executing the command */
  3617. auto mnemonic = fmt::format(
  3618. "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.l.d"),
  3619. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1));
  3620. std::vector<Value*> args {
  3621. this->core_ptr,
  3622. this->gen_const(64, pc.val),
  3623. this->builder.CreateGlobalStringPtr(mnemonic),
  3624. };
  3625. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3626. }
  3627. Value* cur_pc_val = this->gen_const(64, pc.val);
  3628. pc=pc+4;
  3629. Value* Xtmp0_val = this->gen_ext(
  3630. this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector<Value*>{
  3631. this->builder.CreateTrunc(
  3632. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3633. this-> get_type(64)
  3634. ),
  3635. this->gen_ext(
  3636. this->gen_const(64U, 0LL),
  3637. 32,
  3638. false),
  3639. this->gen_const(8U, rm)
  3640. }),
  3641. 64,
  3642. true);
  3643. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3644. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  3645. });
  3646. Value* FCSR_val = this->builder.CreateAdd(
  3647. this->builder.CreateAnd(
  3648. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  3649. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  3650. flags_val);
  3651. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  3652. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3653. this->gen_sync(POST_SYNC, 70);
  3654. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3655. this->gen_trap_check(bb);
  3656. return std::make_tuple(CONT, bb);
  3657. }
  3658. /* instruction 71: FCVT.LU.D */
  3659. std::tuple<continuation_e, BasicBlock*> __fcvt_lu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3660. bb->setName("FCVT.LU.D");
  3661. this->gen_sync(PRE_SYNC, 71);
  3662. uint8_t rd = ((bit_sub<7,5>(instr)));
  3663. uint8_t rm = ((bit_sub<12,3>(instr)));
  3664. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3665. if(this->disass_enabled){
  3666. /* generate console output when executing the command */
  3667. auto mnemonic = fmt::format(
  3668. "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.lu.d"),
  3669. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1));
  3670. std::vector<Value*> args {
  3671. this->core_ptr,
  3672. this->gen_const(64, pc.val),
  3673. this->builder.CreateGlobalStringPtr(mnemonic),
  3674. };
  3675. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3676. }
  3677. Value* cur_pc_val = this->gen_const(64, pc.val);
  3678. pc=pc+4;
  3679. Value* Xtmp0_val = this->gen_ext(
  3680. this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector<Value*>{
  3681. this->builder.CreateTrunc(
  3682. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3683. this-> get_type(64)
  3684. ),
  3685. this->gen_ext(
  3686. this->gen_const(64U, 1LL),
  3687. 32,
  3688. false),
  3689. this->gen_const(8U, rm)
  3690. }),
  3691. 64,
  3692. true);
  3693. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3694. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  3695. });
  3696. Value* FCSR_val = this->builder.CreateAdd(
  3697. this->builder.CreateAnd(
  3698. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  3699. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  3700. flags_val);
  3701. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  3702. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3703. this->gen_sync(POST_SYNC, 71);
  3704. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3705. this->gen_trap_check(bb);
  3706. return std::make_tuple(CONT, bb);
  3707. }
  3708. /* instruction 72: FCVT.D.L */
  3709. std::tuple<continuation_e, BasicBlock*> __fcvt_d_l(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3710. bb->setName("FCVT.D.L");
  3711. this->gen_sync(PRE_SYNC, 72);
  3712. uint8_t rd = ((bit_sub<7,5>(instr)));
  3713. uint8_t rm = ((bit_sub<12,3>(instr)));
  3714. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3715. if(this->disass_enabled){
  3716. /* generate console output when executing the command */
  3717. auto mnemonic = fmt::format(
  3718. "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.l"),
  3719. fmt::arg("rd", rd), fmt::arg("rs1", name(rs1)));
  3720. std::vector<Value*> args {
  3721. this->core_ptr,
  3722. this->gen_const(64, pc.val),
  3723. this->builder.CreateGlobalStringPtr(mnemonic),
  3724. };
  3725. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3726. }
  3727. Value* cur_pc_val = this->gen_const(64, pc.val);
  3728. pc=pc+4;
  3729. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector<Value*>{
  3730. this->gen_ext(
  3731. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  3732. 64,
  3733. true),
  3734. this->gen_ext(
  3735. this->gen_const(64U, 2LL),
  3736. 32,
  3737. false),
  3738. this->gen_const(8U, rm)
  3739. });
  3740. if(64 == 64){
  3741. Value* Ftmp0_val = res_val;
  3742. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3743. } else {
  3744. uint64_t upper_val = - 1;
  3745. Value* Ftmp1_val = this->builder.CreateOr(
  3746. this->builder.CreateShl(
  3747. this->gen_const(64U, upper_val),
  3748. this->gen_const(64U, 64)),
  3749. res_val);
  3750. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3751. }
  3752. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3753. this->gen_sync(POST_SYNC, 72);
  3754. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3755. this->gen_trap_check(bb);
  3756. return std::make_tuple(CONT, bb);
  3757. }
  3758. /* instruction 73: FCVT.D.LU */
  3759. std::tuple<continuation_e, BasicBlock*> __fcvt_d_lu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3760. bb->setName("FCVT.D.LU");
  3761. this->gen_sync(PRE_SYNC, 73);
  3762. uint8_t rd = ((bit_sub<7,5>(instr)));
  3763. uint8_t rm = ((bit_sub<12,3>(instr)));
  3764. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3765. if(this->disass_enabled){
  3766. /* generate console output when executing the command */
  3767. auto mnemonic = fmt::format(
  3768. "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.lu"),
  3769. fmt::arg("rd", rd), fmt::arg("rs1", name(rs1)));
  3770. std::vector<Value*> args {
  3771. this->core_ptr,
  3772. this->gen_const(64, pc.val),
  3773. this->builder.CreateGlobalStringPtr(mnemonic),
  3774. };
  3775. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3776. }
  3777. Value* cur_pc_val = this->gen_const(64, pc.val);
  3778. pc=pc+4;
  3779. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector<Value*>{
  3780. this->gen_ext(
  3781. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  3782. 64,
  3783. false),
  3784. this->gen_ext(
  3785. this->gen_const(64U, 3LL),
  3786. 32,
  3787. false),
  3788. this->gen_const(8U, rm)
  3789. });
  3790. if(64 == 64){
  3791. Value* Ftmp0_val = res_val;
  3792. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3793. } else {
  3794. uint64_t upper_val = - 1;
  3795. Value* Ftmp1_val = this->builder.CreateOr(
  3796. this->builder.CreateShl(
  3797. this->gen_const(64U, upper_val),
  3798. this->gen_const(64U, 64)),
  3799. res_val);
  3800. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3801. }
  3802. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3803. this->gen_sync(POST_SYNC, 73);
  3804. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3805. this->gen_trap_check(bb);
  3806. return std::make_tuple(CONT, bb);
  3807. }
  3808. /* instruction 74: FMV.X.D */
  3809. std::tuple<continuation_e, BasicBlock*> __fmv_x_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3810. bb->setName("FMV.X.D");
  3811. this->gen_sync(PRE_SYNC, 74);
  3812. uint8_t rd = ((bit_sub<7,5>(instr)));
  3813. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3814. if(this->disass_enabled){
  3815. /* generate console output when executing the command */
  3816. auto mnemonic = fmt::format(
  3817. "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fmv.x.d"),
  3818. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1));
  3819. std::vector<Value*> args {
  3820. this->core_ptr,
  3821. this->gen_const(64, pc.val),
  3822. this->builder.CreateGlobalStringPtr(mnemonic),
  3823. };
  3824. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3825. }
  3826. Value* cur_pc_val = this->gen_const(64, pc.val);
  3827. pc=pc+4;
  3828. Value* Xtmp0_val = this->gen_ext(
  3829. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  3830. 64,
  3831. true);
  3832. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3833. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3834. this->gen_sync(POST_SYNC, 74);
  3835. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3836. this->gen_trap_check(bb);
  3837. return std::make_tuple(CONT, bb);
  3838. }
  3839. /* instruction 75: FMV.D.X */
  3840. std::tuple<continuation_e, BasicBlock*> __fmv_d_x(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3841. bb->setName("FMV.D.X");
  3842. this->gen_sync(PRE_SYNC, 75);
  3843. uint8_t rd = ((bit_sub<7,5>(instr)));
  3844. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3845. if(this->disass_enabled){
  3846. /* generate console output when executing the command */
  3847. auto mnemonic = fmt::format(
  3848. "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fmv.d.x"),
  3849. fmt::arg("rd", rd), fmt::arg("rs1", name(rs1)));
  3850. std::vector<Value*> args {
  3851. this->core_ptr,
  3852. this->gen_const(64, pc.val),
  3853. this->builder.CreateGlobalStringPtr(mnemonic),
  3854. };
  3855. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3856. }
  3857. Value* cur_pc_val = this->gen_const(64, pc.val);
  3858. pc=pc+4;
  3859. Value* Ftmp0_val = this->gen_ext(
  3860. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  3861. 64,
  3862. false);
  3863. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  3864. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3865. this->gen_sync(POST_SYNC, 75);
  3866. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3867. this->gen_trap_check(bb);
  3868. return std::make_tuple(CONT, bb);
  3869. }
  3870. /* instruction 76: LUI */
  3871. std::tuple<continuation_e, BasicBlock*> __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3872. bb->setName("LUI");
  3873. this->gen_sync(PRE_SYNC, 76);
  3874. uint8_t rd = ((bit_sub<7,5>(instr)));
  3875. int32_t imm = signextend<int32_t,32>((bit_sub<12,20>(instr) << 12));
  3876. if(this->disass_enabled){
  3877. /* generate console output when executing the command */
  3878. auto mnemonic = fmt::format(
  3879. "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"),
  3880. fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
  3881. std::vector<Value*> args {
  3882. this->core_ptr,
  3883. this->gen_const(64, pc.val),
  3884. this->builder.CreateGlobalStringPtr(mnemonic),
  3885. };
  3886. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3887. }
  3888. Value* cur_pc_val = this->gen_const(64, pc.val);
  3889. pc=pc+4;
  3890. if(rd != 0){
  3891. Value* Xtmp0_val = this->gen_const(64U, imm);
  3892. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3893. }
  3894. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3895. this->gen_sync(POST_SYNC, 76);
  3896. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3897. this->gen_trap_check(bb);
  3898. return std::make_tuple(CONT, bb);
  3899. }
  3900. /* instruction 77: AUIPC */
  3901. std::tuple<continuation_e, BasicBlock*> __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3902. bb->setName("AUIPC");
  3903. this->gen_sync(PRE_SYNC, 77);
  3904. uint8_t rd = ((bit_sub<7,5>(instr)));
  3905. int32_t imm = signextend<int32_t,32>((bit_sub<12,20>(instr) << 12));
  3906. if(this->disass_enabled){
  3907. /* generate console output when executing the command */
  3908. auto mnemonic = fmt::format(
  3909. "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"),
  3910. fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
  3911. std::vector<Value*> args {
  3912. this->core_ptr,
  3913. this->gen_const(64, pc.val),
  3914. this->builder.CreateGlobalStringPtr(mnemonic),
  3915. };
  3916. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3917. }
  3918. Value* cur_pc_val = this->gen_const(64, pc.val);
  3919. pc=pc+4;
  3920. if(rd != 0){
  3921. Value* Xtmp0_val = this->builder.CreateAdd(
  3922. this->gen_ext(
  3923. cur_pc_val,
  3924. 64, true),
  3925. this->gen_const(64U, imm));
  3926. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3927. }
  3928. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  3929. this->gen_sync(POST_SYNC, 77);
  3930. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  3931. this->gen_trap_check(bb);
  3932. return std::make_tuple(CONT, bb);
  3933. }
  3934. /* instruction 78: JAL */
  3935. std::tuple<continuation_e, BasicBlock*> __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3936. bb->setName("JAL");
  3937. this->gen_sync(PRE_SYNC, 78);
  3938. uint8_t rd = ((bit_sub<7,5>(instr)));
  3939. int32_t imm = signextend<int32_t,21>((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20));
  3940. if(this->disass_enabled){
  3941. /* generate console output when executing the command */
  3942. auto mnemonic = fmt::format(
  3943. "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"),
  3944. fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
  3945. std::vector<Value*> args {
  3946. this->core_ptr,
  3947. this->gen_const(64, pc.val),
  3948. this->builder.CreateGlobalStringPtr(mnemonic),
  3949. };
  3950. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3951. }
  3952. Value* cur_pc_val = this->gen_const(64, pc.val);
  3953. pc=pc+4;
  3954. if(rd != 0){
  3955. Value* Xtmp0_val = this->builder.CreateAdd(
  3956. cur_pc_val,
  3957. this->gen_const(64U, 4));
  3958. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  3959. }
  3960. Value* PC_val = this->builder.CreateAdd(
  3961. this->gen_ext(
  3962. cur_pc_val,
  3963. 64, true),
  3964. this->gen_const(64U, imm));
  3965. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  3966. Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v");
  3967. this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  3968. this->gen_sync(POST_SYNC, 78);
  3969. this->gen_trap_check(this->leave_blk);
  3970. return std::make_tuple(BRANCH, nullptr);
  3971. }
  3972. /* instruction 79: BEQ */
  3973. std::tuple<continuation_e, BasicBlock*> __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  3974. bb->setName("BEQ");
  3975. this->gen_sync(PRE_SYNC, 79);
  3976. int16_t imm = signextend<int16_t,13>((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
  3977. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  3978. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  3979. if(this->disass_enabled){
  3980. /* generate console output when executing the command */
  3981. auto mnemonic = fmt::format(
  3982. "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"),
  3983. fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
  3984. std::vector<Value*> args {
  3985. this->core_ptr,
  3986. this->gen_const(64, pc.val),
  3987. this->builder.CreateGlobalStringPtr(mnemonic),
  3988. };
  3989. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  3990. }
  3991. Value* cur_pc_val = this->gen_const(64, pc.val);
  3992. pc=pc+4;
  3993. Value* PC_val = this->gen_choose(
  3994. this->builder.CreateICmp(
  3995. ICmpInst::ICMP_EQ,
  3996. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  3997. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0)),
  3998. this->builder.CreateAdd(
  3999. this->gen_ext(
  4000. cur_pc_val,
  4001. 64, true),
  4002. this->gen_const(64U, imm)),
  4003. this->builder.CreateAdd(
  4004. cur_pc_val,
  4005. this->gen_const(64U, 4)),
  4006. 64);
  4007. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  4008. Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v");
  4009. this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  4010. this->gen_sync(POST_SYNC, 79);
  4011. this->gen_trap_check(this->leave_blk);
  4012. return std::make_tuple(BRANCH, nullptr);
  4013. }
  4014. /* instruction 80: BNE */
  4015. std::tuple<continuation_e, BasicBlock*> __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4016. bb->setName("BNE");
  4017. this->gen_sync(PRE_SYNC, 80);
  4018. int16_t imm = signextend<int16_t,13>((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
  4019. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4020. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4021. if(this->disass_enabled){
  4022. /* generate console output when executing the command */
  4023. auto mnemonic = fmt::format(
  4024. "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"),
  4025. fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
  4026. std::vector<Value*> args {
  4027. this->core_ptr,
  4028. this->gen_const(64, pc.val),
  4029. this->builder.CreateGlobalStringPtr(mnemonic),
  4030. };
  4031. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4032. }
  4033. Value* cur_pc_val = this->gen_const(64, pc.val);
  4034. pc=pc+4;
  4035. Value* PC_val = this->gen_choose(
  4036. this->builder.CreateICmp(
  4037. ICmpInst::ICMP_NE,
  4038. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4039. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0)),
  4040. this->builder.CreateAdd(
  4041. this->gen_ext(
  4042. cur_pc_val,
  4043. 64, true),
  4044. this->gen_const(64U, imm)),
  4045. this->builder.CreateAdd(
  4046. cur_pc_val,
  4047. this->gen_const(64U, 4)),
  4048. 64);
  4049. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  4050. Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v");
  4051. this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  4052. this->gen_sync(POST_SYNC, 80);
  4053. this->gen_trap_check(this->leave_blk);
  4054. return std::make_tuple(BRANCH, nullptr);
  4055. }
  4056. /* instruction 81: BLT */
  4057. std::tuple<continuation_e, BasicBlock*> __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4058. bb->setName("BLT");
  4059. this->gen_sync(PRE_SYNC, 81);
  4060. int16_t imm = signextend<int16_t,13>((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
  4061. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4062. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4063. if(this->disass_enabled){
  4064. /* generate console output when executing the command */
  4065. auto mnemonic = fmt::format(
  4066. "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"),
  4067. fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
  4068. std::vector<Value*> args {
  4069. this->core_ptr,
  4070. this->gen_const(64, pc.val),
  4071. this->builder.CreateGlobalStringPtr(mnemonic),
  4072. };
  4073. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4074. }
  4075. Value* cur_pc_val = this->gen_const(64, pc.val);
  4076. pc=pc+4;
  4077. Value* PC_val = this->gen_choose(
  4078. this->builder.CreateICmp(
  4079. ICmpInst::ICMP_SLT,
  4080. this->gen_ext(
  4081. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4082. 64, true),
  4083. this->gen_ext(
  4084. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0),
  4085. 64, true)),
  4086. this->builder.CreateAdd(
  4087. this->gen_ext(
  4088. cur_pc_val,
  4089. 64, true),
  4090. this->gen_const(64U, imm)),
  4091. this->builder.CreateAdd(
  4092. cur_pc_val,
  4093. this->gen_const(64U, 4)),
  4094. 64);
  4095. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  4096. Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v");
  4097. this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  4098. this->gen_sync(POST_SYNC, 81);
  4099. this->gen_trap_check(this->leave_blk);
  4100. return std::make_tuple(BRANCH, nullptr);
  4101. }
  4102. /* instruction 82: BGE */
  4103. std::tuple<continuation_e, BasicBlock*> __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4104. bb->setName("BGE");
  4105. this->gen_sync(PRE_SYNC, 82);
  4106. int16_t imm = signextend<int16_t,13>((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
  4107. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4108. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4109. if(this->disass_enabled){
  4110. /* generate console output when executing the command */
  4111. auto mnemonic = fmt::format(
  4112. "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"),
  4113. fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
  4114. std::vector<Value*> args {
  4115. this->core_ptr,
  4116. this->gen_const(64, pc.val),
  4117. this->builder.CreateGlobalStringPtr(mnemonic),
  4118. };
  4119. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4120. }
  4121. Value* cur_pc_val = this->gen_const(64, pc.val);
  4122. pc=pc+4;
  4123. Value* PC_val = this->gen_choose(
  4124. this->builder.CreateICmp(
  4125. ICmpInst::ICMP_SGE,
  4126. this->gen_ext(
  4127. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4128. 64, true),
  4129. this->gen_ext(
  4130. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0),
  4131. 64, true)),
  4132. this->builder.CreateAdd(
  4133. this->gen_ext(
  4134. cur_pc_val,
  4135. 64, true),
  4136. this->gen_const(64U, imm)),
  4137. this->builder.CreateAdd(
  4138. cur_pc_val,
  4139. this->gen_const(64U, 4)),
  4140. 64);
  4141. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  4142. Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v");
  4143. this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  4144. this->gen_sync(POST_SYNC, 82);
  4145. this->gen_trap_check(this->leave_blk);
  4146. return std::make_tuple(BRANCH, nullptr);
  4147. }
  4148. /* instruction 83: BLTU */
  4149. std::tuple<continuation_e, BasicBlock*> __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4150. bb->setName("BLTU");
  4151. this->gen_sync(PRE_SYNC, 83);
  4152. int16_t imm = signextend<int16_t,13>((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
  4153. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4154. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4155. if(this->disass_enabled){
  4156. /* generate console output when executing the command */
  4157. auto mnemonic = fmt::format(
  4158. "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"),
  4159. fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
  4160. std::vector<Value*> args {
  4161. this->core_ptr,
  4162. this->gen_const(64, pc.val),
  4163. this->builder.CreateGlobalStringPtr(mnemonic),
  4164. };
  4165. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4166. }
  4167. Value* cur_pc_val = this->gen_const(64, pc.val);
  4168. pc=pc+4;
  4169. Value* PC_val = this->gen_choose(
  4170. this->builder.CreateICmp(
  4171. ICmpInst::ICMP_ULT,
  4172. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4173. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0)),
  4174. this->builder.CreateAdd(
  4175. this->gen_ext(
  4176. cur_pc_val,
  4177. 64, true),
  4178. this->gen_const(64U, imm)),
  4179. this->builder.CreateAdd(
  4180. cur_pc_val,
  4181. this->gen_const(64U, 4)),
  4182. 64);
  4183. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  4184. Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v");
  4185. this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  4186. this->gen_sync(POST_SYNC, 83);
  4187. this->gen_trap_check(this->leave_blk);
  4188. return std::make_tuple(BRANCH, nullptr);
  4189. }
  4190. /* instruction 84: BGEU */
  4191. std::tuple<continuation_e, BasicBlock*> __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4192. bb->setName("BGEU");
  4193. this->gen_sync(PRE_SYNC, 84);
  4194. int16_t imm = signextend<int16_t,13>((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
  4195. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4196. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4197. if(this->disass_enabled){
  4198. /* generate console output when executing the command */
  4199. auto mnemonic = fmt::format(
  4200. "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"),
  4201. fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
  4202. std::vector<Value*> args {
  4203. this->core_ptr,
  4204. this->gen_const(64, pc.val),
  4205. this->builder.CreateGlobalStringPtr(mnemonic),
  4206. };
  4207. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4208. }
  4209. Value* cur_pc_val = this->gen_const(64, pc.val);
  4210. pc=pc+4;
  4211. Value* PC_val = this->gen_choose(
  4212. this->builder.CreateICmp(
  4213. ICmpInst::ICMP_UGE,
  4214. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4215. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0)),
  4216. this->builder.CreateAdd(
  4217. this->gen_ext(
  4218. cur_pc_val,
  4219. 64, true),
  4220. this->gen_const(64U, imm)),
  4221. this->builder.CreateAdd(
  4222. cur_pc_val,
  4223. this->gen_const(64U, 4)),
  4224. 64);
  4225. this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
  4226. Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v");
  4227. this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  4228. this->gen_sync(POST_SYNC, 84);
  4229. this->gen_trap_check(this->leave_blk);
  4230. return std::make_tuple(BRANCH, nullptr);
  4231. }
  4232. /* instruction 85: LB */
  4233. std::tuple<continuation_e, BasicBlock*> __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4234. bb->setName("LB");
  4235. this->gen_sync(PRE_SYNC, 85);
  4236. uint8_t rd = ((bit_sub<7,5>(instr)));
  4237. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4238. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  4239. if(this->disass_enabled){
  4240. /* generate console output when executing the command */
  4241. auto mnemonic = fmt::format(
  4242. "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"),
  4243. fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
  4244. std::vector<Value*> args {
  4245. this->core_ptr,
  4246. this->gen_const(64, pc.val),
  4247. this->builder.CreateGlobalStringPtr(mnemonic),
  4248. };
  4249. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4250. }
  4251. Value* cur_pc_val = this->gen_const(64, pc.val);
  4252. pc=pc+4;
  4253. Value* offs_val = this->builder.CreateAdd(
  4254. this->gen_ext(
  4255. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4256. 64, true),
  4257. this->gen_const(64U, imm));
  4258. if(rd != 0){
  4259. Value* Xtmp0_val = this->gen_ext(
  4260. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 8/8),
  4261. 64,
  4262. true);
  4263. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4264. }
  4265. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4266. this->gen_sync(POST_SYNC, 85);
  4267. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4268. this->gen_trap_check(bb);
  4269. return std::make_tuple(CONT, bb);
  4270. }
  4271. /* instruction 86: LH */
  4272. std::tuple<continuation_e, BasicBlock*> __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4273. bb->setName("LH");
  4274. this->gen_sync(PRE_SYNC, 86);
  4275. uint8_t rd = ((bit_sub<7,5>(instr)));
  4276. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4277. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  4278. if(this->disass_enabled){
  4279. /* generate console output when executing the command */
  4280. auto mnemonic = fmt::format(
  4281. "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"),
  4282. fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
  4283. std::vector<Value*> args {
  4284. this->core_ptr,
  4285. this->gen_const(64, pc.val),
  4286. this->builder.CreateGlobalStringPtr(mnemonic),
  4287. };
  4288. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4289. }
  4290. Value* cur_pc_val = this->gen_const(64, pc.val);
  4291. pc=pc+4;
  4292. Value* offs_val = this->builder.CreateAdd(
  4293. this->gen_ext(
  4294. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4295. 64, true),
  4296. this->gen_const(64U, imm));
  4297. if(rd != 0){
  4298. Value* Xtmp0_val = this->gen_ext(
  4299. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 16/8),
  4300. 64,
  4301. true);
  4302. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4303. }
  4304. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4305. this->gen_sync(POST_SYNC, 86);
  4306. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4307. this->gen_trap_check(bb);
  4308. return std::make_tuple(CONT, bb);
  4309. }
  4310. /* instruction 87: LW */
  4311. std::tuple<continuation_e, BasicBlock*> __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4312. bb->setName("LW");
  4313. this->gen_sync(PRE_SYNC, 87);
  4314. uint8_t rd = ((bit_sub<7,5>(instr)));
  4315. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4316. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  4317. if(this->disass_enabled){
  4318. /* generate console output when executing the command */
  4319. auto mnemonic = fmt::format(
  4320. "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"),
  4321. fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
  4322. std::vector<Value*> args {
  4323. this->core_ptr,
  4324. this->gen_const(64, pc.val),
  4325. this->builder.CreateGlobalStringPtr(mnemonic),
  4326. };
  4327. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4328. }
  4329. Value* cur_pc_val = this->gen_const(64, pc.val);
  4330. pc=pc+4;
  4331. Value* offs_val = this->builder.CreateAdd(
  4332. this->gen_ext(
  4333. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4334. 64, true),
  4335. this->gen_const(64U, imm));
  4336. if(rd != 0){
  4337. Value* Xtmp0_val = this->gen_ext(
  4338. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8),
  4339. 64,
  4340. true);
  4341. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4342. }
  4343. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4344. this->gen_sync(POST_SYNC, 87);
  4345. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4346. this->gen_trap_check(bb);
  4347. return std::make_tuple(CONT, bb);
  4348. }
  4349. /* instruction 88: LBU */
  4350. std::tuple<continuation_e, BasicBlock*> __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4351. bb->setName("LBU");
  4352. this->gen_sync(PRE_SYNC, 88);
  4353. uint8_t rd = ((bit_sub<7,5>(instr)));
  4354. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4355. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  4356. if(this->disass_enabled){
  4357. /* generate console output when executing the command */
  4358. auto mnemonic = fmt::format(
  4359. "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"),
  4360. fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
  4361. std::vector<Value*> args {
  4362. this->core_ptr,
  4363. this->gen_const(64, pc.val),
  4364. this->builder.CreateGlobalStringPtr(mnemonic),
  4365. };
  4366. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4367. }
  4368. Value* cur_pc_val = this->gen_const(64, pc.val);
  4369. pc=pc+4;
  4370. Value* offs_val = this->builder.CreateAdd(
  4371. this->gen_ext(
  4372. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4373. 64, true),
  4374. this->gen_const(64U, imm));
  4375. if(rd != 0){
  4376. Value* Xtmp0_val = this->gen_ext(
  4377. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 8/8),
  4378. 64,
  4379. false);
  4380. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4381. }
  4382. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4383. this->gen_sync(POST_SYNC, 88);
  4384. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4385. this->gen_trap_check(bb);
  4386. return std::make_tuple(CONT, bb);
  4387. }
  4388. /* instruction 89: LHU */
  4389. std::tuple<continuation_e, BasicBlock*> __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4390. bb->setName("LHU");
  4391. this->gen_sync(PRE_SYNC, 89);
  4392. uint8_t rd = ((bit_sub<7,5>(instr)));
  4393. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4394. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  4395. if(this->disass_enabled){
  4396. /* generate console output when executing the command */
  4397. auto mnemonic = fmt::format(
  4398. "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"),
  4399. fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
  4400. std::vector<Value*> args {
  4401. this->core_ptr,
  4402. this->gen_const(64, pc.val),
  4403. this->builder.CreateGlobalStringPtr(mnemonic),
  4404. };
  4405. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4406. }
  4407. Value* cur_pc_val = this->gen_const(64, pc.val);
  4408. pc=pc+4;
  4409. Value* offs_val = this->builder.CreateAdd(
  4410. this->gen_ext(
  4411. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4412. 64, true),
  4413. this->gen_const(64U, imm));
  4414. if(rd != 0){
  4415. Value* Xtmp0_val = this->gen_ext(
  4416. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 16/8),
  4417. 64,
  4418. false);
  4419. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4420. }
  4421. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4422. this->gen_sync(POST_SYNC, 89);
  4423. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4424. this->gen_trap_check(bb);
  4425. return std::make_tuple(CONT, bb);
  4426. }
  4427. /* instruction 90: SB */
  4428. std::tuple<continuation_e, BasicBlock*> __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4429. bb->setName("SB");
  4430. this->gen_sync(PRE_SYNC, 90);
  4431. int16_t imm = signextend<int16_t,12>((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5));
  4432. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4433. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4434. if(this->disass_enabled){
  4435. /* generate console output when executing the command */
  4436. auto mnemonic = fmt::format(
  4437. "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"),
  4438. fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
  4439. std::vector<Value*> args {
  4440. this->core_ptr,
  4441. this->gen_const(64, pc.val),
  4442. this->builder.CreateGlobalStringPtr(mnemonic),
  4443. };
  4444. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4445. }
  4446. Value* cur_pc_val = this->gen_const(64, pc.val);
  4447. pc=pc+4;
  4448. Value* offs_val = this->builder.CreateAdd(
  4449. this->gen_ext(
  4450. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4451. 64, true),
  4452. this->gen_const(64U, imm));
  4453. Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits<ARCH>::X0, 0);
  4454. this->gen_write_mem(
  4455. traits<ARCH>::MEM,
  4456. offs_val,
  4457. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8)));
  4458. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4459. this->gen_sync(POST_SYNC, 90);
  4460. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4461. this->gen_trap_check(bb);
  4462. return std::make_tuple(CONT, bb);
  4463. }
  4464. /* instruction 91: SH */
  4465. std::tuple<continuation_e, BasicBlock*> __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4466. bb->setName("SH");
  4467. this->gen_sync(PRE_SYNC, 91);
  4468. int16_t imm = signextend<int16_t,12>((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5));
  4469. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4470. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4471. if(this->disass_enabled){
  4472. /* generate console output when executing the command */
  4473. auto mnemonic = fmt::format(
  4474. "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"),
  4475. fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
  4476. std::vector<Value*> args {
  4477. this->core_ptr,
  4478. this->gen_const(64, pc.val),
  4479. this->builder.CreateGlobalStringPtr(mnemonic),
  4480. };
  4481. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4482. }
  4483. Value* cur_pc_val = this->gen_const(64, pc.val);
  4484. pc=pc+4;
  4485. Value* offs_val = this->builder.CreateAdd(
  4486. this->gen_ext(
  4487. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4488. 64, true),
  4489. this->gen_const(64U, imm));
  4490. Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits<ARCH>::X0, 0);
  4491. this->gen_write_mem(
  4492. traits<ARCH>::MEM,
  4493. offs_val,
  4494. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16)));
  4495. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4496. this->gen_sync(POST_SYNC, 91);
  4497. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4498. this->gen_trap_check(bb);
  4499. return std::make_tuple(CONT, bb);
  4500. }
  4501. /* instruction 92: SW */
  4502. std::tuple<continuation_e, BasicBlock*> __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4503. bb->setName("SW");
  4504. this->gen_sync(PRE_SYNC, 92);
  4505. int16_t imm = signextend<int16_t,12>((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5));
  4506. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4507. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4508. if(this->disass_enabled){
  4509. /* generate console output when executing the command */
  4510. auto mnemonic = fmt::format(
  4511. "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"),
  4512. fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
  4513. std::vector<Value*> args {
  4514. this->core_ptr,
  4515. this->gen_const(64, pc.val),
  4516. this->builder.CreateGlobalStringPtr(mnemonic),
  4517. };
  4518. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4519. }
  4520. Value* cur_pc_val = this->gen_const(64, pc.val);
  4521. pc=pc+4;
  4522. Value* offs_val = this->builder.CreateAdd(
  4523. this->gen_ext(
  4524. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4525. 64, true),
  4526. this->gen_const(64U, imm));
  4527. Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits<ARCH>::X0, 0);
  4528. this->gen_write_mem(
  4529. traits<ARCH>::MEM,
  4530. offs_val,
  4531. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32)));
  4532. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4533. this->gen_sync(POST_SYNC, 92);
  4534. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4535. this->gen_trap_check(bb);
  4536. return std::make_tuple(CONT, bb);
  4537. }
  4538. /* instruction 93: ADDI */
  4539. std::tuple<continuation_e, BasicBlock*> __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4540. bb->setName("ADDI");
  4541. this->gen_sync(PRE_SYNC, 93);
  4542. uint8_t rd = ((bit_sub<7,5>(instr)));
  4543. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4544. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  4545. if(this->disass_enabled){
  4546. /* generate console output when executing the command */
  4547. auto mnemonic = fmt::format(
  4548. "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"),
  4549. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
  4550. std::vector<Value*> args {
  4551. this->core_ptr,
  4552. this->gen_const(64, pc.val),
  4553. this->builder.CreateGlobalStringPtr(mnemonic),
  4554. };
  4555. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4556. }
  4557. Value* cur_pc_val = this->gen_const(64, pc.val);
  4558. pc=pc+4;
  4559. if(rd != 0){
  4560. Value* Xtmp0_val = this->builder.CreateAdd(
  4561. this->gen_ext(
  4562. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4563. 64, true),
  4564. this->gen_const(64U, imm));
  4565. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4566. }
  4567. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4568. this->gen_sync(POST_SYNC, 93);
  4569. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4570. this->gen_trap_check(bb);
  4571. return std::make_tuple(CONT, bb);
  4572. }
  4573. /* instruction 94: SLTI */
  4574. std::tuple<continuation_e, BasicBlock*> __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4575. bb->setName("SLTI");
  4576. this->gen_sync(PRE_SYNC, 94);
  4577. uint8_t rd = ((bit_sub<7,5>(instr)));
  4578. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4579. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  4580. if(this->disass_enabled){
  4581. /* generate console output when executing the command */
  4582. auto mnemonic = fmt::format(
  4583. "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"),
  4584. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
  4585. std::vector<Value*> args {
  4586. this->core_ptr,
  4587. this->gen_const(64, pc.val),
  4588. this->builder.CreateGlobalStringPtr(mnemonic),
  4589. };
  4590. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4591. }
  4592. Value* cur_pc_val = this->gen_const(64, pc.val);
  4593. pc=pc+4;
  4594. if(rd != 0){
  4595. Value* Xtmp0_val = this->gen_choose(
  4596. this->builder.CreateICmp(
  4597. ICmpInst::ICMP_SLT,
  4598. this->gen_ext(
  4599. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4600. 64, true),
  4601. this->gen_const(64U, imm)),
  4602. this->gen_const(64U, 1),
  4603. this->gen_const(64U, 0),
  4604. 64);
  4605. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4606. }
  4607. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4608. this->gen_sync(POST_SYNC, 94);
  4609. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4610. this->gen_trap_check(bb);
  4611. return std::make_tuple(CONT, bb);
  4612. }
  4613. /* instruction 95: SLTIU */
  4614. std::tuple<continuation_e, BasicBlock*> __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4615. bb->setName("SLTIU");
  4616. this->gen_sync(PRE_SYNC, 95);
  4617. uint8_t rd = ((bit_sub<7,5>(instr)));
  4618. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4619. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  4620. if(this->disass_enabled){
  4621. /* generate console output when executing the command */
  4622. auto mnemonic = fmt::format(
  4623. "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"),
  4624. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
  4625. std::vector<Value*> args {
  4626. this->core_ptr,
  4627. this->gen_const(64, pc.val),
  4628. this->builder.CreateGlobalStringPtr(mnemonic),
  4629. };
  4630. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4631. }
  4632. Value* cur_pc_val = this->gen_const(64, pc.val);
  4633. pc=pc+4;
  4634. int64_t full_imm_val = imm;
  4635. if(rd != 0){
  4636. Value* Xtmp0_val = this->gen_choose(
  4637. this->builder.CreateICmp(
  4638. ICmpInst::ICMP_ULT,
  4639. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4640. this->gen_const(64U, full_imm_val)),
  4641. this->gen_const(64U, 1),
  4642. this->gen_const(64U, 0),
  4643. 64);
  4644. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4645. }
  4646. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4647. this->gen_sync(POST_SYNC, 95);
  4648. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4649. this->gen_trap_check(bb);
  4650. return std::make_tuple(CONT, bb);
  4651. }
  4652. /* instruction 96: XORI */
  4653. std::tuple<continuation_e, BasicBlock*> __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4654. bb->setName("XORI");
  4655. this->gen_sync(PRE_SYNC, 96);
  4656. uint8_t rd = ((bit_sub<7,5>(instr)));
  4657. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4658. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  4659. if(this->disass_enabled){
  4660. /* generate console output when executing the command */
  4661. auto mnemonic = fmt::format(
  4662. "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"),
  4663. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
  4664. std::vector<Value*> args {
  4665. this->core_ptr,
  4666. this->gen_const(64, pc.val),
  4667. this->builder.CreateGlobalStringPtr(mnemonic),
  4668. };
  4669. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4670. }
  4671. Value* cur_pc_val = this->gen_const(64, pc.val);
  4672. pc=pc+4;
  4673. if(rd != 0){
  4674. Value* Xtmp0_val = this->builder.CreateXor(
  4675. this->gen_ext(
  4676. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4677. 64, true),
  4678. this->gen_const(64U, imm));
  4679. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4680. }
  4681. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4682. this->gen_sync(POST_SYNC, 96);
  4683. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4684. this->gen_trap_check(bb);
  4685. return std::make_tuple(CONT, bb);
  4686. }
  4687. /* instruction 97: ORI */
  4688. std::tuple<continuation_e, BasicBlock*> __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4689. bb->setName("ORI");
  4690. this->gen_sync(PRE_SYNC, 97);
  4691. uint8_t rd = ((bit_sub<7,5>(instr)));
  4692. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4693. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  4694. if(this->disass_enabled){
  4695. /* generate console output when executing the command */
  4696. auto mnemonic = fmt::format(
  4697. "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"),
  4698. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
  4699. std::vector<Value*> args {
  4700. this->core_ptr,
  4701. this->gen_const(64, pc.val),
  4702. this->builder.CreateGlobalStringPtr(mnemonic),
  4703. };
  4704. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4705. }
  4706. Value* cur_pc_val = this->gen_const(64, pc.val);
  4707. pc=pc+4;
  4708. if(rd != 0){
  4709. Value* Xtmp0_val = this->builder.CreateOr(
  4710. this->gen_ext(
  4711. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4712. 64, true),
  4713. this->gen_const(64U, imm));
  4714. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4715. }
  4716. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4717. this->gen_sync(POST_SYNC, 97);
  4718. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4719. this->gen_trap_check(bb);
  4720. return std::make_tuple(CONT, bb);
  4721. }
  4722. /* instruction 98: ANDI */
  4723. std::tuple<continuation_e, BasicBlock*> __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4724. bb->setName("ANDI");
  4725. this->gen_sync(PRE_SYNC, 98);
  4726. uint8_t rd = ((bit_sub<7,5>(instr)));
  4727. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4728. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  4729. if(this->disass_enabled){
  4730. /* generate console output when executing the command */
  4731. auto mnemonic = fmt::format(
  4732. "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"),
  4733. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
  4734. std::vector<Value*> args {
  4735. this->core_ptr,
  4736. this->gen_const(64, pc.val),
  4737. this->builder.CreateGlobalStringPtr(mnemonic),
  4738. };
  4739. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4740. }
  4741. Value* cur_pc_val = this->gen_const(64, pc.val);
  4742. pc=pc+4;
  4743. if(rd != 0){
  4744. Value* Xtmp0_val = this->builder.CreateAnd(
  4745. this->gen_ext(
  4746. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4747. 64, true),
  4748. this->gen_const(64U, imm));
  4749. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4750. }
  4751. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4752. this->gen_sync(POST_SYNC, 98);
  4753. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4754. this->gen_trap_check(bb);
  4755. return std::make_tuple(CONT, bb);
  4756. }
  4757. /* instruction 99: SLLI */
  4758. std::tuple<continuation_e, BasicBlock*> __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4759. bb->setName("SLLI");
  4760. this->gen_sync(PRE_SYNC, 99);
  4761. uint8_t rd = ((bit_sub<7,5>(instr)));
  4762. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4763. uint8_t shamt = ((bit_sub<20,6>(instr)));
  4764. if(this->disass_enabled){
  4765. /* generate console output when executing the command */
  4766. auto mnemonic = fmt::format(
  4767. "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"),
  4768. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt));
  4769. std::vector<Value*> args {
  4770. this->core_ptr,
  4771. this->gen_const(64, pc.val),
  4772. this->builder.CreateGlobalStringPtr(mnemonic),
  4773. };
  4774. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4775. }
  4776. Value* cur_pc_val = this->gen_const(64, pc.val);
  4777. pc=pc+4;
  4778. if(rd != 0){
  4779. Value* Xtmp0_val = this->builder.CreateShl(
  4780. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4781. this->gen_const(64U, shamt));
  4782. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4783. }
  4784. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4785. this->gen_sync(POST_SYNC, 99);
  4786. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4787. this->gen_trap_check(bb);
  4788. return std::make_tuple(CONT, bb);
  4789. }
  4790. /* instruction 100: SRLI */
  4791. std::tuple<continuation_e, BasicBlock*> __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4792. bb->setName("SRLI");
  4793. this->gen_sync(PRE_SYNC, 100);
  4794. uint8_t rd = ((bit_sub<7,5>(instr)));
  4795. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4796. uint8_t shamt = ((bit_sub<20,6>(instr)));
  4797. if(this->disass_enabled){
  4798. /* generate console output when executing the command */
  4799. auto mnemonic = fmt::format(
  4800. "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"),
  4801. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt));
  4802. std::vector<Value*> args {
  4803. this->core_ptr,
  4804. this->gen_const(64, pc.val),
  4805. this->builder.CreateGlobalStringPtr(mnemonic),
  4806. };
  4807. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4808. }
  4809. Value* cur_pc_val = this->gen_const(64, pc.val);
  4810. pc=pc+4;
  4811. if(rd != 0){
  4812. Value* Xtmp0_val = this->builder.CreateLShr(
  4813. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4814. this->gen_const(64U, shamt));
  4815. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4816. }
  4817. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4818. this->gen_sync(POST_SYNC, 100);
  4819. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4820. this->gen_trap_check(bb);
  4821. return std::make_tuple(CONT, bb);
  4822. }
  4823. /* instruction 101: SRAI */
  4824. std::tuple<continuation_e, BasicBlock*> __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4825. bb->setName("SRAI");
  4826. this->gen_sync(PRE_SYNC, 101);
  4827. uint8_t rd = ((bit_sub<7,5>(instr)));
  4828. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4829. uint8_t shamt = ((bit_sub<20,6>(instr)));
  4830. if(this->disass_enabled){
  4831. /* generate console output when executing the command */
  4832. auto mnemonic = fmt::format(
  4833. "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"),
  4834. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt));
  4835. std::vector<Value*> args {
  4836. this->core_ptr,
  4837. this->gen_const(64, pc.val),
  4838. this->builder.CreateGlobalStringPtr(mnemonic),
  4839. };
  4840. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4841. }
  4842. Value* cur_pc_val = this->gen_const(64, pc.val);
  4843. pc=pc+4;
  4844. if(rd != 0){
  4845. Value* Xtmp0_val = this->builder.CreateAShr(
  4846. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4847. this->gen_const(64U, shamt));
  4848. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4849. }
  4850. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4851. this->gen_sync(POST_SYNC, 101);
  4852. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4853. this->gen_trap_check(bb);
  4854. return std::make_tuple(CONT, bb);
  4855. }
  4856. /* instruction 102: ADD */
  4857. std::tuple<continuation_e, BasicBlock*> __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4858. bb->setName("ADD");
  4859. this->gen_sync(PRE_SYNC, 102);
  4860. uint8_t rd = ((bit_sub<7,5>(instr)));
  4861. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4862. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4863. if(this->disass_enabled){
  4864. /* generate console output when executing the command */
  4865. auto mnemonic = fmt::format(
  4866. "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"),
  4867. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
  4868. std::vector<Value*> args {
  4869. this->core_ptr,
  4870. this->gen_const(64, pc.val),
  4871. this->builder.CreateGlobalStringPtr(mnemonic),
  4872. };
  4873. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4874. }
  4875. Value* cur_pc_val = this->gen_const(64, pc.val);
  4876. pc=pc+4;
  4877. if(rd != 0){
  4878. Value* Xtmp0_val = this->builder.CreateAdd(
  4879. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4880. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0));
  4881. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4882. }
  4883. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4884. this->gen_sync(POST_SYNC, 102);
  4885. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4886. this->gen_trap_check(bb);
  4887. return std::make_tuple(CONT, bb);
  4888. }
  4889. /* instruction 103: SUB */
  4890. std::tuple<continuation_e, BasicBlock*> __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4891. bb->setName("SUB");
  4892. this->gen_sync(PRE_SYNC, 103);
  4893. uint8_t rd = ((bit_sub<7,5>(instr)));
  4894. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4895. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4896. if(this->disass_enabled){
  4897. /* generate console output when executing the command */
  4898. auto mnemonic = fmt::format(
  4899. "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"),
  4900. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
  4901. std::vector<Value*> args {
  4902. this->core_ptr,
  4903. this->gen_const(64, pc.val),
  4904. this->builder.CreateGlobalStringPtr(mnemonic),
  4905. };
  4906. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4907. }
  4908. Value* cur_pc_val = this->gen_const(64, pc.val);
  4909. pc=pc+4;
  4910. if(rd != 0){
  4911. Value* Xtmp0_val = this->builder.CreateSub(
  4912. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4913. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0));
  4914. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4915. }
  4916. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4917. this->gen_sync(POST_SYNC, 103);
  4918. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4919. this->gen_trap_check(bb);
  4920. return std::make_tuple(CONT, bb);
  4921. }
  4922. /* instruction 104: SLL */
  4923. std::tuple<continuation_e, BasicBlock*> __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4924. bb->setName("SLL");
  4925. this->gen_sync(PRE_SYNC, 104);
  4926. uint8_t rd = ((bit_sub<7,5>(instr)));
  4927. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4928. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4929. if(this->disass_enabled){
  4930. /* generate console output when executing the command */
  4931. auto mnemonic = fmt::format(
  4932. "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"),
  4933. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
  4934. std::vector<Value*> args {
  4935. this->core_ptr,
  4936. this->gen_const(64, pc.val),
  4937. this->builder.CreateGlobalStringPtr(mnemonic),
  4938. };
  4939. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4940. }
  4941. Value* cur_pc_val = this->gen_const(64, pc.val);
  4942. pc=pc+4;
  4943. if(rd != 0){
  4944. Value* Xtmp0_val = this->builder.CreateShl(
  4945. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4946. this->builder.CreateAnd(
  4947. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0),
  4948. this->builder.CreateSub(
  4949. this->gen_const(64U, 64),
  4950. this->gen_const(64U, 1))));
  4951. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4952. }
  4953. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4954. this->gen_sync(POST_SYNC, 104);
  4955. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4956. this->gen_trap_check(bb);
  4957. return std::make_tuple(CONT, bb);
  4958. }
  4959. /* instruction 105: SLT */
  4960. std::tuple<continuation_e, BasicBlock*> __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  4961. bb->setName("SLT");
  4962. this->gen_sync(PRE_SYNC, 105);
  4963. uint8_t rd = ((bit_sub<7,5>(instr)));
  4964. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  4965. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  4966. if(this->disass_enabled){
  4967. /* generate console output when executing the command */
  4968. auto mnemonic = fmt::format(
  4969. "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"),
  4970. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
  4971. std::vector<Value*> args {
  4972. this->core_ptr,
  4973. this->gen_const(64, pc.val),
  4974. this->builder.CreateGlobalStringPtr(mnemonic),
  4975. };
  4976. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  4977. }
  4978. Value* cur_pc_val = this->gen_const(64, pc.val);
  4979. pc=pc+4;
  4980. if(rd != 0){
  4981. Value* Xtmp0_val = this->gen_choose(
  4982. this->builder.CreateICmp(
  4983. ICmpInst::ICMP_SLT,
  4984. this->gen_ext(
  4985. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  4986. 64, true),
  4987. this->gen_ext(
  4988. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0),
  4989. 64, true)),
  4990. this->gen_const(64U, 1),
  4991. this->gen_const(64U, 0),
  4992. 64);
  4993. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  4994. }
  4995. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  4996. this->gen_sync(POST_SYNC, 105);
  4997. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  4998. this->gen_trap_check(bb);
  4999. return std::make_tuple(CONT, bb);
  5000. }
  5001. /* instruction 106: SLTU */
  5002. std::tuple<continuation_e, BasicBlock*> __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5003. bb->setName("SLTU");
  5004. this->gen_sync(PRE_SYNC, 106);
  5005. uint8_t rd = ((bit_sub<7,5>(instr)));
  5006. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5007. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  5008. if(this->disass_enabled){
  5009. /* generate console output when executing the command */
  5010. auto mnemonic = fmt::format(
  5011. "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"),
  5012. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
  5013. std::vector<Value*> args {
  5014. this->core_ptr,
  5015. this->gen_const(64, pc.val),
  5016. this->builder.CreateGlobalStringPtr(mnemonic),
  5017. };
  5018. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5019. }
  5020. Value* cur_pc_val = this->gen_const(64, pc.val);
  5021. pc=pc+4;
  5022. if(rd != 0){
  5023. Value* Xtmp0_val = this->gen_choose(
  5024. this->builder.CreateICmp(
  5025. ICmpInst::ICMP_ULT,
  5026. this->gen_ext(
  5027. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  5028. 64,
  5029. false),
  5030. this->gen_ext(
  5031. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0),
  5032. 64,
  5033. false)),
  5034. this->gen_const(64U, 1),
  5035. this->gen_const(64U, 0),
  5036. 64);
  5037. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5038. }
  5039. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5040. this->gen_sync(POST_SYNC, 106);
  5041. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5042. this->gen_trap_check(bb);
  5043. return std::make_tuple(CONT, bb);
  5044. }
  5045. /* instruction 107: XOR */
  5046. std::tuple<continuation_e, BasicBlock*> __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5047. bb->setName("XOR");
  5048. this->gen_sync(PRE_SYNC, 107);
  5049. uint8_t rd = ((bit_sub<7,5>(instr)));
  5050. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5051. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  5052. if(this->disass_enabled){
  5053. /* generate console output when executing the command */
  5054. auto mnemonic = fmt::format(
  5055. "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"),
  5056. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
  5057. std::vector<Value*> args {
  5058. this->core_ptr,
  5059. this->gen_const(64, pc.val),
  5060. this->builder.CreateGlobalStringPtr(mnemonic),
  5061. };
  5062. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5063. }
  5064. Value* cur_pc_val = this->gen_const(64, pc.val);
  5065. pc=pc+4;
  5066. if(rd != 0){
  5067. Value* Xtmp0_val = this->builder.CreateXor(
  5068. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  5069. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0));
  5070. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5071. }
  5072. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5073. this->gen_sync(POST_SYNC, 107);
  5074. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5075. this->gen_trap_check(bb);
  5076. return std::make_tuple(CONT, bb);
  5077. }
  5078. /* instruction 108: SRL */
  5079. std::tuple<continuation_e, BasicBlock*> __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5080. bb->setName("SRL");
  5081. this->gen_sync(PRE_SYNC, 108);
  5082. uint8_t rd = ((bit_sub<7,5>(instr)));
  5083. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5084. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  5085. if(this->disass_enabled){
  5086. /* generate console output when executing the command */
  5087. auto mnemonic = fmt::format(
  5088. "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"),
  5089. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
  5090. std::vector<Value*> args {
  5091. this->core_ptr,
  5092. this->gen_const(64, pc.val),
  5093. this->builder.CreateGlobalStringPtr(mnemonic),
  5094. };
  5095. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5096. }
  5097. Value* cur_pc_val = this->gen_const(64, pc.val);
  5098. pc=pc+4;
  5099. if(rd != 0){
  5100. Value* Xtmp0_val = this->builder.CreateLShr(
  5101. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  5102. this->builder.CreateAnd(
  5103. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0),
  5104. this->builder.CreateSub(
  5105. this->gen_const(64U, 64),
  5106. this->gen_const(64U, 1))));
  5107. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5108. }
  5109. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5110. this->gen_sync(POST_SYNC, 108);
  5111. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5112. this->gen_trap_check(bb);
  5113. return std::make_tuple(CONT, bb);
  5114. }
  5115. /* instruction 109: SRA */
  5116. std::tuple<continuation_e, BasicBlock*> __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5117. bb->setName("SRA");
  5118. this->gen_sync(PRE_SYNC, 109);
  5119. uint8_t rd = ((bit_sub<7,5>(instr)));
  5120. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5121. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  5122. if(this->disass_enabled){
  5123. /* generate console output when executing the command */
  5124. auto mnemonic = fmt::format(
  5125. "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"),
  5126. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
  5127. std::vector<Value*> args {
  5128. this->core_ptr,
  5129. this->gen_const(64, pc.val),
  5130. this->builder.CreateGlobalStringPtr(mnemonic),
  5131. };
  5132. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5133. }
  5134. Value* cur_pc_val = this->gen_const(64, pc.val);
  5135. pc=pc+4;
  5136. if(rd != 0){
  5137. Value* Xtmp0_val = this->builder.CreateAShr(
  5138. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  5139. this->builder.CreateAnd(
  5140. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0),
  5141. this->builder.CreateSub(
  5142. this->gen_const(64U, 64),
  5143. this->gen_const(64U, 1))));
  5144. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5145. }
  5146. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5147. this->gen_sync(POST_SYNC, 109);
  5148. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5149. this->gen_trap_check(bb);
  5150. return std::make_tuple(CONT, bb);
  5151. }
  5152. /* instruction 110: OR */
  5153. std::tuple<continuation_e, BasicBlock*> __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5154. bb->setName("OR");
  5155. this->gen_sync(PRE_SYNC, 110);
  5156. uint8_t rd = ((bit_sub<7,5>(instr)));
  5157. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5158. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  5159. if(this->disass_enabled){
  5160. /* generate console output when executing the command */
  5161. auto mnemonic = fmt::format(
  5162. "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"),
  5163. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
  5164. std::vector<Value*> args {
  5165. this->core_ptr,
  5166. this->gen_const(64, pc.val),
  5167. this->builder.CreateGlobalStringPtr(mnemonic),
  5168. };
  5169. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5170. }
  5171. Value* cur_pc_val = this->gen_const(64, pc.val);
  5172. pc=pc+4;
  5173. if(rd != 0){
  5174. Value* Xtmp0_val = this->builder.CreateOr(
  5175. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  5176. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0));
  5177. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5178. }
  5179. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5180. this->gen_sync(POST_SYNC, 110);
  5181. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5182. this->gen_trap_check(bb);
  5183. return std::make_tuple(CONT, bb);
  5184. }
  5185. /* instruction 111: AND */
  5186. std::tuple<continuation_e, BasicBlock*> __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5187. bb->setName("AND");
  5188. this->gen_sync(PRE_SYNC, 111);
  5189. uint8_t rd = ((bit_sub<7,5>(instr)));
  5190. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5191. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  5192. if(this->disass_enabled){
  5193. /* generate console output when executing the command */
  5194. auto mnemonic = fmt::format(
  5195. "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"),
  5196. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
  5197. std::vector<Value*> args {
  5198. this->core_ptr,
  5199. this->gen_const(64, pc.val),
  5200. this->builder.CreateGlobalStringPtr(mnemonic),
  5201. };
  5202. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5203. }
  5204. Value* cur_pc_val = this->gen_const(64, pc.val);
  5205. pc=pc+4;
  5206. if(rd != 0){
  5207. Value* Xtmp0_val = this->builder.CreateAnd(
  5208. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  5209. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0));
  5210. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5211. }
  5212. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5213. this->gen_sync(POST_SYNC, 111);
  5214. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5215. this->gen_trap_check(bb);
  5216. return std::make_tuple(CONT, bb);
  5217. }
  5218. /* instruction 112: FENCE */
  5219. std::tuple<continuation_e, BasicBlock*> __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5220. bb->setName("FENCE");
  5221. this->gen_sync(PRE_SYNC, 112);
  5222. uint8_t rd = ((bit_sub<7,5>(instr)));
  5223. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5224. uint8_t succ = ((bit_sub<20,4>(instr)));
  5225. uint8_t pred = ((bit_sub<24,4>(instr)));
  5226. if(this->disass_enabled){
  5227. /* generate console output when executing the command */
  5228. std::vector<Value*> args {
  5229. this->core_ptr,
  5230. this->gen_const(64, pc.val),
  5231. this->builder.CreateGlobalStringPtr("fence"),
  5232. };
  5233. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5234. }
  5235. Value* cur_pc_val = this->gen_const(64, pc.val);
  5236. pc=pc+4;
  5237. Value* FENCEtmp0_val = this->builder.CreateOr(
  5238. this->builder.CreateShl(
  5239. this->gen_const(64U, pred),
  5240. this->gen_const(64U, 4)),
  5241. this->gen_const(64U, succ));
  5242. this->gen_write_mem(
  5243. traits<ARCH>::FENCE,
  5244. this->gen_const(64U, 0),
  5245. this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64)));
  5246. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5247. this->gen_sync(POST_SYNC, 112);
  5248. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5249. this->gen_trap_check(bb);
  5250. return std::make_tuple(CONT, bb);
  5251. }
  5252. /* instruction 113: FENCE_I */
  5253. std::tuple<continuation_e, BasicBlock*> __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5254. bb->setName("FENCE_I");
  5255. this->gen_sync(PRE_SYNC, 113);
  5256. uint8_t rd = ((bit_sub<7,5>(instr)));
  5257. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5258. uint16_t imm = ((bit_sub<20,12>(instr)));
  5259. if(this->disass_enabled){
  5260. /* generate console output when executing the command */
  5261. std::vector<Value*> args {
  5262. this->core_ptr,
  5263. this->gen_const(64, pc.val),
  5264. this->builder.CreateGlobalStringPtr("fence_i"),
  5265. };
  5266. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5267. }
  5268. Value* cur_pc_val = this->gen_const(64, pc.val);
  5269. pc=pc+4;
  5270. Value* FENCEtmp0_val = this->gen_const(64U, imm);
  5271. this->gen_write_mem(
  5272. traits<ARCH>::FENCE,
  5273. this->gen_const(64U, 1),
  5274. this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64)));
  5275. this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
  5276. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5277. this->gen_sync(POST_SYNC, 113);
  5278. this->gen_trap_check(this->leave_blk);
  5279. return std::make_tuple(FLUSH, nullptr);
  5280. }
  5281. /* instruction 114: ECALL */
  5282. std::tuple<continuation_e, BasicBlock*> __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5283. bb->setName("ECALL");
  5284. this->gen_sync(PRE_SYNC, 114);
  5285. if(this->disass_enabled){
  5286. /* generate console output when executing the command */
  5287. std::vector<Value*> args {
  5288. this->core_ptr,
  5289. this->gen_const(64, pc.val),
  5290. this->builder.CreateGlobalStringPtr("ecall"),
  5291. };
  5292. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5293. }
  5294. Value* cur_pc_val = this->gen_const(64, pc.val);
  5295. pc=pc+4;
  5296. this->gen_raise_trap(0, 11);
  5297. this->gen_sync(POST_SYNC, 114);
  5298. this->gen_trap_check(this->leave_blk);
  5299. return std::make_tuple(BRANCH, nullptr);
  5300. }
  5301. /* instruction 115: EBREAK */
  5302. std::tuple<continuation_e, BasicBlock*> __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5303. bb->setName("EBREAK");
  5304. this->gen_sync(PRE_SYNC, 115);
  5305. if(this->disass_enabled){
  5306. /* generate console output when executing the command */
  5307. std::vector<Value*> args {
  5308. this->core_ptr,
  5309. this->gen_const(64, pc.val),
  5310. this->builder.CreateGlobalStringPtr("ebreak"),
  5311. };
  5312. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5313. }
  5314. Value* cur_pc_val = this->gen_const(64, pc.val);
  5315. pc=pc+4;
  5316. this->gen_raise_trap(0, 3);
  5317. this->gen_sync(POST_SYNC, 115);
  5318. this->gen_trap_check(this->leave_blk);
  5319. return std::make_tuple(BRANCH, nullptr);
  5320. }
  5321. /* instruction 116: URET */
  5322. std::tuple<continuation_e, BasicBlock*> __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5323. bb->setName("URET");
  5324. this->gen_sync(PRE_SYNC, 116);
  5325. if(this->disass_enabled){
  5326. /* generate console output when executing the command */
  5327. std::vector<Value*> args {
  5328. this->core_ptr,
  5329. this->gen_const(64, pc.val),
  5330. this->builder.CreateGlobalStringPtr("uret"),
  5331. };
  5332. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5333. }
  5334. Value* cur_pc_val = this->gen_const(64, pc.val);
  5335. pc=pc+4;
  5336. this->gen_leave_trap(0);
  5337. this->gen_sync(POST_SYNC, 116);
  5338. this->gen_trap_check(this->leave_blk);
  5339. return std::make_tuple(BRANCH, nullptr);
  5340. }
  5341. /* instruction 117: SRET */
  5342. std::tuple<continuation_e, BasicBlock*> __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5343. bb->setName("SRET");
  5344. this->gen_sync(PRE_SYNC, 117);
  5345. if(this->disass_enabled){
  5346. /* generate console output when executing the command */
  5347. std::vector<Value*> args {
  5348. this->core_ptr,
  5349. this->gen_const(64, pc.val),
  5350. this->builder.CreateGlobalStringPtr("sret"),
  5351. };
  5352. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5353. }
  5354. Value* cur_pc_val = this->gen_const(64, pc.val);
  5355. pc=pc+4;
  5356. this->gen_leave_trap(1);
  5357. this->gen_sync(POST_SYNC, 117);
  5358. this->gen_trap_check(this->leave_blk);
  5359. return std::make_tuple(BRANCH, nullptr);
  5360. }
  5361. /* instruction 118: MRET */
  5362. std::tuple<continuation_e, BasicBlock*> __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5363. bb->setName("MRET");
  5364. this->gen_sync(PRE_SYNC, 118);
  5365. if(this->disass_enabled){
  5366. /* generate console output when executing the command */
  5367. std::vector<Value*> args {
  5368. this->core_ptr,
  5369. this->gen_const(64, pc.val),
  5370. this->builder.CreateGlobalStringPtr("mret"),
  5371. };
  5372. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5373. }
  5374. Value* cur_pc_val = this->gen_const(64, pc.val);
  5375. pc=pc+4;
  5376. this->gen_leave_trap(3);
  5377. this->gen_sync(POST_SYNC, 118);
  5378. this->gen_trap_check(this->leave_blk);
  5379. return std::make_tuple(BRANCH, nullptr);
  5380. }
  5381. /* instruction 119: WFI */
  5382. std::tuple<continuation_e, BasicBlock*> __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5383. bb->setName("WFI");
  5384. this->gen_sync(PRE_SYNC, 119);
  5385. if(this->disass_enabled){
  5386. /* generate console output when executing the command */
  5387. std::vector<Value*> args {
  5388. this->core_ptr,
  5389. this->gen_const(64, pc.val),
  5390. this->builder.CreateGlobalStringPtr("wfi"),
  5391. };
  5392. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5393. }
  5394. Value* cur_pc_val = this->gen_const(64, pc.val);
  5395. pc=pc+4;
  5396. this->gen_wait(1);
  5397. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5398. this->gen_sync(POST_SYNC, 119);
  5399. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5400. this->gen_trap_check(bb);
  5401. return std::make_tuple(CONT, bb);
  5402. }
  5403. /* instruction 120: SFENCE.VMA */
  5404. std::tuple<continuation_e, BasicBlock*> __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5405. bb->setName("SFENCE.VMA");
  5406. this->gen_sync(PRE_SYNC, 120);
  5407. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5408. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  5409. if(this->disass_enabled){
  5410. /* generate console output when executing the command */
  5411. std::vector<Value*> args {
  5412. this->core_ptr,
  5413. this->gen_const(64, pc.val),
  5414. this->builder.CreateGlobalStringPtr("sfence.vma"),
  5415. };
  5416. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5417. }
  5418. Value* cur_pc_val = this->gen_const(64, pc.val);
  5419. pc=pc+4;
  5420. Value* FENCEtmp0_val = this->gen_const(64U, rs1);
  5421. this->gen_write_mem(
  5422. traits<ARCH>::FENCE,
  5423. this->gen_const(64U, 2),
  5424. this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64)));
  5425. Value* FENCEtmp1_val = this->gen_const(64U, rs2);
  5426. this->gen_write_mem(
  5427. traits<ARCH>::FENCE,
  5428. this->gen_const(64U, 3),
  5429. this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(64)));
  5430. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5431. this->gen_sync(POST_SYNC, 120);
  5432. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5433. this->gen_trap_check(bb);
  5434. return std::make_tuple(CONT, bb);
  5435. }
  5436. /* instruction 121: CSRRW */
  5437. std::tuple<continuation_e, BasicBlock*> __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5438. bb->setName("CSRRW");
  5439. this->gen_sync(PRE_SYNC, 121);
  5440. uint8_t rd = ((bit_sub<7,5>(instr)));
  5441. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5442. uint16_t csr = ((bit_sub<20,12>(instr)));
  5443. if(this->disass_enabled){
  5444. /* generate console output when executing the command */
  5445. auto mnemonic = fmt::format(
  5446. "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"),
  5447. fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1)));
  5448. std::vector<Value*> args {
  5449. this->core_ptr,
  5450. this->gen_const(64, pc.val),
  5451. this->builder.CreateGlobalStringPtr(mnemonic),
  5452. };
  5453. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5454. }
  5455. Value* cur_pc_val = this->gen_const(64, pc.val);
  5456. pc=pc+4;
  5457. Value* rs_val_val = this->gen_reg_load(rs1 + traits<ARCH>::X0, 0);
  5458. if(rd != 0){
  5459. Value* csr_val_val = this->gen_read_mem(traits<ARCH>::CSR, this->gen_const(16U, csr), 64/8);
  5460. Value* CSRtmp0_val = rs_val_val;
  5461. this->gen_write_mem(
  5462. traits<ARCH>::CSR,
  5463. this->gen_const(16U, csr),
  5464. this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(64)));
  5465. Value* Xtmp1_val = csr_val_val;
  5466. this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5467. } else {
  5468. Value* CSRtmp2_val = rs_val_val;
  5469. this->gen_write_mem(
  5470. traits<ARCH>::CSR,
  5471. this->gen_const(16U, csr),
  5472. this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(64)));
  5473. }
  5474. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5475. this->gen_sync(POST_SYNC, 121);
  5476. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5477. this->gen_trap_check(bb);
  5478. return std::make_tuple(CONT, bb);
  5479. }
  5480. /* instruction 122: CSRRS */
  5481. std::tuple<continuation_e, BasicBlock*> __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5482. bb->setName("CSRRS");
  5483. this->gen_sync(PRE_SYNC, 122);
  5484. uint8_t rd = ((bit_sub<7,5>(instr)));
  5485. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5486. uint16_t csr = ((bit_sub<20,12>(instr)));
  5487. if(this->disass_enabled){
  5488. /* generate console output when executing the command */
  5489. auto mnemonic = fmt::format(
  5490. "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"),
  5491. fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1)));
  5492. std::vector<Value*> args {
  5493. this->core_ptr,
  5494. this->gen_const(64, pc.val),
  5495. this->builder.CreateGlobalStringPtr(mnemonic),
  5496. };
  5497. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5498. }
  5499. Value* cur_pc_val = this->gen_const(64, pc.val);
  5500. pc=pc+4;
  5501. Value* xrd_val = this->gen_read_mem(traits<ARCH>::CSR, this->gen_const(16U, csr), 64/8);
  5502. Value* xrs1_val = this->gen_reg_load(rs1 + traits<ARCH>::X0, 0);
  5503. if(rd != 0){
  5504. Value* Xtmp0_val = xrd_val;
  5505. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5506. }
  5507. if(rs1 != 0){
  5508. Value* CSRtmp1_val = this->builder.CreateOr(
  5509. xrd_val,
  5510. xrs1_val);
  5511. this->gen_write_mem(
  5512. traits<ARCH>::CSR,
  5513. this->gen_const(16U, csr),
  5514. this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64)));
  5515. }
  5516. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5517. this->gen_sync(POST_SYNC, 122);
  5518. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5519. this->gen_trap_check(bb);
  5520. return std::make_tuple(CONT, bb);
  5521. }
  5522. /* instruction 123: CSRRC */
  5523. std::tuple<continuation_e, BasicBlock*> __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5524. bb->setName("CSRRC");
  5525. this->gen_sync(PRE_SYNC, 123);
  5526. uint8_t rd = ((bit_sub<7,5>(instr)));
  5527. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5528. uint16_t csr = ((bit_sub<20,12>(instr)));
  5529. if(this->disass_enabled){
  5530. /* generate console output when executing the command */
  5531. auto mnemonic = fmt::format(
  5532. "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"),
  5533. fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1)));
  5534. std::vector<Value*> args {
  5535. this->core_ptr,
  5536. this->gen_const(64, pc.val),
  5537. this->builder.CreateGlobalStringPtr(mnemonic),
  5538. };
  5539. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5540. }
  5541. Value* cur_pc_val = this->gen_const(64, pc.val);
  5542. pc=pc+4;
  5543. Value* xrd_val = this->gen_read_mem(traits<ARCH>::CSR, this->gen_const(16U, csr), 64/8);
  5544. Value* xrs1_val = this->gen_reg_load(rs1 + traits<ARCH>::X0, 0);
  5545. if(rd != 0){
  5546. Value* Xtmp0_val = xrd_val;
  5547. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5548. }
  5549. if(rs1 != 0){
  5550. Value* CSRtmp1_val = this->builder.CreateAnd(
  5551. xrd_val,
  5552. this->builder.CreateNot(xrs1_val));
  5553. this->gen_write_mem(
  5554. traits<ARCH>::CSR,
  5555. this->gen_const(16U, csr),
  5556. this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64)));
  5557. }
  5558. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5559. this->gen_sync(POST_SYNC, 123);
  5560. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5561. this->gen_trap_check(bb);
  5562. return std::make_tuple(CONT, bb);
  5563. }
  5564. /* instruction 124: CSRRWI */
  5565. std::tuple<continuation_e, BasicBlock*> __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5566. bb->setName("CSRRWI");
  5567. this->gen_sync(PRE_SYNC, 124);
  5568. uint8_t rd = ((bit_sub<7,5>(instr)));
  5569. uint8_t zimm = ((bit_sub<15,5>(instr)));
  5570. uint16_t csr = ((bit_sub<20,12>(instr)));
  5571. if(this->disass_enabled){
  5572. /* generate console output when executing the command */
  5573. auto mnemonic = fmt::format(
  5574. "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"),
  5575. fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm));
  5576. std::vector<Value*> args {
  5577. this->core_ptr,
  5578. this->gen_const(64, pc.val),
  5579. this->builder.CreateGlobalStringPtr(mnemonic),
  5580. };
  5581. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5582. }
  5583. Value* cur_pc_val = this->gen_const(64, pc.val);
  5584. pc=pc+4;
  5585. if(rd != 0){
  5586. Value* Xtmp0_val = this->gen_read_mem(traits<ARCH>::CSR, this->gen_const(16U, csr), 64/8);
  5587. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5588. }
  5589. Value* CSRtmp1_val = this->gen_ext(
  5590. this->gen_const(64U, zimm),
  5591. 64,
  5592. false);
  5593. this->gen_write_mem(
  5594. traits<ARCH>::CSR,
  5595. this->gen_const(16U, csr),
  5596. this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64)));
  5597. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5598. this->gen_sync(POST_SYNC, 124);
  5599. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5600. this->gen_trap_check(bb);
  5601. return std::make_tuple(CONT, bb);
  5602. }
  5603. /* instruction 125: CSRRSI */
  5604. std::tuple<continuation_e, BasicBlock*> __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5605. bb->setName("CSRRSI");
  5606. this->gen_sync(PRE_SYNC, 125);
  5607. uint8_t rd = ((bit_sub<7,5>(instr)));
  5608. uint8_t zimm = ((bit_sub<15,5>(instr)));
  5609. uint16_t csr = ((bit_sub<20,12>(instr)));
  5610. if(this->disass_enabled){
  5611. /* generate console output when executing the command */
  5612. auto mnemonic = fmt::format(
  5613. "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"),
  5614. fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm));
  5615. std::vector<Value*> args {
  5616. this->core_ptr,
  5617. this->gen_const(64, pc.val),
  5618. this->builder.CreateGlobalStringPtr(mnemonic),
  5619. };
  5620. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5621. }
  5622. Value* cur_pc_val = this->gen_const(64, pc.val);
  5623. pc=pc+4;
  5624. Value* res_val = this->gen_read_mem(traits<ARCH>::CSR, this->gen_const(16U, csr), 64/8);
  5625. if(zimm != 0){
  5626. Value* CSRtmp0_val = this->builder.CreateOr(
  5627. res_val,
  5628. this->gen_ext(
  5629. this->gen_const(64U, zimm),
  5630. 64,
  5631. false));
  5632. this->gen_write_mem(
  5633. traits<ARCH>::CSR,
  5634. this->gen_const(16U, csr),
  5635. this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(64)));
  5636. }
  5637. if(rd != 0){
  5638. Value* Xtmp1_val = res_val;
  5639. this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5640. }
  5641. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5642. this->gen_sync(POST_SYNC, 125);
  5643. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5644. this->gen_trap_check(bb);
  5645. return std::make_tuple(CONT, bb);
  5646. }
  5647. /* instruction 126: CSRRCI */
  5648. std::tuple<continuation_e, BasicBlock*> __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5649. bb->setName("CSRRCI");
  5650. this->gen_sync(PRE_SYNC, 126);
  5651. uint8_t rd = ((bit_sub<7,5>(instr)));
  5652. uint8_t zimm = ((bit_sub<15,5>(instr)));
  5653. uint16_t csr = ((bit_sub<20,12>(instr)));
  5654. if(this->disass_enabled){
  5655. /* generate console output when executing the command */
  5656. auto mnemonic = fmt::format(
  5657. "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"),
  5658. fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm));
  5659. std::vector<Value*> args {
  5660. this->core_ptr,
  5661. this->gen_const(64, pc.val),
  5662. this->builder.CreateGlobalStringPtr(mnemonic),
  5663. };
  5664. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5665. }
  5666. Value* cur_pc_val = this->gen_const(64, pc.val);
  5667. pc=pc+4;
  5668. Value* res_val = this->gen_read_mem(traits<ARCH>::CSR, this->gen_const(16U, csr), 64/8);
  5669. if(rd != 0){
  5670. Value* Xtmp0_val = res_val;
  5671. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  5672. }
  5673. if(zimm != 0){
  5674. Value* CSRtmp1_val = this->builder.CreateAnd(
  5675. res_val,
  5676. this->builder.CreateNot(this->gen_ext(
  5677. this->gen_const(64U, zimm),
  5678. 64,
  5679. false)));
  5680. this->gen_write_mem(
  5681. traits<ARCH>::CSR,
  5682. this->gen_const(16U, csr),
  5683. this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64)));
  5684. }
  5685. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5686. this->gen_sync(POST_SYNC, 126);
  5687. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5688. this->gen_trap_check(bb);
  5689. return std::make_tuple(CONT, bb);
  5690. }
  5691. /* instruction 127: FLW */
  5692. std::tuple<continuation_e, BasicBlock*> __flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5693. bb->setName("FLW");
  5694. this->gen_sync(PRE_SYNC, 127);
  5695. uint8_t rd = ((bit_sub<7,5>(instr)));
  5696. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5697. int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
  5698. if(this->disass_enabled){
  5699. /* generate console output when executing the command */
  5700. auto mnemonic = fmt::format(
  5701. "{mnemonic:10} f{rd}, {imm}(x{rs1})", fmt::arg("mnemonic", "flw"),
  5702. fmt::arg("rd", rd), fmt::arg("imm", imm), fmt::arg("rs1", rs1));
  5703. std::vector<Value*> args {
  5704. this->core_ptr,
  5705. this->gen_const(64, pc.val),
  5706. this->builder.CreateGlobalStringPtr(mnemonic),
  5707. };
  5708. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5709. }
  5710. Value* cur_pc_val = this->gen_const(64, pc.val);
  5711. pc=pc+4;
  5712. Value* offs_val = this->builder.CreateAdd(
  5713. this->gen_ext(
  5714. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  5715. 64, true),
  5716. this->gen_const(64U, imm));
  5717. Value* res_val = this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8);
  5718. if(64 == 32){
  5719. Value* Ftmp0_val = res_val;
  5720. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  5721. } else {
  5722. uint64_t upper_val = - 1;
  5723. Value* Ftmp1_val = this->builder.CreateOr(
  5724. this->builder.CreateShl(
  5725. this->gen_const(64U, upper_val),
  5726. this->gen_const(64U, 32)),
  5727. this->gen_ext(
  5728. res_val,
  5729. 64,
  5730. false));
  5731. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  5732. }
  5733. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5734. this->gen_sync(POST_SYNC, 127);
  5735. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5736. this->gen_trap_check(bb);
  5737. return std::make_tuple(CONT, bb);
  5738. }
  5739. /* instruction 128: FSW */
  5740. std::tuple<continuation_e, BasicBlock*> __fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5741. bb->setName("FSW");
  5742. this->gen_sync(PRE_SYNC, 128);
  5743. int16_t imm = signextend<int16_t,12>((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5));
  5744. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5745. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  5746. if(this->disass_enabled){
  5747. /* generate console output when executing the command */
  5748. auto mnemonic = fmt::format(
  5749. "{mnemonic:10} f{rs2}, {imm}(x{rs1})", fmt::arg("mnemonic", "fsw"),
  5750. fmt::arg("rs2", rs2), fmt::arg("imm", imm), fmt::arg("rs1", rs1));
  5751. std::vector<Value*> args {
  5752. this->core_ptr,
  5753. this->gen_const(64, pc.val),
  5754. this->builder.CreateGlobalStringPtr(mnemonic),
  5755. };
  5756. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5757. }
  5758. Value* cur_pc_val = this->gen_const(64, pc.val);
  5759. pc=pc+4;
  5760. Value* offs_val = this->builder.CreateAdd(
  5761. this->gen_ext(
  5762. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  5763. 64, true),
  5764. this->gen_const(64U, imm));
  5765. Value* MEMtmp0_val = this->builder.CreateTrunc(
  5766. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  5767. this-> get_type(32)
  5768. );
  5769. this->gen_write_mem(
  5770. traits<ARCH>::MEM,
  5771. offs_val,
  5772. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32)));
  5773. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5774. this->gen_sync(POST_SYNC, 128);
  5775. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5776. this->gen_trap_check(bb);
  5777. return std::make_tuple(CONT, bb);
  5778. }
  5779. /* instruction 129: FMADD.S */
  5780. std::tuple<continuation_e, BasicBlock*> __fmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5781. bb->setName("FMADD.S");
  5782. this->gen_sync(PRE_SYNC, 129);
  5783. uint8_t rd = ((bit_sub<7,5>(instr)));
  5784. uint8_t rm = ((bit_sub<12,3>(instr)));
  5785. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5786. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  5787. uint8_t rs3 = ((bit_sub<27,5>(instr)));
  5788. if(this->disass_enabled){
  5789. /* generate console output when executing the command */
  5790. auto mnemonic = fmt::format(
  5791. "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmadd.s"),
  5792. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3));
  5793. std::vector<Value*> args {
  5794. this->core_ptr,
  5795. this->gen_const(64, pc.val),
  5796. this->builder.CreateGlobalStringPtr(mnemonic),
  5797. };
  5798. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5799. }
  5800. Value* cur_pc_val = this->gen_const(64, pc.val);
  5801. pc=pc+4;
  5802. if(64 == 32){
  5803. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector<Value*>{
  5804. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  5805. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  5806. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0),
  5807. this->gen_ext(
  5808. this->gen_const(64U, 0LL),
  5809. 32,
  5810. false),
  5811. this->gen_choose(
  5812. this->builder.CreateICmp(
  5813. ICmpInst::ICMP_ULT,
  5814. this->gen_const(8U, rm),
  5815. this->gen_const(8U, 7)),
  5816. this->gen_const(8U, rm),
  5817. this->builder.CreateTrunc(
  5818. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  5819. this-> get_type(8)
  5820. ),
  5821. 8)
  5822. });
  5823. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  5824. } else {
  5825. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  5826. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  5827. });
  5828. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  5829. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  5830. });
  5831. Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  5832. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0)
  5833. });
  5834. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector<Value*>{
  5835. frs1_val,
  5836. frs2_val,
  5837. frs3_val,
  5838. this->gen_ext(
  5839. this->gen_const(64U, 0LL),
  5840. 32,
  5841. false),
  5842. this->gen_choose(
  5843. this->builder.CreateICmp(
  5844. ICmpInst::ICMP_ULT,
  5845. this->gen_const(8U, rm),
  5846. this->gen_const(8U, 7)),
  5847. this->gen_const(8U, rm),
  5848. this->builder.CreateTrunc(
  5849. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  5850. this-> get_type(8)
  5851. ),
  5852. 8)
  5853. });
  5854. uint64_t upper_val = - 1;
  5855. Value* Ftmp1_val = this->builder.CreateOr(
  5856. this->builder.CreateShl(
  5857. this->gen_const(64U, upper_val),
  5858. this->gen_const(64U, 32)),
  5859. this->gen_ext(
  5860. res_val,
  5861. 64,
  5862. false));
  5863. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  5864. }
  5865. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  5866. });
  5867. Value* FCSR_val = this->builder.CreateAdd(
  5868. this->builder.CreateAnd(
  5869. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  5870. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  5871. flags_val);
  5872. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  5873. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5874. this->gen_sync(POST_SYNC, 129);
  5875. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5876. this->gen_trap_check(bb);
  5877. return std::make_tuple(CONT, bb);
  5878. }
  5879. /* instruction 130: FMSUB.S */
  5880. std::tuple<continuation_e, BasicBlock*> __fmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5881. bb->setName("FMSUB.S");
  5882. this->gen_sync(PRE_SYNC, 130);
  5883. uint8_t rd = ((bit_sub<7,5>(instr)));
  5884. uint8_t rm = ((bit_sub<12,3>(instr)));
  5885. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5886. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  5887. uint8_t rs3 = ((bit_sub<27,5>(instr)));
  5888. if(this->disass_enabled){
  5889. /* generate console output when executing the command */
  5890. auto mnemonic = fmt::format(
  5891. "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmsub.s"),
  5892. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3));
  5893. std::vector<Value*> args {
  5894. this->core_ptr,
  5895. this->gen_const(64, pc.val),
  5896. this->builder.CreateGlobalStringPtr(mnemonic),
  5897. };
  5898. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5899. }
  5900. Value* cur_pc_val = this->gen_const(64, pc.val);
  5901. pc=pc+4;
  5902. if(64 == 32){
  5903. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector<Value*>{
  5904. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  5905. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  5906. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0),
  5907. this->gen_ext(
  5908. this->gen_const(64U, 1LL),
  5909. 32,
  5910. false),
  5911. this->gen_choose(
  5912. this->builder.CreateICmp(
  5913. ICmpInst::ICMP_ULT,
  5914. this->gen_const(8U, rm),
  5915. this->gen_const(8U, 7)),
  5916. this->gen_const(8U, rm),
  5917. this->builder.CreateTrunc(
  5918. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  5919. this-> get_type(8)
  5920. ),
  5921. 8)
  5922. });
  5923. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  5924. } else {
  5925. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  5926. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  5927. });
  5928. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  5929. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  5930. });
  5931. Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  5932. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0)
  5933. });
  5934. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector<Value*>{
  5935. frs1_val,
  5936. frs2_val,
  5937. frs3_val,
  5938. this->gen_ext(
  5939. this->gen_const(64U, 1LL),
  5940. 32,
  5941. false),
  5942. this->gen_choose(
  5943. this->builder.CreateICmp(
  5944. ICmpInst::ICMP_ULT,
  5945. this->gen_const(8U, rm),
  5946. this->gen_const(8U, 7)),
  5947. this->gen_const(8U, rm),
  5948. this->builder.CreateTrunc(
  5949. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  5950. this-> get_type(8)
  5951. ),
  5952. 8)
  5953. });
  5954. uint64_t upper_val = - 1;
  5955. Value* Ftmp1_val = this->builder.CreateOr(
  5956. this->builder.CreateShl(
  5957. this->gen_const(64U, upper_val),
  5958. this->gen_const(64U, 32)),
  5959. this->gen_ext(
  5960. res_val,
  5961. 64,
  5962. false));
  5963. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  5964. }
  5965. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  5966. });
  5967. Value* FCSR_val = this->builder.CreateAdd(
  5968. this->builder.CreateAnd(
  5969. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  5970. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  5971. flags_val);
  5972. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  5973. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  5974. this->gen_sync(POST_SYNC, 130);
  5975. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  5976. this->gen_trap_check(bb);
  5977. return std::make_tuple(CONT, bb);
  5978. }
  5979. /* instruction 131: FNMADD.S */
  5980. std::tuple<continuation_e, BasicBlock*> __fnmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  5981. bb->setName("FNMADD.S");
  5982. this->gen_sync(PRE_SYNC, 131);
  5983. uint8_t rd = ((bit_sub<7,5>(instr)));
  5984. uint8_t rm = ((bit_sub<12,3>(instr)));
  5985. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  5986. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  5987. uint8_t rs3 = ((bit_sub<27,5>(instr)));
  5988. if(this->disass_enabled){
  5989. /* generate console output when executing the command */
  5990. auto mnemonic = fmt::format(
  5991. "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmadd.s"),
  5992. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3));
  5993. std::vector<Value*> args {
  5994. this->core_ptr,
  5995. this->gen_const(64, pc.val),
  5996. this->builder.CreateGlobalStringPtr(mnemonic),
  5997. };
  5998. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  5999. }
  6000. Value* cur_pc_val = this->gen_const(64, pc.val);
  6001. pc=pc+4;
  6002. if(64 == 32){
  6003. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector<Value*>{
  6004. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6005. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  6006. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0),
  6007. this->gen_ext(
  6008. this->gen_const(64U, 2LL),
  6009. 32,
  6010. false),
  6011. this->gen_choose(
  6012. this->builder.CreateICmp(
  6013. ICmpInst::ICMP_ULT,
  6014. this->gen_const(8U, rm),
  6015. this->gen_const(8U, 7)),
  6016. this->gen_const(8U, rm),
  6017. this->builder.CreateTrunc(
  6018. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6019. this-> get_type(8)
  6020. ),
  6021. 8)
  6022. });
  6023. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6024. } else {
  6025. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6026. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6027. });
  6028. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6029. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  6030. });
  6031. Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6032. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0)
  6033. });
  6034. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector<Value*>{
  6035. frs1_val,
  6036. frs2_val,
  6037. frs3_val,
  6038. this->gen_ext(
  6039. this->gen_const(64U, 2LL),
  6040. 32,
  6041. false),
  6042. this->gen_choose(
  6043. this->builder.CreateICmp(
  6044. ICmpInst::ICMP_ULT,
  6045. this->gen_const(8U, rm),
  6046. this->gen_const(8U, 7)),
  6047. this->gen_const(8U, rm),
  6048. this->builder.CreateTrunc(
  6049. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6050. this-> get_type(8)
  6051. ),
  6052. 8)
  6053. });
  6054. uint64_t upper_val = - 1;
  6055. Value* Ftmp1_val = this->builder.CreateOr(
  6056. this->builder.CreateShl(
  6057. this->gen_const(64U, upper_val),
  6058. this->gen_const(64U, 32)),
  6059. this->gen_ext(
  6060. res_val,
  6061. 64,
  6062. false));
  6063. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6064. }
  6065. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  6066. });
  6067. Value* FCSR_val = this->builder.CreateAdd(
  6068. this->builder.CreateAnd(
  6069. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6070. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  6071. flags_val);
  6072. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  6073. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6074. this->gen_sync(POST_SYNC, 131);
  6075. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6076. this->gen_trap_check(bb);
  6077. return std::make_tuple(CONT, bb);
  6078. }
  6079. /* instruction 132: FNMSUB.S */
  6080. std::tuple<continuation_e, BasicBlock*> __fnmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6081. bb->setName("FNMSUB.S");
  6082. this->gen_sync(PRE_SYNC, 132);
  6083. uint8_t rd = ((bit_sub<7,5>(instr)));
  6084. uint8_t rm = ((bit_sub<12,3>(instr)));
  6085. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6086. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  6087. uint8_t rs3 = ((bit_sub<27,5>(instr)));
  6088. if(this->disass_enabled){
  6089. /* generate console output when executing the command */
  6090. auto mnemonic = fmt::format(
  6091. "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmsub.s"),
  6092. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3));
  6093. std::vector<Value*> args {
  6094. this->core_ptr,
  6095. this->gen_const(64, pc.val),
  6096. this->builder.CreateGlobalStringPtr(mnemonic),
  6097. };
  6098. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6099. }
  6100. Value* cur_pc_val = this->gen_const(64, pc.val);
  6101. pc=pc+4;
  6102. if(64 == 32){
  6103. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector<Value*>{
  6104. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6105. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  6106. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0),
  6107. this->gen_ext(
  6108. this->gen_const(64U, 3LL),
  6109. 32,
  6110. false),
  6111. this->gen_choose(
  6112. this->builder.CreateICmp(
  6113. ICmpInst::ICMP_ULT,
  6114. this->gen_const(8U, rm),
  6115. this->gen_const(8U, 7)),
  6116. this->gen_const(8U, rm),
  6117. this->builder.CreateTrunc(
  6118. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6119. this-> get_type(8)
  6120. ),
  6121. 8)
  6122. });
  6123. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6124. } else {
  6125. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6126. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6127. });
  6128. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6129. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  6130. });
  6131. Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6132. this->gen_reg_load(rs3 + traits<ARCH>::F0, 0)
  6133. });
  6134. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector<Value*>{
  6135. frs1_val,
  6136. frs2_val,
  6137. frs3_val,
  6138. this->gen_ext(
  6139. this->gen_const(64U, 3LL),
  6140. 32,
  6141. false),
  6142. this->gen_choose(
  6143. this->builder.CreateICmp(
  6144. ICmpInst::ICMP_ULT,
  6145. this->gen_const(8U, rm),
  6146. this->gen_const(8U, 7)),
  6147. this->gen_const(8U, rm),
  6148. this->builder.CreateTrunc(
  6149. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6150. this-> get_type(8)
  6151. ),
  6152. 8)
  6153. });
  6154. uint64_t upper_val = - 1;
  6155. Value* Ftmp1_val = this->builder.CreateOr(
  6156. this->builder.CreateShl(
  6157. this->gen_const(64U, upper_val),
  6158. this->gen_const(64U, 32)),
  6159. this->gen_ext(
  6160. res_val,
  6161. 64,
  6162. false));
  6163. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6164. }
  6165. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  6166. });
  6167. Value* FCSR_val = this->builder.CreateAdd(
  6168. this->builder.CreateAnd(
  6169. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6170. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  6171. flags_val);
  6172. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  6173. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6174. this->gen_sync(POST_SYNC, 132);
  6175. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6176. this->gen_trap_check(bb);
  6177. return std::make_tuple(CONT, bb);
  6178. }
  6179. /* instruction 133: FADD.S */
  6180. std::tuple<continuation_e, BasicBlock*> __fadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6181. bb->setName("FADD.S");
  6182. this->gen_sync(PRE_SYNC, 133);
  6183. uint8_t rd = ((bit_sub<7,5>(instr)));
  6184. uint8_t rm = ((bit_sub<12,3>(instr)));
  6185. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6186. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  6187. if(this->disass_enabled){
  6188. /* generate console output when executing the command */
  6189. auto mnemonic = fmt::format(
  6190. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fadd.s"),
  6191. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  6192. std::vector<Value*> args {
  6193. this->core_ptr,
  6194. this->gen_const(64, pc.val),
  6195. this->builder.CreateGlobalStringPtr(mnemonic),
  6196. };
  6197. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6198. }
  6199. Value* cur_pc_val = this->gen_const(64, pc.val);
  6200. pc=pc+4;
  6201. if(64 == 32){
  6202. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fadd_s"), std::vector<Value*>{
  6203. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6204. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  6205. this->gen_choose(
  6206. this->builder.CreateICmp(
  6207. ICmpInst::ICMP_ULT,
  6208. this->gen_const(8U, rm),
  6209. this->gen_const(8U, 7)),
  6210. this->gen_const(8U, rm),
  6211. this->builder.CreateTrunc(
  6212. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6213. this-> get_type(8)
  6214. ),
  6215. 8)
  6216. });
  6217. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6218. } else {
  6219. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6220. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6221. });
  6222. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6223. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  6224. });
  6225. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fadd_s"), std::vector<Value*>{
  6226. frs1_val,
  6227. frs2_val,
  6228. this->gen_choose(
  6229. this->builder.CreateICmp(
  6230. ICmpInst::ICMP_ULT,
  6231. this->gen_const(8U, rm),
  6232. this->gen_const(8U, 7)),
  6233. this->gen_const(8U, rm),
  6234. this->builder.CreateTrunc(
  6235. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6236. this-> get_type(8)
  6237. ),
  6238. 8)
  6239. });
  6240. uint64_t upper_val = - 1;
  6241. Value* Ftmp1_val = this->builder.CreateOr(
  6242. this->builder.CreateShl(
  6243. this->gen_const(64U, upper_val),
  6244. this->gen_const(64U, 32)),
  6245. this->gen_ext(
  6246. res_val,
  6247. 64,
  6248. false));
  6249. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6250. }
  6251. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  6252. });
  6253. Value* FCSR_val = this->builder.CreateAdd(
  6254. this->builder.CreateAnd(
  6255. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6256. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  6257. flags_val);
  6258. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  6259. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6260. this->gen_sync(POST_SYNC, 133);
  6261. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6262. this->gen_trap_check(bb);
  6263. return std::make_tuple(CONT, bb);
  6264. }
  6265. /* instruction 134: FSUB.S */
  6266. std::tuple<continuation_e, BasicBlock*> __fsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6267. bb->setName("FSUB.S");
  6268. this->gen_sync(PRE_SYNC, 134);
  6269. uint8_t rd = ((bit_sub<7,5>(instr)));
  6270. uint8_t rm = ((bit_sub<12,3>(instr)));
  6271. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6272. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  6273. if(this->disass_enabled){
  6274. /* generate console output when executing the command */
  6275. auto mnemonic = fmt::format(
  6276. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsub.s"),
  6277. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  6278. std::vector<Value*> args {
  6279. this->core_ptr,
  6280. this->gen_const(64, pc.val),
  6281. this->builder.CreateGlobalStringPtr(mnemonic),
  6282. };
  6283. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6284. }
  6285. Value* cur_pc_val = this->gen_const(64, pc.val);
  6286. pc=pc+4;
  6287. if(64 == 32){
  6288. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsub_s"), std::vector<Value*>{
  6289. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6290. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  6291. this->gen_choose(
  6292. this->builder.CreateICmp(
  6293. ICmpInst::ICMP_ULT,
  6294. this->gen_const(8U, rm),
  6295. this->gen_const(8U, 7)),
  6296. this->gen_const(8U, rm),
  6297. this->builder.CreateTrunc(
  6298. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6299. this-> get_type(8)
  6300. ),
  6301. 8)
  6302. });
  6303. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6304. } else {
  6305. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6306. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6307. });
  6308. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6309. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  6310. });
  6311. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsub_s"), std::vector<Value*>{
  6312. frs1_val,
  6313. frs2_val,
  6314. this->gen_choose(
  6315. this->builder.CreateICmp(
  6316. ICmpInst::ICMP_ULT,
  6317. this->gen_const(8U, rm),
  6318. this->gen_const(8U, 7)),
  6319. this->gen_const(8U, rm),
  6320. this->builder.CreateTrunc(
  6321. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6322. this-> get_type(8)
  6323. ),
  6324. 8)
  6325. });
  6326. uint64_t upper_val = - 1;
  6327. Value* Ftmp1_val = this->builder.CreateOr(
  6328. this->builder.CreateShl(
  6329. this->gen_const(64U, upper_val),
  6330. this->gen_const(64U, 32)),
  6331. this->gen_ext(
  6332. res_val,
  6333. 64,
  6334. false));
  6335. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6336. }
  6337. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  6338. });
  6339. Value* FCSR_val = this->builder.CreateAdd(
  6340. this->builder.CreateAnd(
  6341. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6342. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  6343. flags_val);
  6344. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  6345. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6346. this->gen_sync(POST_SYNC, 134);
  6347. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6348. this->gen_trap_check(bb);
  6349. return std::make_tuple(CONT, bb);
  6350. }
  6351. /* instruction 135: FMUL.S */
  6352. std::tuple<continuation_e, BasicBlock*> __fmul_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6353. bb->setName("FMUL.S");
  6354. this->gen_sync(PRE_SYNC, 135);
  6355. uint8_t rd = ((bit_sub<7,5>(instr)));
  6356. uint8_t rm = ((bit_sub<12,3>(instr)));
  6357. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6358. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  6359. if(this->disass_enabled){
  6360. /* generate console output when executing the command */
  6361. auto mnemonic = fmt::format(
  6362. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmul.s"),
  6363. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  6364. std::vector<Value*> args {
  6365. this->core_ptr,
  6366. this->gen_const(64, pc.val),
  6367. this->builder.CreateGlobalStringPtr(mnemonic),
  6368. };
  6369. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6370. }
  6371. Value* cur_pc_val = this->gen_const(64, pc.val);
  6372. pc=pc+4;
  6373. if(64 == 32){
  6374. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmul_s"), std::vector<Value*>{
  6375. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6376. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  6377. this->gen_choose(
  6378. this->builder.CreateICmp(
  6379. ICmpInst::ICMP_ULT,
  6380. this->gen_const(8U, rm),
  6381. this->gen_const(8U, 7)),
  6382. this->gen_const(8U, rm),
  6383. this->builder.CreateTrunc(
  6384. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6385. this-> get_type(8)
  6386. ),
  6387. 8)
  6388. });
  6389. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6390. } else {
  6391. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6392. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6393. });
  6394. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6395. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  6396. });
  6397. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmul_s"), std::vector<Value*>{
  6398. frs1_val,
  6399. frs2_val,
  6400. this->gen_choose(
  6401. this->builder.CreateICmp(
  6402. ICmpInst::ICMP_ULT,
  6403. this->gen_const(8U, rm),
  6404. this->gen_const(8U, 7)),
  6405. this->gen_const(8U, rm),
  6406. this->builder.CreateTrunc(
  6407. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6408. this-> get_type(8)
  6409. ),
  6410. 8)
  6411. });
  6412. uint64_t upper_val = - 1;
  6413. Value* Ftmp1_val = this->builder.CreateOr(
  6414. this->builder.CreateShl(
  6415. this->gen_const(64U, upper_val),
  6416. this->gen_const(64U, 32)),
  6417. this->gen_ext(
  6418. res_val,
  6419. 64,
  6420. false));
  6421. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6422. }
  6423. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  6424. });
  6425. Value* FCSR_val = this->builder.CreateAdd(
  6426. this->builder.CreateAnd(
  6427. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6428. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  6429. flags_val);
  6430. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  6431. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6432. this->gen_sync(POST_SYNC, 135);
  6433. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6434. this->gen_trap_check(bb);
  6435. return std::make_tuple(CONT, bb);
  6436. }
  6437. /* instruction 136: FDIV.S */
  6438. std::tuple<continuation_e, BasicBlock*> __fdiv_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6439. bb->setName("FDIV.S");
  6440. this->gen_sync(PRE_SYNC, 136);
  6441. uint8_t rd = ((bit_sub<7,5>(instr)));
  6442. uint8_t rm = ((bit_sub<12,3>(instr)));
  6443. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6444. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  6445. if(this->disass_enabled){
  6446. /* generate console output when executing the command */
  6447. auto mnemonic = fmt::format(
  6448. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fdiv.s"),
  6449. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  6450. std::vector<Value*> args {
  6451. this->core_ptr,
  6452. this->gen_const(64, pc.val),
  6453. this->builder.CreateGlobalStringPtr(mnemonic),
  6454. };
  6455. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6456. }
  6457. Value* cur_pc_val = this->gen_const(64, pc.val);
  6458. pc=pc+4;
  6459. if(64 == 32){
  6460. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fdiv_s"), std::vector<Value*>{
  6461. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6462. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  6463. this->gen_choose(
  6464. this->builder.CreateICmp(
  6465. ICmpInst::ICMP_ULT,
  6466. this->gen_const(8U, rm),
  6467. this->gen_const(8U, 7)),
  6468. this->gen_const(8U, rm),
  6469. this->builder.CreateTrunc(
  6470. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6471. this-> get_type(8)
  6472. ),
  6473. 8)
  6474. });
  6475. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6476. } else {
  6477. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6478. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6479. });
  6480. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6481. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  6482. });
  6483. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fdiv_s"), std::vector<Value*>{
  6484. frs1_val,
  6485. frs2_val,
  6486. this->gen_choose(
  6487. this->builder.CreateICmp(
  6488. ICmpInst::ICMP_ULT,
  6489. this->gen_const(8U, rm),
  6490. this->gen_const(8U, 7)),
  6491. this->gen_const(8U, rm),
  6492. this->builder.CreateTrunc(
  6493. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6494. this-> get_type(8)
  6495. ),
  6496. 8)
  6497. });
  6498. uint64_t upper_val = - 1;
  6499. Value* Ftmp1_val = this->builder.CreateOr(
  6500. this->builder.CreateShl(
  6501. this->gen_const(64U, upper_val),
  6502. this->gen_const(64U, 32)),
  6503. this->gen_ext(
  6504. res_val,
  6505. 64,
  6506. false));
  6507. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6508. }
  6509. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  6510. });
  6511. Value* FCSR_val = this->builder.CreateAdd(
  6512. this->builder.CreateAnd(
  6513. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6514. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  6515. flags_val);
  6516. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  6517. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6518. this->gen_sync(POST_SYNC, 136);
  6519. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6520. this->gen_trap_check(bb);
  6521. return std::make_tuple(CONT, bb);
  6522. }
  6523. /* instruction 137: FSQRT.S */
  6524. std::tuple<continuation_e, BasicBlock*> __fsqrt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6525. bb->setName("FSQRT.S");
  6526. this->gen_sync(PRE_SYNC, 137);
  6527. uint8_t rd = ((bit_sub<7,5>(instr)));
  6528. uint8_t rm = ((bit_sub<12,3>(instr)));
  6529. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6530. if(this->disass_enabled){
  6531. /* generate console output when executing the command */
  6532. auto mnemonic = fmt::format(
  6533. "{mnemonic:10} f{rd}, f{rs1}", fmt::arg("mnemonic", "fsqrt.s"),
  6534. fmt::arg("rd", rd), fmt::arg("rs1", rs1));
  6535. std::vector<Value*> args {
  6536. this->core_ptr,
  6537. this->gen_const(64, pc.val),
  6538. this->builder.CreateGlobalStringPtr(mnemonic),
  6539. };
  6540. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6541. }
  6542. Value* cur_pc_val = this->gen_const(64, pc.val);
  6543. pc=pc+4;
  6544. if(64 == 32){
  6545. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_s"), std::vector<Value*>{
  6546. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6547. this->gen_choose(
  6548. this->builder.CreateICmp(
  6549. ICmpInst::ICMP_ULT,
  6550. this->gen_const(8U, rm),
  6551. this->gen_const(8U, 7)),
  6552. this->gen_const(8U, rm),
  6553. this->builder.CreateTrunc(
  6554. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6555. this-> get_type(8)
  6556. ),
  6557. 8)
  6558. });
  6559. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6560. } else {
  6561. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6562. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6563. });
  6564. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_s"), std::vector<Value*>{
  6565. frs1_val,
  6566. this->gen_choose(
  6567. this->builder.CreateICmp(
  6568. ICmpInst::ICMP_ULT,
  6569. this->gen_const(8U, rm),
  6570. this->gen_const(8U, 7)),
  6571. this->gen_const(8U, rm),
  6572. this->builder.CreateTrunc(
  6573. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6574. this-> get_type(8)
  6575. ),
  6576. 8)
  6577. });
  6578. uint64_t upper_val = - 1;
  6579. Value* Ftmp1_val = this->builder.CreateOr(
  6580. this->builder.CreateShl(
  6581. this->gen_const(64U, upper_val),
  6582. this->gen_const(64U, 32)),
  6583. this->gen_ext(
  6584. res_val,
  6585. 64,
  6586. false));
  6587. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6588. }
  6589. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  6590. });
  6591. Value* FCSR_val = this->builder.CreateAdd(
  6592. this->builder.CreateAnd(
  6593. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6594. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  6595. flags_val);
  6596. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  6597. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6598. this->gen_sync(POST_SYNC, 137);
  6599. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6600. this->gen_trap_check(bb);
  6601. return std::make_tuple(CONT, bb);
  6602. }
  6603. /* instruction 138: FSGNJ.S */
  6604. std::tuple<continuation_e, BasicBlock*> __fsgnj_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6605. bb->setName("FSGNJ.S");
  6606. this->gen_sync(PRE_SYNC, 138);
  6607. uint8_t rd = ((bit_sub<7,5>(instr)));
  6608. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6609. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  6610. if(this->disass_enabled){
  6611. /* generate console output when executing the command */
  6612. auto mnemonic = fmt::format(
  6613. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnj.s"),
  6614. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  6615. std::vector<Value*> args {
  6616. this->core_ptr,
  6617. this->gen_const(64, pc.val),
  6618. this->builder.CreateGlobalStringPtr(mnemonic),
  6619. };
  6620. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6621. }
  6622. Value* cur_pc_val = this->gen_const(64, pc.val);
  6623. pc=pc+4;
  6624. if(64 == 32){
  6625. Value* Ftmp0_val = this->builder.CreateOr(
  6626. this->builder.CreateAnd(
  6627. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6628. this->gen_const(64U, 0x7fffffff)),
  6629. this->builder.CreateAnd(
  6630. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  6631. this->gen_const(64U, 0x80000000)));
  6632. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6633. } else {
  6634. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6635. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6636. });
  6637. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6638. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  6639. });
  6640. Value* res_val = this->builder.CreateOr(
  6641. this->builder.CreateAnd(
  6642. frs1_val,
  6643. this->gen_const(32U, 0x7fffffff)),
  6644. this->builder.CreateAnd(
  6645. frs2_val,
  6646. this->gen_const(32U, 0x80000000)));
  6647. uint64_t upper_val = - 1;
  6648. Value* Ftmp1_val = this->builder.CreateOr(
  6649. this->builder.CreateShl(
  6650. this->gen_const(64U, upper_val),
  6651. this->gen_const(64U, 32)),
  6652. this->gen_ext(
  6653. res_val,
  6654. 64,
  6655. false));
  6656. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6657. }
  6658. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6659. this->gen_sync(POST_SYNC, 138);
  6660. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6661. this->gen_trap_check(bb);
  6662. return std::make_tuple(CONT, bb);
  6663. }
  6664. /* instruction 139: FSGNJN.S */
  6665. std::tuple<continuation_e, BasicBlock*> __fsgnjn_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6666. bb->setName("FSGNJN.S");
  6667. this->gen_sync(PRE_SYNC, 139);
  6668. uint8_t rd = ((bit_sub<7,5>(instr)));
  6669. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6670. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  6671. if(this->disass_enabled){
  6672. /* generate console output when executing the command */
  6673. auto mnemonic = fmt::format(
  6674. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjn.s"),
  6675. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  6676. std::vector<Value*> args {
  6677. this->core_ptr,
  6678. this->gen_const(64, pc.val),
  6679. this->builder.CreateGlobalStringPtr(mnemonic),
  6680. };
  6681. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6682. }
  6683. Value* cur_pc_val = this->gen_const(64, pc.val);
  6684. pc=pc+4;
  6685. if(64 == 32){
  6686. Value* Ftmp0_val = this->builder.CreateOr(
  6687. this->builder.CreateAnd(
  6688. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6689. this->gen_const(64U, 0x7fffffff)),
  6690. this->builder.CreateAnd(
  6691. this->builder.CreateNot(this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)),
  6692. this->gen_const(64U, 0x80000000)));
  6693. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6694. } else {
  6695. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6696. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6697. });
  6698. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6699. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  6700. });
  6701. Value* res_val = this->builder.CreateOr(
  6702. this->builder.CreateAnd(
  6703. frs1_val,
  6704. this->gen_const(32U, 0x7fffffff)),
  6705. this->builder.CreateAnd(
  6706. this->builder.CreateNot(frs2_val),
  6707. this->gen_const(32U, 0x80000000)));
  6708. uint64_t upper_val = - 1;
  6709. Value* Ftmp1_val = this->builder.CreateOr(
  6710. this->builder.CreateShl(
  6711. this->gen_const(64U, upper_val),
  6712. this->gen_const(64U, 32)),
  6713. this->gen_ext(
  6714. res_val,
  6715. 64,
  6716. false));
  6717. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6718. }
  6719. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6720. this->gen_sync(POST_SYNC, 139);
  6721. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6722. this->gen_trap_check(bb);
  6723. return std::make_tuple(CONT, bb);
  6724. }
  6725. /* instruction 140: FSGNJX.S */
  6726. std::tuple<continuation_e, BasicBlock*> __fsgnjx_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6727. bb->setName("FSGNJX.S");
  6728. this->gen_sync(PRE_SYNC, 140);
  6729. uint8_t rd = ((bit_sub<7,5>(instr)));
  6730. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6731. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  6732. if(this->disass_enabled){
  6733. /* generate console output when executing the command */
  6734. auto mnemonic = fmt::format(
  6735. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjx.s"),
  6736. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  6737. std::vector<Value*> args {
  6738. this->core_ptr,
  6739. this->gen_const(64, pc.val),
  6740. this->builder.CreateGlobalStringPtr(mnemonic),
  6741. };
  6742. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6743. }
  6744. Value* cur_pc_val = this->gen_const(64, pc.val);
  6745. pc=pc+4;
  6746. if(64 == 32){
  6747. Value* Ftmp0_val = this->builder.CreateXor(
  6748. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6749. this->builder.CreateAnd(
  6750. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  6751. this->gen_const(64U, 0x80000000)));
  6752. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6753. } else {
  6754. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6755. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6756. });
  6757. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6758. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  6759. });
  6760. Value* res_val = this->builder.CreateXor(
  6761. frs1_val,
  6762. this->builder.CreateAnd(
  6763. frs2_val,
  6764. this->gen_const(32U, 0x80000000)));
  6765. uint64_t upper_val = - 1;
  6766. Value* Ftmp1_val = this->builder.CreateOr(
  6767. this->builder.CreateShl(
  6768. this->gen_const(64U, upper_val),
  6769. this->gen_const(64U, 32)),
  6770. this->gen_ext(
  6771. res_val,
  6772. 64,
  6773. false));
  6774. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6775. }
  6776. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6777. this->gen_sync(POST_SYNC, 140);
  6778. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6779. this->gen_trap_check(bb);
  6780. return std::make_tuple(CONT, bb);
  6781. }
  6782. /* instruction 141: FMIN.S */
  6783. std::tuple<continuation_e, BasicBlock*> __fmin_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6784. bb->setName("FMIN.S");
  6785. this->gen_sync(PRE_SYNC, 141);
  6786. uint8_t rd = ((bit_sub<7,5>(instr)));
  6787. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6788. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  6789. if(this->disass_enabled){
  6790. /* generate console output when executing the command */
  6791. auto mnemonic = fmt::format(
  6792. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmin.s"),
  6793. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  6794. std::vector<Value*> args {
  6795. this->core_ptr,
  6796. this->gen_const(64, pc.val),
  6797. this->builder.CreateGlobalStringPtr(mnemonic),
  6798. };
  6799. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6800. }
  6801. Value* cur_pc_val = this->gen_const(64, pc.val);
  6802. pc=pc+4;
  6803. if(64 == 32){
  6804. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector<Value*>{
  6805. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6806. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  6807. this->gen_ext(
  6808. this->gen_const(64U, 0LL),
  6809. 32,
  6810. false)
  6811. });
  6812. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6813. } else {
  6814. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6815. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6816. });
  6817. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6818. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  6819. });
  6820. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector<Value*>{
  6821. frs1_val,
  6822. frs2_val,
  6823. this->gen_ext(
  6824. this->gen_const(64U, 0LL),
  6825. 32,
  6826. false)
  6827. });
  6828. uint64_t upper_val = - 1;
  6829. Value* Ftmp1_val = this->builder.CreateOr(
  6830. this->builder.CreateShl(
  6831. this->gen_const(64U, upper_val),
  6832. this->gen_const(64U, 32)),
  6833. this->gen_ext(
  6834. res_val,
  6835. 64,
  6836. false));
  6837. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6838. }
  6839. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  6840. });
  6841. Value* FCSR_val = this->builder.CreateAdd(
  6842. this->builder.CreateAnd(
  6843. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6844. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  6845. flags_val);
  6846. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  6847. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6848. this->gen_sync(POST_SYNC, 141);
  6849. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6850. this->gen_trap_check(bb);
  6851. return std::make_tuple(CONT, bb);
  6852. }
  6853. /* instruction 142: FMAX.S */
  6854. std::tuple<continuation_e, BasicBlock*> __fmax_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6855. bb->setName("FMAX.S");
  6856. this->gen_sync(PRE_SYNC, 142);
  6857. uint8_t rd = ((bit_sub<7,5>(instr)));
  6858. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6859. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  6860. if(this->disass_enabled){
  6861. /* generate console output when executing the command */
  6862. auto mnemonic = fmt::format(
  6863. "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmax.s"),
  6864. fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  6865. std::vector<Value*> args {
  6866. this->core_ptr,
  6867. this->gen_const(64, pc.val),
  6868. this->builder.CreateGlobalStringPtr(mnemonic),
  6869. };
  6870. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6871. }
  6872. Value* cur_pc_val = this->gen_const(64, pc.val);
  6873. pc=pc+4;
  6874. if(64 == 32){
  6875. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector<Value*>{
  6876. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6877. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  6878. this->gen_ext(
  6879. this->gen_const(64U, 1LL),
  6880. 32,
  6881. false)
  6882. });
  6883. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6884. } else {
  6885. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6886. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6887. });
  6888. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6889. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  6890. });
  6891. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector<Value*>{
  6892. frs1_val,
  6893. frs2_val,
  6894. this->gen_ext(
  6895. this->gen_const(64U, 1LL),
  6896. 32,
  6897. false)
  6898. });
  6899. uint64_t upper_val = - 1;
  6900. Value* Ftmp1_val = this->builder.CreateOr(
  6901. this->builder.CreateShl(
  6902. this->gen_const(64U, upper_val),
  6903. this->gen_const(64U, 32)),
  6904. this->gen_ext(
  6905. res_val,
  6906. 64,
  6907. false));
  6908. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  6909. }
  6910. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  6911. });
  6912. Value* FCSR_val = this->builder.CreateAdd(
  6913. this->builder.CreateAnd(
  6914. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6915. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  6916. flags_val);
  6917. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  6918. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6919. this->gen_sync(POST_SYNC, 142);
  6920. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6921. this->gen_trap_check(bb);
  6922. return std::make_tuple(CONT, bb);
  6923. }
  6924. /* instruction 143: FCVT.W.S */
  6925. std::tuple<continuation_e, BasicBlock*> __fcvt_w_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6926. bb->setName("FCVT.W.S");
  6927. this->gen_sync(PRE_SYNC, 143);
  6928. uint8_t rd = ((bit_sub<7,5>(instr)));
  6929. uint8_t rm = ((bit_sub<12,3>(instr)));
  6930. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6931. if(this->disass_enabled){
  6932. /* generate console output when executing the command */
  6933. auto mnemonic = fmt::format(
  6934. "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.w.s"),
  6935. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1));
  6936. std::vector<Value*> args {
  6937. this->core_ptr,
  6938. this->gen_const(64, pc.val),
  6939. this->builder.CreateGlobalStringPtr(mnemonic),
  6940. };
  6941. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  6942. }
  6943. Value* cur_pc_val = this->gen_const(64, pc.val);
  6944. pc=pc+4;
  6945. if(64 == 32){
  6946. Value* Xtmp0_val = this->gen_ext(
  6947. this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector<Value*>{
  6948. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  6949. this->gen_ext(
  6950. this->gen_const(64U, 0LL),
  6951. 32,
  6952. false),
  6953. this->gen_const(8U, rm)
  6954. }),
  6955. 64,
  6956. true);
  6957. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  6958. } else {
  6959. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  6960. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  6961. });
  6962. Value* Xtmp1_val = this->gen_ext(
  6963. this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector<Value*>{
  6964. frs1_val,
  6965. this->gen_ext(
  6966. this->gen_const(64U, 0LL),
  6967. 32,
  6968. false),
  6969. this->gen_const(8U, rm)
  6970. }),
  6971. 64,
  6972. true);
  6973. this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  6974. }
  6975. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  6976. });
  6977. Value* FCSR_val = this->builder.CreateAdd(
  6978. this->builder.CreateAnd(
  6979. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  6980. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  6981. flags_val);
  6982. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  6983. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  6984. this->gen_sync(POST_SYNC, 143);
  6985. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  6986. this->gen_trap_check(bb);
  6987. return std::make_tuple(CONT, bb);
  6988. }
  6989. /* instruction 144: FCVT.WU.S */
  6990. std::tuple<continuation_e, BasicBlock*> __fcvt_wu_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  6991. bb->setName("FCVT.WU.S");
  6992. this->gen_sync(PRE_SYNC, 144);
  6993. uint8_t rd = ((bit_sub<7,5>(instr)));
  6994. uint8_t rm = ((bit_sub<12,3>(instr)));
  6995. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  6996. if(this->disass_enabled){
  6997. /* generate console output when executing the command */
  6998. auto mnemonic = fmt::format(
  6999. "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.wu.s"),
  7000. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1));
  7001. std::vector<Value*> args {
  7002. this->core_ptr,
  7003. this->gen_const(64, pc.val),
  7004. this->builder.CreateGlobalStringPtr(mnemonic),
  7005. };
  7006. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7007. }
  7008. Value* cur_pc_val = this->gen_const(64, pc.val);
  7009. pc=pc+4;
  7010. if(64 == 32){
  7011. Value* Xtmp0_val = this->gen_ext(
  7012. this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector<Value*>{
  7013. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  7014. this->gen_ext(
  7015. this->gen_const(64U, 1LL),
  7016. 32,
  7017. false),
  7018. this->gen_const(8U, rm)
  7019. }),
  7020. 64,
  7021. true);
  7022. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7023. } else {
  7024. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  7025. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  7026. });
  7027. Value* Xtmp1_val = this->gen_ext(
  7028. this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector<Value*>{
  7029. frs1_val,
  7030. this->gen_ext(
  7031. this->gen_const(64U, 1LL),
  7032. 32,
  7033. false),
  7034. this->gen_const(8U, rm)
  7035. }),
  7036. 64,
  7037. true);
  7038. this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7039. }
  7040. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  7041. });
  7042. Value* FCSR_val = this->builder.CreateAdd(
  7043. this->builder.CreateAnd(
  7044. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  7045. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  7046. flags_val);
  7047. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  7048. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7049. this->gen_sync(POST_SYNC, 144);
  7050. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7051. this->gen_trap_check(bb);
  7052. return std::make_tuple(CONT, bb);
  7053. }
  7054. /* instruction 145: FEQ.S */
  7055. std::tuple<continuation_e, BasicBlock*> __feq_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7056. bb->setName("FEQ.S");
  7057. this->gen_sync(PRE_SYNC, 145);
  7058. uint8_t rd = ((bit_sub<7,5>(instr)));
  7059. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7060. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  7061. if(this->disass_enabled){
  7062. /* generate console output when executing the command */
  7063. auto mnemonic = fmt::format(
  7064. "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "feq.s"),
  7065. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  7066. std::vector<Value*> args {
  7067. this->core_ptr,
  7068. this->gen_const(64, pc.val),
  7069. this->builder.CreateGlobalStringPtr(mnemonic),
  7070. };
  7071. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7072. }
  7073. Value* cur_pc_val = this->gen_const(64, pc.val);
  7074. pc=pc+4;
  7075. if(64 == 32){
  7076. Value* Xtmp0_val = this->gen_ext(
  7077. this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector<Value*>{
  7078. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  7079. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  7080. this->gen_ext(
  7081. this->gen_const(64U, 0LL),
  7082. 32,
  7083. false)
  7084. }),
  7085. 64,
  7086. false);
  7087. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7088. } else {
  7089. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  7090. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  7091. });
  7092. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  7093. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  7094. });
  7095. Value* Xtmp1_val = this->gen_ext(
  7096. this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector<Value*>{
  7097. frs1_val,
  7098. frs2_val,
  7099. this->gen_ext(
  7100. this->gen_const(64U, 0LL),
  7101. 32,
  7102. false)
  7103. }),
  7104. 64,
  7105. false);
  7106. this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7107. }
  7108. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  7109. });
  7110. Value* FCSR_val = this->builder.CreateAdd(
  7111. this->builder.CreateAnd(
  7112. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  7113. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  7114. flags_val);
  7115. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  7116. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7117. this->gen_sync(POST_SYNC, 145);
  7118. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7119. this->gen_trap_check(bb);
  7120. return std::make_tuple(CONT, bb);
  7121. }
  7122. /* instruction 146: FLT.S */
  7123. std::tuple<continuation_e, BasicBlock*> __flt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7124. bb->setName("FLT.S");
  7125. this->gen_sync(PRE_SYNC, 146);
  7126. uint8_t rd = ((bit_sub<7,5>(instr)));
  7127. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7128. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  7129. if(this->disass_enabled){
  7130. /* generate console output when executing the command */
  7131. auto mnemonic = fmt::format(
  7132. "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "flt.s"),
  7133. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  7134. std::vector<Value*> args {
  7135. this->core_ptr,
  7136. this->gen_const(64, pc.val),
  7137. this->builder.CreateGlobalStringPtr(mnemonic),
  7138. };
  7139. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7140. }
  7141. Value* cur_pc_val = this->gen_const(64, pc.val);
  7142. pc=pc+4;
  7143. if(64 == 32){
  7144. Value* Xtmp0_val = this->gen_ext(
  7145. this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector<Value*>{
  7146. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  7147. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  7148. this->gen_ext(
  7149. this->gen_const(64U, 2LL),
  7150. 32,
  7151. false)
  7152. }),
  7153. 64,
  7154. false);
  7155. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7156. } else {
  7157. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  7158. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  7159. });
  7160. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  7161. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  7162. });
  7163. Value* Xtmp1_val = this->gen_ext(
  7164. this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector<Value*>{
  7165. frs1_val,
  7166. frs2_val,
  7167. this->gen_ext(
  7168. this->gen_const(64U, 2LL),
  7169. 32,
  7170. false)
  7171. }),
  7172. 64,
  7173. false);
  7174. this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7175. }
  7176. Value* Xtmp2_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector<Value*>{
  7177. this->builder.CreateTrunc(
  7178. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  7179. this-> get_type(32)
  7180. ),
  7181. this->builder.CreateTrunc(
  7182. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  7183. this-> get_type(32)
  7184. ),
  7185. this->gen_ext(
  7186. this->gen_const(64U, 2LL),
  7187. 32,
  7188. false)
  7189. });
  7190. this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7191. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  7192. });
  7193. Value* FCSR_val = this->builder.CreateAdd(
  7194. this->builder.CreateAnd(
  7195. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  7196. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  7197. flags_val);
  7198. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  7199. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7200. this->gen_sync(POST_SYNC, 146);
  7201. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7202. this->gen_trap_check(bb);
  7203. return std::make_tuple(CONT, bb);
  7204. }
  7205. /* instruction 147: FLE.S */
  7206. std::tuple<continuation_e, BasicBlock*> __fle_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7207. bb->setName("FLE.S");
  7208. this->gen_sync(PRE_SYNC, 147);
  7209. uint8_t rd = ((bit_sub<7,5>(instr)));
  7210. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7211. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  7212. if(this->disass_enabled){
  7213. /* generate console output when executing the command */
  7214. auto mnemonic = fmt::format(
  7215. "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fle.s"),
  7216. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2));
  7217. std::vector<Value*> args {
  7218. this->core_ptr,
  7219. this->gen_const(64, pc.val),
  7220. this->builder.CreateGlobalStringPtr(mnemonic),
  7221. };
  7222. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7223. }
  7224. Value* cur_pc_val = this->gen_const(64, pc.val);
  7225. pc=pc+4;
  7226. if(64 == 32){
  7227. Value* Xtmp0_val = this->gen_ext(
  7228. this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector<Value*>{
  7229. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  7230. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0),
  7231. this->gen_ext(
  7232. this->gen_const(64U, 1LL),
  7233. 32,
  7234. false)
  7235. }),
  7236. 64,
  7237. false);
  7238. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7239. } else {
  7240. Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  7241. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  7242. });
  7243. Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  7244. this->gen_reg_load(rs2 + traits<ARCH>::F0, 0)
  7245. });
  7246. Value* Xtmp1_val = this->gen_ext(
  7247. this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector<Value*>{
  7248. frs1_val,
  7249. frs2_val,
  7250. this->gen_ext(
  7251. this->gen_const(64U, 1LL),
  7252. 32,
  7253. false)
  7254. }),
  7255. 64,
  7256. false);
  7257. this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7258. }
  7259. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  7260. });
  7261. Value* FCSR_val = this->builder.CreateAdd(
  7262. this->builder.CreateAnd(
  7263. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  7264. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  7265. flags_val);
  7266. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  7267. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7268. this->gen_sync(POST_SYNC, 147);
  7269. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7270. this->gen_trap_check(bb);
  7271. return std::make_tuple(CONT, bb);
  7272. }
  7273. /* instruction 148: FCLASS.S */
  7274. std::tuple<continuation_e, BasicBlock*> __fclass_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7275. bb->setName("FCLASS.S");
  7276. this->gen_sync(PRE_SYNC, 148);
  7277. uint8_t rd = ((bit_sub<7,5>(instr)));
  7278. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7279. if(this->disass_enabled){
  7280. /* generate console output when executing the command */
  7281. auto mnemonic = fmt::format(
  7282. "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fclass.s"),
  7283. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1));
  7284. std::vector<Value*> args {
  7285. this->core_ptr,
  7286. this->gen_const(64, pc.val),
  7287. this->builder.CreateGlobalStringPtr(mnemonic),
  7288. };
  7289. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7290. }
  7291. Value* cur_pc_val = this->gen_const(64, pc.val);
  7292. pc=pc+4;
  7293. Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_s"), std::vector<Value*>{
  7294. this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  7295. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  7296. })
  7297. });
  7298. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7299. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7300. this->gen_sync(POST_SYNC, 148);
  7301. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7302. this->gen_trap_check(bb);
  7303. return std::make_tuple(CONT, bb);
  7304. }
  7305. /* instruction 149: FCVT.S.W */
  7306. std::tuple<continuation_e, BasicBlock*> __fcvt_s_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7307. bb->setName("FCVT.S.W");
  7308. this->gen_sync(PRE_SYNC, 149);
  7309. uint8_t rd = ((bit_sub<7,5>(instr)));
  7310. uint8_t rm = ((bit_sub<12,3>(instr)));
  7311. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7312. if(this->disass_enabled){
  7313. /* generate console output when executing the command */
  7314. auto mnemonic = fmt::format(
  7315. "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.s.w"),
  7316. fmt::arg("rd", rd), fmt::arg("rs1", name(rs1)));
  7317. std::vector<Value*> args {
  7318. this->core_ptr,
  7319. this->gen_const(64, pc.val),
  7320. this->builder.CreateGlobalStringPtr(mnemonic),
  7321. };
  7322. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7323. }
  7324. Value* cur_pc_val = this->gen_const(64, pc.val);
  7325. pc=pc+4;
  7326. if(64 == 32){
  7327. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector<Value*>{
  7328. this->builder.CreateTrunc(
  7329. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  7330. this-> get_type(32)
  7331. ),
  7332. this->gen_ext(
  7333. this->gen_const(64U, 2LL),
  7334. 32,
  7335. false),
  7336. this->gen_const(8U, rm)
  7337. });
  7338. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  7339. } else {
  7340. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector<Value*>{
  7341. this->builder.CreateTrunc(
  7342. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  7343. this-> get_type(32)
  7344. ),
  7345. this->gen_ext(
  7346. this->gen_const(64U, 2LL),
  7347. 32,
  7348. false),
  7349. this->gen_const(8U, rm)
  7350. });
  7351. uint64_t upper_val = - 1;
  7352. Value* Ftmp1_val = this->builder.CreateOr(
  7353. this->builder.CreateShl(
  7354. this->gen_const(64U, upper_val),
  7355. this->gen_const(64U, 32)),
  7356. this->gen_ext(
  7357. res_val,
  7358. 64,
  7359. false));
  7360. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  7361. }
  7362. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7363. this->gen_sync(POST_SYNC, 149);
  7364. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7365. this->gen_trap_check(bb);
  7366. return std::make_tuple(CONT, bb);
  7367. }
  7368. /* instruction 150: FCVT.S.WU */
  7369. std::tuple<continuation_e, BasicBlock*> __fcvt_s_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7370. bb->setName("FCVT.S.WU");
  7371. this->gen_sync(PRE_SYNC, 150);
  7372. uint8_t rd = ((bit_sub<7,5>(instr)));
  7373. uint8_t rm = ((bit_sub<12,3>(instr)));
  7374. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7375. if(this->disass_enabled){
  7376. /* generate console output when executing the command */
  7377. auto mnemonic = fmt::format(
  7378. "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.s.wu"),
  7379. fmt::arg("rd", rd), fmt::arg("rs1", name(rs1)));
  7380. std::vector<Value*> args {
  7381. this->core_ptr,
  7382. this->gen_const(64, pc.val),
  7383. this->builder.CreateGlobalStringPtr(mnemonic),
  7384. };
  7385. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7386. }
  7387. Value* cur_pc_val = this->gen_const(64, pc.val);
  7388. pc=pc+4;
  7389. if(64 == 32){
  7390. Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector<Value*>{
  7391. this->builder.CreateTrunc(
  7392. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  7393. this-> get_type(32)
  7394. ),
  7395. this->gen_ext(
  7396. this->gen_const(64U, 3LL),
  7397. 32,
  7398. false),
  7399. this->gen_const(8U, rm)
  7400. });
  7401. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  7402. } else {
  7403. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector<Value*>{
  7404. this->builder.CreateTrunc(
  7405. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  7406. this-> get_type(32)
  7407. ),
  7408. this->gen_ext(
  7409. this->gen_const(64U, 3LL),
  7410. 32,
  7411. false),
  7412. this->gen_const(8U, rm)
  7413. });
  7414. uint64_t upper_val = - 1;
  7415. Value* Ftmp1_val = this->builder.CreateOr(
  7416. this->builder.CreateShl(
  7417. this->gen_const(64U, upper_val),
  7418. this->gen_const(64U, 32)),
  7419. this->gen_ext(
  7420. res_val,
  7421. 64,
  7422. false));
  7423. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  7424. }
  7425. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7426. this->gen_sync(POST_SYNC, 150);
  7427. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7428. this->gen_trap_check(bb);
  7429. return std::make_tuple(CONT, bb);
  7430. }
  7431. /* instruction 151: FMV.X.W */
  7432. std::tuple<continuation_e, BasicBlock*> __fmv_x_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7433. bb->setName("FMV.X.W");
  7434. this->gen_sync(PRE_SYNC, 151);
  7435. uint8_t rd = ((bit_sub<7,5>(instr)));
  7436. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7437. if(this->disass_enabled){
  7438. /* generate console output when executing the command */
  7439. auto mnemonic = fmt::format(
  7440. "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fmv.x.w"),
  7441. fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1));
  7442. std::vector<Value*> args {
  7443. this->core_ptr,
  7444. this->gen_const(64, pc.val),
  7445. this->builder.CreateGlobalStringPtr(mnemonic),
  7446. };
  7447. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7448. }
  7449. Value* cur_pc_val = this->gen_const(64, pc.val);
  7450. pc=pc+4;
  7451. Value* Xtmp0_val = this->gen_ext(
  7452. this->builder.CreateTrunc(
  7453. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0),
  7454. this-> get_type(32)
  7455. ),
  7456. 64,
  7457. true);
  7458. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7459. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7460. this->gen_sync(POST_SYNC, 151);
  7461. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7462. this->gen_trap_check(bb);
  7463. return std::make_tuple(CONT, bb);
  7464. }
  7465. /* instruction 152: FMV.W.X */
  7466. std::tuple<continuation_e, BasicBlock*> __fmv_w_x(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7467. bb->setName("FMV.W.X");
  7468. this->gen_sync(PRE_SYNC, 152);
  7469. uint8_t rd = ((bit_sub<7,5>(instr)));
  7470. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7471. if(this->disass_enabled){
  7472. /* generate console output when executing the command */
  7473. auto mnemonic = fmt::format(
  7474. "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fmv.w.x"),
  7475. fmt::arg("rd", rd), fmt::arg("rs1", name(rs1)));
  7476. std::vector<Value*> args {
  7477. this->core_ptr,
  7478. this->gen_const(64, pc.val),
  7479. this->builder.CreateGlobalStringPtr(mnemonic),
  7480. };
  7481. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7482. }
  7483. Value* cur_pc_val = this->gen_const(64, pc.val);
  7484. pc=pc+4;
  7485. if(64 == 32){
  7486. Value* Ftmp0_val = this->builder.CreateTrunc(
  7487. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  7488. this-> get_type(32)
  7489. );
  7490. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  7491. } else {
  7492. uint64_t upper_val = - 1;
  7493. Value* Ftmp1_val = this->builder.CreateOr(
  7494. this->builder.CreateShl(
  7495. this->gen_const(64U, upper_val),
  7496. this->gen_const(64U, 32)),
  7497. this->gen_ext(
  7498. this->builder.CreateTrunc(
  7499. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  7500. this-> get_type(32)
  7501. ),
  7502. 64,
  7503. false));
  7504. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  7505. }
  7506. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7507. this->gen_sync(POST_SYNC, 152);
  7508. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7509. this->gen_trap_check(bb);
  7510. return std::make_tuple(CONT, bb);
  7511. }
  7512. /* instruction 153: FCVT.L.S */
  7513. std::tuple<continuation_e, BasicBlock*> __fcvt_l_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7514. bb->setName("FCVT.L.S");
  7515. this->gen_sync(PRE_SYNC, 153);
  7516. uint8_t rd = ((bit_sub<7,5>(instr)));
  7517. uint8_t rm = ((bit_sub<12,3>(instr)));
  7518. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7519. if(this->disass_enabled){
  7520. /* generate console output when executing the command */
  7521. auto mnemonic = fmt::format(
  7522. "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.l.s"),
  7523. fmt::arg("rd", rd), fmt::arg("rs1", rs1));
  7524. std::vector<Value*> args {
  7525. this->core_ptr,
  7526. this->gen_const(64, pc.val),
  7527. this->builder.CreateGlobalStringPtr(mnemonic),
  7528. };
  7529. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7530. }
  7531. Value* cur_pc_val = this->gen_const(64, pc.val);
  7532. pc=pc+4;
  7533. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_32_64"), std::vector<Value*>{
  7534. this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  7535. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  7536. }),
  7537. this->gen_ext(
  7538. this->gen_const(64U, 0LL),
  7539. 32,
  7540. false),
  7541. this->gen_const(8U, rm)
  7542. });
  7543. Value* Xtmp0_val = this->gen_ext(
  7544. res_val,
  7545. 64,
  7546. true);
  7547. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7548. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  7549. });
  7550. Value* FCSR_val = this->builder.CreateAdd(
  7551. this->builder.CreateAnd(
  7552. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  7553. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  7554. flags_val);
  7555. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  7556. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7557. this->gen_sync(POST_SYNC, 153);
  7558. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7559. this->gen_trap_check(bb);
  7560. return std::make_tuple(CONT, bb);
  7561. }
  7562. /* instruction 154: FCVT.LU.S */
  7563. std::tuple<continuation_e, BasicBlock*> __fcvt_lu_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7564. bb->setName("FCVT.LU.S");
  7565. this->gen_sync(PRE_SYNC, 154);
  7566. uint8_t rd = ((bit_sub<7,5>(instr)));
  7567. uint8_t rm = ((bit_sub<12,3>(instr)));
  7568. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7569. if(this->disass_enabled){
  7570. /* generate console output when executing the command */
  7571. auto mnemonic = fmt::format(
  7572. "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.lu.s"),
  7573. fmt::arg("rd", rd), fmt::arg("rs1", rs1));
  7574. std::vector<Value*> args {
  7575. this->core_ptr,
  7576. this->gen_const(64, pc.val),
  7577. this->builder.CreateGlobalStringPtr(mnemonic),
  7578. };
  7579. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7580. }
  7581. Value* cur_pc_val = this->gen_const(64, pc.val);
  7582. pc=pc+4;
  7583. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_32_64"), std::vector<Value*>{
  7584. this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector<Value*>{
  7585. this->gen_reg_load(rs1 + traits<ARCH>::F0, 0)
  7586. }),
  7587. this->gen_ext(
  7588. this->gen_const(64U, 1LL),
  7589. 32,
  7590. false),
  7591. this->gen_const(8U, rm)
  7592. });
  7593. Value* Xtmp0_val = this->gen_ext(
  7594. res_val,
  7595. 64,
  7596. false);
  7597. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7598. Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector<Value*>{
  7599. });
  7600. Value* FCSR_val = this->builder.CreateAdd(
  7601. this->builder.CreateAnd(
  7602. this->gen_reg_load(traits<ARCH>::FCSR, 0),
  7603. this->builder.CreateNot(this->gen_const(32U, 0x1f))),
  7604. flags_val);
  7605. this->builder.CreateStore(FCSR_val, get_reg_ptr(traits<ARCH>::FCSR), false);
  7606. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7607. this->gen_sync(POST_SYNC, 154);
  7608. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7609. this->gen_trap_check(bb);
  7610. return std::make_tuple(CONT, bb);
  7611. }
  7612. /* instruction 155: FCVT.S.L */
  7613. std::tuple<continuation_e, BasicBlock*> __fcvt_s_l(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7614. bb->setName("FCVT.S.L");
  7615. this->gen_sync(PRE_SYNC, 155);
  7616. uint8_t rd = ((bit_sub<7,5>(instr)));
  7617. uint8_t rm = ((bit_sub<12,3>(instr)));
  7618. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7619. if(this->disass_enabled){
  7620. /* generate console output when executing the command */
  7621. auto mnemonic = fmt::format(
  7622. "{mnemonic:10} f{rd}, x{rs1}", fmt::arg("mnemonic", "fcvt.s.l"),
  7623. fmt::arg("rd", rd), fmt::arg("rs1", rs1));
  7624. std::vector<Value*> args {
  7625. this->core_ptr,
  7626. this->gen_const(64, pc.val),
  7627. this->builder.CreateGlobalStringPtr(mnemonic),
  7628. };
  7629. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7630. }
  7631. Value* cur_pc_val = this->gen_const(64, pc.val);
  7632. pc=pc+4;
  7633. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_64_32"), std::vector<Value*>{
  7634. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  7635. this->gen_ext(
  7636. this->gen_const(64U, 2LL),
  7637. 32,
  7638. false)
  7639. });
  7640. if(64 == 32){
  7641. Value* Ftmp0_val = res_val;
  7642. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  7643. } else {
  7644. uint64_t upper_val = - 1;
  7645. Value* Ftmp1_val = this->builder.CreateOr(
  7646. this->builder.CreateShl(
  7647. this->gen_const(64U, upper_val),
  7648. this->gen_const(64U, 32)),
  7649. this->gen_ext(
  7650. res_val,
  7651. 64,
  7652. false));
  7653. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  7654. }
  7655. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7656. this->gen_sync(POST_SYNC, 155);
  7657. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7658. this->gen_trap_check(bb);
  7659. return std::make_tuple(CONT, bb);
  7660. }
  7661. /* instruction 156: FCVT.S.LU */
  7662. std::tuple<continuation_e, BasicBlock*> __fcvt_s_lu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7663. bb->setName("FCVT.S.LU");
  7664. this->gen_sync(PRE_SYNC, 156);
  7665. uint8_t rd = ((bit_sub<7,5>(instr)));
  7666. uint8_t rm = ((bit_sub<12,3>(instr)));
  7667. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7668. if(this->disass_enabled){
  7669. /* generate console output when executing the command */
  7670. auto mnemonic = fmt::format(
  7671. "{mnemonic:10} f{rd}, x{rs1}", fmt::arg("mnemonic", "fcvt.s.lu"),
  7672. fmt::arg("rd", rd), fmt::arg("rs1", rs1));
  7673. std::vector<Value*> args {
  7674. this->core_ptr,
  7675. this->gen_const(64, pc.val),
  7676. this->builder.CreateGlobalStringPtr(mnemonic),
  7677. };
  7678. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7679. }
  7680. Value* cur_pc_val = this->gen_const(64, pc.val);
  7681. pc=pc+4;
  7682. Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_64_32"), std::vector<Value*>{
  7683. this->gen_reg_load(rs1 + traits<ARCH>::X0, 0),
  7684. this->gen_ext(
  7685. this->gen_const(64U, 3LL),
  7686. 32,
  7687. false)
  7688. });
  7689. if(64 == 32){
  7690. Value* Ftmp0_val = res_val;
  7691. this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  7692. } else {
  7693. uint64_t upper_val = - 1;
  7694. Value* Ftmp1_val = this->builder.CreateOr(
  7695. this->builder.CreateShl(
  7696. this->gen_const(64U, upper_val),
  7697. this->gen_const(64U, 32)),
  7698. this->gen_ext(
  7699. res_val,
  7700. 64,
  7701. false));
  7702. this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits<ARCH>::F0), false);
  7703. }
  7704. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7705. this->gen_sync(POST_SYNC, 156);
  7706. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7707. this->gen_trap_check(bb);
  7708. return std::make_tuple(CONT, bb);
  7709. }
  7710. /* instruction 157: LR.W */
  7711. std::tuple<continuation_e, BasicBlock*> __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7712. bb->setName("LR.W");
  7713. this->gen_sync(PRE_SYNC, 157);
  7714. uint8_t rd = ((bit_sub<7,5>(instr)));
  7715. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7716. uint8_t rl = ((bit_sub<25,1>(instr)));
  7717. uint8_t aq = ((bit_sub<26,1>(instr)));
  7718. if(this->disass_enabled){
  7719. /* generate console output when executing the command */
  7720. auto mnemonic = fmt::format(
  7721. "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.w"),
  7722. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)));
  7723. std::vector<Value*> args {
  7724. this->core_ptr,
  7725. this->gen_const(64, pc.val),
  7726. this->builder.CreateGlobalStringPtr(mnemonic),
  7727. };
  7728. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7729. }
  7730. Value* cur_pc_val = this->gen_const(64, pc.val);
  7731. pc=pc+4;
  7732. if(rd != 0){
  7733. Value* offs_val = this->gen_reg_load(rs1 + traits<ARCH>::X0, 0);
  7734. Value* Xtmp0_val = this->gen_ext(
  7735. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8),
  7736. 64,
  7737. true);
  7738. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7739. Value* REStmp1_val = this->gen_ext(
  7740. this->builder.CreateNeg(this->gen_const(8U, 1)),
  7741. 32,
  7742. true);
  7743. this->gen_write_mem(
  7744. traits<ARCH>::RES,
  7745. offs_val,
  7746. this->builder.CreateZExtOrTrunc(REStmp1_val,this->get_type(32)));
  7747. }
  7748. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7749. this->gen_sync(POST_SYNC, 157);
  7750. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7751. this->gen_trap_check(bb);
  7752. return std::make_tuple(CONT, bb);
  7753. }
  7754. /* instruction 158: SC.W */
  7755. std::tuple<continuation_e, BasicBlock*> __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7756. bb->setName("SC.W");
  7757. this->gen_sync(PRE_SYNC, 158);
  7758. uint8_t rd = ((bit_sub<7,5>(instr)));
  7759. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7760. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  7761. uint8_t rl = ((bit_sub<25,1>(instr)));
  7762. uint8_t aq = ((bit_sub<26,1>(instr)));
  7763. if(this->disass_enabled){
  7764. /* generate console output when executing the command */
  7765. auto mnemonic = fmt::format(
  7766. "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.w"),
  7767. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
  7768. std::vector<Value*> args {
  7769. this->core_ptr,
  7770. this->gen_const(64, pc.val),
  7771. this->builder.CreateGlobalStringPtr(mnemonic),
  7772. };
  7773. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7774. }
  7775. Value* cur_pc_val = this->gen_const(64, pc.val);
  7776. pc=pc+4;
  7777. Value* offs_val = this->gen_reg_load(rs1 + traits<ARCH>::X0, 0);
  7778. Value* res1_val = this->gen_read_mem(traits<ARCH>::RES, offs_val, 32/8);
  7779. {
  7780. BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk);
  7781. BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext);
  7782. // this->builder.SetInsertPoint(bb);
  7783. this->gen_cond_branch(this->builder.CreateICmp(
  7784. ICmpInst::ICMP_NE,
  7785. res1_val,
  7786. this->gen_const(32U, 0)),
  7787. bb_then,
  7788. bbnext);
  7789. this->builder.SetInsertPoint(bb_then);
  7790. {
  7791. Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits<ARCH>::X0, 1);
  7792. this->gen_write_mem(
  7793. traits<ARCH>::MEM,
  7794. offs_val,
  7795. this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32)));
  7796. }
  7797. this->builder.CreateBr(bbnext);
  7798. bb=bbnext;
  7799. }
  7800. this->builder.SetInsertPoint(bb);
  7801. if(rd != 0){
  7802. Value* Xtmp1_val = this->gen_choose(
  7803. this->builder.CreateICmp(
  7804. ICmpInst::ICMP_NE,
  7805. res1_val,
  7806. this->gen_ext(
  7807. this->gen_const(64U, 0),
  7808. 32,
  7809. false)),
  7810. this->gen_const(64U, 0),
  7811. this->gen_const(64U, 1),
  7812. 64);
  7813. this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7814. }
  7815. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7816. this->gen_sync(POST_SYNC, 158);
  7817. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7818. this->gen_trap_check(bb);
  7819. return std::make_tuple(CONT, bb);
  7820. }
  7821. /* instruction 159: AMOSWAP.W */
  7822. std::tuple<continuation_e, BasicBlock*> __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7823. bb->setName("AMOSWAP.W");
  7824. this->gen_sync(PRE_SYNC, 159);
  7825. uint8_t rd = ((bit_sub<7,5>(instr)));
  7826. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7827. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  7828. uint8_t rl = ((bit_sub<25,1>(instr)));
  7829. uint8_t aq = ((bit_sub<26,1>(instr)));
  7830. if(this->disass_enabled){
  7831. /* generate console output when executing the command */
  7832. auto mnemonic = fmt::format(
  7833. "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.w"),
  7834. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl));
  7835. std::vector<Value*> args {
  7836. this->core_ptr,
  7837. this->gen_const(64, pc.val),
  7838. this->builder.CreateGlobalStringPtr(mnemonic),
  7839. };
  7840. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7841. }
  7842. Value* cur_pc_val = this->gen_const(64, pc.val);
  7843. pc=pc+4;
  7844. Value* offs_val = this->gen_reg_load(rs1 + traits<ARCH>::X0, 0);
  7845. if(rd != 0){
  7846. Value* Xtmp0_val = this->gen_ext(
  7847. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8),
  7848. 64,
  7849. true);
  7850. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7851. }
  7852. Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits<ARCH>::X0, 0);
  7853. this->gen_write_mem(
  7854. traits<ARCH>::MEM,
  7855. offs_val,
  7856. this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32)));
  7857. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7858. this->gen_sync(POST_SYNC, 159);
  7859. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7860. this->gen_trap_check(bb);
  7861. return std::make_tuple(CONT, bb);
  7862. }
  7863. /* instruction 160: AMOADD.W */
  7864. std::tuple<continuation_e, BasicBlock*> __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
  7865. bb->setName("AMOADD.W");
  7866. this->gen_sync(PRE_SYNC, 160);
  7867. uint8_t rd = ((bit_sub<7,5>(instr)));
  7868. uint8_t rs1 = ((bit_sub<15,5>(instr)));
  7869. uint8_t rs2 = ((bit_sub<20,5>(instr)));
  7870. uint8_t rl = ((bit_sub<25,1>(instr)));
  7871. uint8_t aq = ((bit_sub<26,1>(instr)));
  7872. if(this->disass_enabled){
  7873. /* generate console output when executing the command */
  7874. auto mnemonic = fmt::format(
  7875. "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.w"),
  7876. fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl));
  7877. std::vector<Value*> args {
  7878. this->core_ptr,
  7879. this->gen_const(64, pc.val),
  7880. this->builder.CreateGlobalStringPtr(mnemonic),
  7881. };
  7882. this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
  7883. }
  7884. Value* cur_pc_val = this->gen_const(64, pc.val);
  7885. pc=pc+4;
  7886. Value* offs_val = this->gen_reg_load(rs1 + traits<ARCH>::X0, 0);
  7887. Value* res1_val = this->gen_ext(
  7888. this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8),
  7889. 64,
  7890. true);
  7891. if(rd != 0){
  7892. Value* Xtmp0_val = res1_val;
  7893. this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits<ARCH>::X0), false);
  7894. }
  7895. Value* res2_val = this->builder.CreateAdd(
  7896. res1_val,
  7897. this->gen_reg_load(rs2 + traits<ARCH>::X0, 0));
  7898. Value* MEMtmp1_val = res2_val;
  7899. this->gen_write_mem(
  7900. traits<ARCH>::MEM,
  7901. offs_val,
  7902. this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32)));
  7903. this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
  7904. this->gen_sync(POST_SYNC, 160);
  7905. bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
  7906. this->gen_trap_check(bb);
  7907. return std::make_tuple(CONT, bb);
  7908. }