simulator.c 358 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383
  1. /* simulator.c -- Interface for the AArch64 simulator.
  2. Copyright (C) 2015-2022 Free Software Foundation, Inc.
  3. Contributed by Red Hat.
  4. This file is part of GDB.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. /* This must come before any other includes. */
  16. #include "defs.h"
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <sys/types.h>
  21. #include <math.h>
  22. #include <time.h>
  23. #include <limits.h>
  24. #include "simulator.h"
  25. #include "cpustate.h"
  26. #include "memory.h"
  27. #include "sim-signal.h"
  28. #define NO_SP 0
  29. #define SP_OK 1
  30. #define TST(_flag) (aarch64_test_CPSR_bit (cpu, _flag))
  31. #define IS_SET(_X) (TST (( _X )) ? 1 : 0)
  32. #define IS_CLEAR(_X) (TST (( _X )) ? 0 : 1)
  33. /* Space saver macro. */
  34. #define INSTR(HIGH, LOW) uimm (aarch64_get_instr (cpu), (HIGH), (LOW))
  35. #define HALT_UNALLOC \
  36. do \
  37. { \
  38. TRACE_DISASM (cpu, aarch64_get_PC (cpu)); \
  39. TRACE_INSN (cpu, \
  40. "Unallocated instruction detected at sim line %d," \
  41. " exe addr %" PRIx64, \
  42. __LINE__, aarch64_get_PC (cpu)); \
  43. sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),\
  44. sim_stopped, SIM_SIGILL); \
  45. } \
  46. while (0)
  47. #define HALT_NYI \
  48. do \
  49. { \
  50. TRACE_DISASM (cpu, aarch64_get_PC (cpu)); \
  51. TRACE_INSN (cpu, \
  52. "Unimplemented instruction detected at sim line %d," \
  53. " exe addr %" PRIx64, \
  54. __LINE__, aarch64_get_PC (cpu)); \
  55. if (! TRACE_ANY_P (cpu)) \
  56. sim_io_eprintf (CPU_STATE (cpu), "SIM Error: Unimplemented instruction: %#08x\n", \
  57. aarch64_get_instr (cpu)); \
  58. sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),\
  59. sim_stopped, SIM_SIGABRT); \
  60. } \
  61. while (0)
  62. #define NYI_assert(HI, LO, EXPECTED) \
  63. do \
  64. { \
  65. if (INSTR ((HI), (LO)) != (EXPECTED)) \
  66. HALT_NYI; \
  67. } \
  68. while (0)
  69. /* Helper functions used by expandLogicalImmediate. */
  70. /* for i = 1, ... N result<i-1> = 1 other bits are zero */
  71. static inline uint64_t
  72. ones (int N)
  73. {
  74. return (N == 64 ? (uint64_t)-1UL : ((1UL << N) - 1));
  75. }
  76. /* result<0> to val<N> */
  77. static inline uint64_t
  78. pickbit (uint64_t val, int N)
  79. {
  80. return pickbits64 (val, N, N);
  81. }
  82. static uint64_t
  83. expand_logical_immediate (uint32_t S, uint32_t R, uint32_t N)
  84. {
  85. uint64_t mask;
  86. uint64_t imm;
  87. unsigned simd_size;
  88. /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
  89. (in other words, right rotated by R), then replicated. */
  90. if (N != 0)
  91. {
  92. simd_size = 64;
  93. mask = 0xffffffffffffffffull;
  94. }
  95. else
  96. {
  97. switch (S)
  98. {
  99. case 0x00 ... 0x1f: /* 0xxxxx */ simd_size = 32; break;
  100. case 0x20 ... 0x2f: /* 10xxxx */ simd_size = 16; S &= 0xf; break;
  101. case 0x30 ... 0x37: /* 110xxx */ simd_size = 8; S &= 0x7; break;
  102. case 0x38 ... 0x3b: /* 1110xx */ simd_size = 4; S &= 0x3; break;
  103. case 0x3c ... 0x3d: /* 11110x */ simd_size = 2; S &= 0x1; break;
  104. default: return 0;
  105. }
  106. mask = (1ull << simd_size) - 1;
  107. /* Top bits are IGNORED. */
  108. R &= simd_size - 1;
  109. }
  110. /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected. */
  111. if (S == simd_size - 1)
  112. return 0;
  113. /* S+1 consecutive bits to 1. */
  114. /* NOTE: S can't be 63 due to detection above. */
  115. imm = (1ull << (S + 1)) - 1;
  116. /* Rotate to the left by simd_size - R. */
  117. if (R != 0)
  118. imm = ((imm << (simd_size - R)) & mask) | (imm >> R);
  119. /* Replicate the value according to SIMD size. */
  120. switch (simd_size)
  121. {
  122. case 2: imm = (imm << 2) | imm;
  123. case 4: imm = (imm << 4) | imm;
  124. case 8: imm = (imm << 8) | imm;
  125. case 16: imm = (imm << 16) | imm;
  126. case 32: imm = (imm << 32) | imm;
  127. case 64: break;
  128. default: return 0;
  129. }
  130. return imm;
  131. }
  132. /* Instr[22,10] encodes N immr and imms. we want a lookup table
  133. for each possible combination i.e. 13 bits worth of int entries. */
  134. #define LI_TABLE_SIZE (1 << 13)
  135. static uint64_t LITable[LI_TABLE_SIZE];
  136. void
  137. aarch64_init_LIT_table (void)
  138. {
  139. unsigned index;
  140. for (index = 0; index < LI_TABLE_SIZE; index++)
  141. {
  142. uint32_t N = uimm (index, 12, 12);
  143. uint32_t immr = uimm (index, 11, 6);
  144. uint32_t imms = uimm (index, 5, 0);
  145. LITable [index] = expand_logical_immediate (imms, immr, N);
  146. }
  147. }
  148. static void
  149. dexNotify (sim_cpu *cpu)
  150. {
  151. /* instr[14,0] == type : 0 ==> method entry, 1 ==> method reentry
  152. 2 ==> exit Java, 3 ==> start next bytecode. */
  153. uint32_t type = INSTR (14, 0);
  154. TRACE_EVENTS (cpu, "Notify Insn encountered, type = 0x%x", type);
  155. switch (type)
  156. {
  157. case 0:
  158. /* aarch64_notifyMethodEntry (aarch64_get_reg_u64 (cpu, R23, 0),
  159. aarch64_get_reg_u64 (cpu, R22, 0)); */
  160. break;
  161. case 1:
  162. /* aarch64_notifyMethodReentry (aarch64_get_reg_u64 (cpu, R23, 0),
  163. aarch64_get_reg_u64 (cpu, R22, 0)); */
  164. break;
  165. case 2:
  166. /* aarch64_notifyMethodExit (); */
  167. break;
  168. case 3:
  169. /* aarch64_notifyBCStart (aarch64_get_reg_u64 (cpu, R23, 0),
  170. aarch64_get_reg_u64 (cpu, R22, 0)); */
  171. break;
  172. }
  173. }
  174. /* secondary decode within top level groups */
  175. static void
  176. dexPseudo (sim_cpu *cpu)
  177. {
  178. /* assert instr[28,27] = 00
  179. We provide 2 pseudo instructions:
  180. HALT stops execution of the simulator causing an immediate
  181. return to the x86 code which entered it.
  182. CALLOUT initiates recursive entry into x86 code. A register
  183. argument holds the address of the x86 routine. Immediate
  184. values in the instruction identify the number of general
  185. purpose and floating point register arguments to be passed
  186. and the type of any value to be returned. */
  187. uint32_t PSEUDO_HALT = 0xE0000000U;
  188. uint32_t PSEUDO_CALLOUT = 0x00018000U;
  189. uint32_t PSEUDO_CALLOUTR = 0x00018001U;
  190. uint32_t PSEUDO_NOTIFY = 0x00014000U;
  191. uint32_t dispatch;
  192. if (aarch64_get_instr (cpu) == PSEUDO_HALT)
  193. {
  194. TRACE_EVENTS (cpu, " Pseudo Halt Instruction");
  195. sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
  196. sim_stopped, SIM_SIGTRAP);
  197. }
  198. dispatch = INSTR (31, 15);
  199. /* We do not handle callouts at the moment. */
  200. if (dispatch == PSEUDO_CALLOUT || dispatch == PSEUDO_CALLOUTR)
  201. {
  202. TRACE_EVENTS (cpu, " Callout");
  203. sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
  204. sim_stopped, SIM_SIGABRT);
  205. }
  206. else if (dispatch == PSEUDO_NOTIFY)
  207. dexNotify (cpu);
  208. else
  209. HALT_UNALLOC;
  210. }
  211. /* Load-store single register (unscaled offset)
  212. These instructions employ a base register plus an unscaled signed
  213. 9 bit offset.
  214. N.B. the base register (source) can be Xn or SP. all other
  215. registers may not be SP. */
  216. /* 32 bit load 32 bit unscaled signed 9 bit. */
  217. static void
  218. ldur32 (sim_cpu *cpu, int32_t offset)
  219. {
  220. unsigned rn = INSTR (9, 5);
  221. unsigned rt = INSTR (4, 0);
  222. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  223. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32
  224. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  225. + offset));
  226. }
  227. /* 64 bit load 64 bit unscaled signed 9 bit. */
  228. static void
  229. ldur64 (sim_cpu *cpu, int32_t offset)
  230. {
  231. unsigned rn = INSTR (9, 5);
  232. unsigned rt = INSTR (4, 0);
  233. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  234. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64
  235. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  236. + offset));
  237. }
  238. /* 32 bit load zero-extended byte unscaled signed 9 bit. */
  239. static void
  240. ldurb32 (sim_cpu *cpu, int32_t offset)
  241. {
  242. unsigned rn = INSTR (9, 5);
  243. unsigned rt = INSTR (4, 0);
  244. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  245. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u8
  246. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  247. + offset));
  248. }
  249. /* 32 bit load sign-extended byte unscaled signed 9 bit. */
  250. static void
  251. ldursb32 (sim_cpu *cpu, int32_t offset)
  252. {
  253. unsigned rn = INSTR (9, 5);
  254. unsigned rt = INSTR (4, 0);
  255. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  256. aarch64_set_reg_u64 (cpu, rt, NO_SP, (uint32_t) aarch64_get_mem_s8
  257. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  258. + offset));
  259. }
  260. /* 64 bit load sign-extended byte unscaled signed 9 bit. */
  261. static void
  262. ldursb64 (sim_cpu *cpu, int32_t offset)
  263. {
  264. unsigned rn = INSTR (9, 5);
  265. unsigned rt = INSTR (4, 0);
  266. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  267. aarch64_set_reg_s64 (cpu, rt, NO_SP, aarch64_get_mem_s8
  268. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  269. + offset));
  270. }
  271. /* 32 bit load zero-extended short unscaled signed 9 bit */
  272. static void
  273. ldurh32 (sim_cpu *cpu, int32_t offset)
  274. {
  275. unsigned rn = INSTR (9, 5);
  276. unsigned rd = INSTR (4, 0);
  277. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  278. aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_mem_u16
  279. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  280. + offset));
  281. }
  282. /* 32 bit load sign-extended short unscaled signed 9 bit */
  283. static void
  284. ldursh32 (sim_cpu *cpu, int32_t offset)
  285. {
  286. unsigned rn = INSTR (9, 5);
  287. unsigned rd = INSTR (4, 0);
  288. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  289. aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) aarch64_get_mem_s16
  290. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  291. + offset));
  292. }
  293. /* 64 bit load sign-extended short unscaled signed 9 bit */
  294. static void
  295. ldursh64 (sim_cpu *cpu, int32_t offset)
  296. {
  297. unsigned rn = INSTR (9, 5);
  298. unsigned rt = INSTR (4, 0);
  299. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  300. aarch64_set_reg_s64 (cpu, rt, NO_SP, aarch64_get_mem_s16
  301. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  302. + offset));
  303. }
  304. /* 64 bit load sign-extended word unscaled signed 9 bit */
  305. static void
  306. ldursw (sim_cpu *cpu, int32_t offset)
  307. {
  308. unsigned rn = INSTR (9, 5);
  309. unsigned rd = INSTR (4, 0);
  310. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  311. aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) aarch64_get_mem_s32
  312. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  313. + offset));
  314. }
  315. /* N.B. with stores the value in source is written to the address
  316. identified by source2 modified by offset. */
  317. /* 32 bit store 32 bit unscaled signed 9 bit. */
  318. static void
  319. stur32 (sim_cpu *cpu, int32_t offset)
  320. {
  321. unsigned rn = INSTR (9, 5);
  322. unsigned rd = INSTR (4, 0);
  323. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  324. aarch64_set_mem_u32 (cpu,
  325. aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
  326. aarch64_get_reg_u32 (cpu, rd, NO_SP));
  327. }
  328. /* 64 bit store 64 bit unscaled signed 9 bit */
  329. static void
  330. stur64 (sim_cpu *cpu, int32_t offset)
  331. {
  332. unsigned rn = INSTR (9, 5);
  333. unsigned rd = INSTR (4, 0);
  334. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  335. aarch64_set_mem_u64 (cpu,
  336. aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
  337. aarch64_get_reg_u64 (cpu, rd, NO_SP));
  338. }
  339. /* 32 bit store byte unscaled signed 9 bit */
  340. static void
  341. sturb (sim_cpu *cpu, int32_t offset)
  342. {
  343. unsigned rn = INSTR (9, 5);
  344. unsigned rd = INSTR (4, 0);
  345. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  346. aarch64_set_mem_u8 (cpu,
  347. aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
  348. aarch64_get_reg_u8 (cpu, rd, NO_SP));
  349. }
  350. /* 32 bit store short unscaled signed 9 bit */
  351. static void
  352. sturh (sim_cpu *cpu, int32_t offset)
  353. {
  354. unsigned rn = INSTR (9, 5);
  355. unsigned rd = INSTR (4, 0);
  356. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  357. aarch64_set_mem_u16 (cpu,
  358. aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
  359. aarch64_get_reg_u16 (cpu, rd, NO_SP));
  360. }
  361. /* Load single register pc-relative label
  362. Offset is a signed 19 bit immediate count in words
  363. rt may not be SP. */
  364. /* 32 bit pc-relative load */
  365. static void
  366. ldr32_pcrel (sim_cpu *cpu, int32_t offset)
  367. {
  368. unsigned rd = INSTR (4, 0);
  369. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  370. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  371. aarch64_get_mem_u32
  372. (cpu, aarch64_get_PC (cpu) + offset * 4));
  373. }
  374. /* 64 bit pc-relative load */
  375. static void
  376. ldr_pcrel (sim_cpu *cpu, int32_t offset)
  377. {
  378. unsigned rd = INSTR (4, 0);
  379. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  380. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  381. aarch64_get_mem_u64
  382. (cpu, aarch64_get_PC (cpu) + offset * 4));
  383. }
  384. /* sign extended 32 bit pc-relative load */
  385. static void
  386. ldrsw_pcrel (sim_cpu *cpu, int32_t offset)
  387. {
  388. unsigned rd = INSTR (4, 0);
  389. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  390. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  391. aarch64_get_mem_s32
  392. (cpu, aarch64_get_PC (cpu) + offset * 4));
  393. }
  394. /* float pc-relative load */
  395. static void
  396. fldrs_pcrel (sim_cpu *cpu, int32_t offset)
  397. {
  398. unsigned int rd = INSTR (4, 0);
  399. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  400. aarch64_set_vec_u32 (cpu, rd, 0,
  401. aarch64_get_mem_u32
  402. (cpu, aarch64_get_PC (cpu) + offset * 4));
  403. }
  404. /* double pc-relative load */
  405. static void
  406. fldrd_pcrel (sim_cpu *cpu, int32_t offset)
  407. {
  408. unsigned int st = INSTR (4, 0);
  409. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  410. aarch64_set_vec_u64 (cpu, st, 0,
  411. aarch64_get_mem_u64
  412. (cpu, aarch64_get_PC (cpu) + offset * 4));
  413. }
  414. /* long double pc-relative load. */
  415. static void
  416. fldrq_pcrel (sim_cpu *cpu, int32_t offset)
  417. {
  418. unsigned int st = INSTR (4, 0);
  419. uint64_t addr = aarch64_get_PC (cpu) + offset * 4;
  420. FRegister a;
  421. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  422. aarch64_get_mem_long_double (cpu, addr, & a);
  423. aarch64_set_FP_long_double (cpu, st, a);
  424. }
  425. /* This can be used to scale an offset by applying
  426. the requisite shift. the second argument is either
  427. 16, 32 or 64. */
  428. #define SCALE(_offset, _elementSize) \
  429. ((_offset) << ScaleShift ## _elementSize)
  430. /* This can be used to optionally scale a register derived offset
  431. by applying the requisite shift as indicated by the Scaling
  432. argument. The second argument is either Byte, Short, Word
  433. or Long. The third argument is either Scaled or Unscaled.
  434. N.B. when _Scaling is Scaled the shift gets ANDed with
  435. all 1s while when it is Unscaled it gets ANDed with 0. */
  436. #define OPT_SCALE(_offset, _elementType, _Scaling) \
  437. ((_offset) << (_Scaling ? ScaleShift ## _elementType : 0))
  438. /* This can be used to zero or sign extend a 32 bit register derived
  439. value to a 64 bit value. the first argument must be the value as
  440. a uint32_t and the second must be either UXTW or SXTW. The result
  441. is returned as an int64_t. */
  442. static inline int64_t
  443. extend (uint32_t value, Extension extension)
  444. {
  445. union
  446. {
  447. uint32_t u;
  448. int32_t n;
  449. } x;
  450. /* A branchless variant of this ought to be possible. */
  451. if (extension == UXTW || extension == NoExtension)
  452. return value;
  453. x.u = value;
  454. return x.n;
  455. }
  456. /* Scalar Floating Point
  457. FP load/store single register (4 addressing modes)
  458. N.B. the base register (source) can be the stack pointer.
  459. The secondary source register (source2) can only be an Xn register. */
  460. /* Load 32 bit unscaled signed 9 bit with pre- or post-writeback. */
  461. static void
  462. fldrs_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  463. {
  464. unsigned rn = INSTR (9, 5);
  465. unsigned st = INSTR (4, 0);
  466. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  467. if (wb != Post)
  468. address += offset;
  469. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  470. aarch64_set_vec_u32 (cpu, st, 0, aarch64_get_mem_u32 (cpu, address));
  471. if (wb == Post)
  472. address += offset;
  473. if (wb != NoWriteBack)
  474. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  475. }
  476. /* Load 8 bit with unsigned 12 bit offset. */
  477. static void
  478. fldrb_abs (sim_cpu *cpu, uint32_t offset)
  479. {
  480. unsigned rd = INSTR (4, 0);
  481. unsigned rn = INSTR (9, 5);
  482. uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset;
  483. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  484. aarch64_set_vec_u8 (cpu, rd, 0, aarch64_get_mem_u32 (cpu, addr));
  485. }
  486. /* Load 16 bit scaled unsigned 12 bit. */
  487. static void
  488. fldrh_abs (sim_cpu *cpu, uint32_t offset)
  489. {
  490. unsigned rd = INSTR (4, 0);
  491. unsigned rn = INSTR (9, 5);
  492. uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 16);
  493. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  494. aarch64_set_vec_u16 (cpu, rd, 0, aarch64_get_mem_u16 (cpu, addr));
  495. }
  496. /* Load 32 bit scaled unsigned 12 bit. */
  497. static void
  498. fldrs_abs (sim_cpu *cpu, uint32_t offset)
  499. {
  500. unsigned rd = INSTR (4, 0);
  501. unsigned rn = INSTR (9, 5);
  502. uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 32);
  503. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  504. aarch64_set_vec_u32 (cpu, rd, 0, aarch64_get_mem_u32 (cpu, addr));
  505. }
  506. /* Load 64 bit scaled unsigned 12 bit. */
  507. static void
  508. fldrd_abs (sim_cpu *cpu, uint32_t offset)
  509. {
  510. unsigned rd = INSTR (4, 0);
  511. unsigned rn = INSTR (9, 5);
  512. uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 64);
  513. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  514. aarch64_set_vec_u64 (cpu, rd, 0, aarch64_get_mem_u64 (cpu, addr));
  515. }
  516. /* Load 128 bit scaled unsigned 12 bit. */
  517. static void
  518. fldrq_abs (sim_cpu *cpu, uint32_t offset)
  519. {
  520. unsigned rd = INSTR (4, 0);
  521. unsigned rn = INSTR (9, 5);
  522. uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 128);
  523. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  524. aarch64_set_vec_u64 (cpu, rd, 0, aarch64_get_mem_u64 (cpu, addr));
  525. aarch64_set_vec_u64 (cpu, rd, 1, aarch64_get_mem_u64 (cpu, addr + 8));
  526. }
  527. /* Load 32 bit scaled or unscaled zero- or sign-extended
  528. 32-bit register offset. */
  529. static void
  530. fldrs_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  531. {
  532. unsigned rm = INSTR (20, 16);
  533. unsigned rn = INSTR (9, 5);
  534. unsigned st = INSTR (4, 0);
  535. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  536. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
  537. uint64_t displacement = OPT_SCALE (extended, 32, scaling);
  538. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  539. aarch64_set_vec_u32 (cpu, st, 0, aarch64_get_mem_u32
  540. (cpu, address + displacement));
  541. }
  542. /* Load 64 bit unscaled signed 9 bit with pre- or post-writeback. */
  543. static void
  544. fldrd_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  545. {
  546. unsigned rn = INSTR (9, 5);
  547. unsigned st = INSTR (4, 0);
  548. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  549. if (wb != Post)
  550. address += offset;
  551. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  552. aarch64_set_vec_u64 (cpu, st, 0, aarch64_get_mem_u64 (cpu, address));
  553. if (wb == Post)
  554. address += offset;
  555. if (wb != NoWriteBack)
  556. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  557. }
  558. /* Load 64 bit scaled or unscaled zero- or sign-extended 32-bit register offset. */
  559. static void
  560. fldrd_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  561. {
  562. unsigned rm = INSTR (20, 16);
  563. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
  564. uint64_t displacement = OPT_SCALE (extended, 64, scaling);
  565. fldrd_wb (cpu, displacement, NoWriteBack);
  566. }
  567. /* Load 128 bit unscaled signed 9 bit with pre- or post-writeback. */
  568. static void
  569. fldrq_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  570. {
  571. FRegister a;
  572. unsigned rn = INSTR (9, 5);
  573. unsigned st = INSTR (4, 0);
  574. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  575. if (wb != Post)
  576. address += offset;
  577. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  578. aarch64_get_mem_long_double (cpu, address, & a);
  579. aarch64_set_FP_long_double (cpu, st, a);
  580. if (wb == Post)
  581. address += offset;
  582. if (wb != NoWriteBack)
  583. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  584. }
  585. /* Load 128 bit scaled or unscaled zero- or sign-extended 32-bit register offset */
  586. static void
  587. fldrq_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  588. {
  589. unsigned rm = INSTR (20, 16);
  590. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
  591. uint64_t displacement = OPT_SCALE (extended, 128, scaling);
  592. fldrq_wb (cpu, displacement, NoWriteBack);
  593. }
  594. /* Memory Access
  595. load-store single register
  596. There are four addressing modes available here which all employ a
  597. 64 bit source (base) register.
  598. N.B. the base register (source) can be the stack pointer.
  599. The secondary source register (source2)can only be an Xn register.
  600. Scaled, 12-bit, unsigned immediate offset, without pre- and
  601. post-index options.
  602. Unscaled, 9-bit, signed immediate offset with pre- or post-index
  603. writeback.
  604. scaled or unscaled 64-bit register offset.
  605. scaled or unscaled 32-bit extended register offset.
  606. All offsets are assumed to be raw from the decode i.e. the
  607. simulator is expected to adjust scaled offsets based on the
  608. accessed data size with register or extended register offset
  609. versions the same applies except that in the latter case the
  610. operation may also require a sign extend.
  611. A separate method is provided for each possible addressing mode. */
  612. /* 32 bit load 32 bit scaled unsigned 12 bit */
  613. static void
  614. ldr32_abs (sim_cpu *cpu, uint32_t offset)
  615. {
  616. unsigned rn = INSTR (9, 5);
  617. unsigned rt = INSTR (4, 0);
  618. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  619. /* The target register may not be SP but the source may be. */
  620. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32
  621. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  622. + SCALE (offset, 32)));
  623. }
  624. /* 32 bit load 32 bit unscaled signed 9 bit with pre- or post-writeback. */
  625. static void
  626. ldr32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  627. {
  628. unsigned rn = INSTR (9, 5);
  629. unsigned rt = INSTR (4, 0);
  630. uint64_t address;
  631. if (rn == rt && wb != NoWriteBack)
  632. HALT_UNALLOC;
  633. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  634. if (wb != Post)
  635. address += offset;
  636. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  637. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32 (cpu, address));
  638. if (wb == Post)
  639. address += offset;
  640. if (wb != NoWriteBack)
  641. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  642. }
  643. /* 32 bit load 32 bit scaled or unscaled
  644. zero- or sign-extended 32-bit register offset */
  645. static void
  646. ldr32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  647. {
  648. unsigned rm = INSTR (20, 16);
  649. unsigned rn = INSTR (9, 5);
  650. unsigned rt = INSTR (4, 0);
  651. /* rn may reference SP, rm and rt must reference ZR */
  652. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  653. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
  654. uint64_t displacement = OPT_SCALE (extended, 32, scaling);
  655. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  656. aarch64_set_reg_u64 (cpu, rt, NO_SP,
  657. aarch64_get_mem_u32 (cpu, address + displacement));
  658. }
  659. /* 64 bit load 64 bit scaled unsigned 12 bit */
  660. static void
  661. ldr_abs (sim_cpu *cpu, uint32_t offset)
  662. {
  663. unsigned rn = INSTR (9, 5);
  664. unsigned rt = INSTR (4, 0);
  665. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  666. /* The target register may not be SP but the source may be. */
  667. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64
  668. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  669. + SCALE (offset, 64)));
  670. }
  671. /* 64 bit load 64 bit unscaled signed 9 bit with pre- or post-writeback. */
  672. static void
  673. ldr_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  674. {
  675. unsigned rn = INSTR (9, 5);
  676. unsigned rt = INSTR (4, 0);
  677. uint64_t address;
  678. if (rn == rt && wb != NoWriteBack)
  679. HALT_UNALLOC;
  680. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  681. if (wb != Post)
  682. address += offset;
  683. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  684. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64 (cpu, address));
  685. if (wb == Post)
  686. address += offset;
  687. if (wb != NoWriteBack)
  688. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  689. }
  690. /* 64 bit load 64 bit scaled or unscaled zero-
  691. or sign-extended 32-bit register offset. */
  692. static void
  693. ldr_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  694. {
  695. unsigned rm = INSTR (20, 16);
  696. unsigned rn = INSTR (9, 5);
  697. unsigned rt = INSTR (4, 0);
  698. /* rn may reference SP, rm and rt must reference ZR */
  699. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  700. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
  701. uint64_t displacement = OPT_SCALE (extended, 64, scaling);
  702. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  703. aarch64_set_reg_u64 (cpu, rt, NO_SP,
  704. aarch64_get_mem_u64 (cpu, address + displacement));
  705. }
  706. /* 32 bit load zero-extended byte scaled unsigned 12 bit. */
  707. static void
  708. ldrb32_abs (sim_cpu *cpu, uint32_t offset)
  709. {
  710. unsigned rn = INSTR (9, 5);
  711. unsigned rt = INSTR (4, 0);
  712. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  713. /* The target register may not be SP but the source may be
  714. there is no scaling required for a byte load. */
  715. aarch64_set_reg_u64 (cpu, rt, NO_SP,
  716. aarch64_get_mem_u8
  717. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset));
  718. }
  719. /* 32 bit load zero-extended byte unscaled signed 9 bit with pre- or post-writeback. */
  720. static void
  721. ldrb32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  722. {
  723. unsigned rn = INSTR (9, 5);
  724. unsigned rt = INSTR (4, 0);
  725. uint64_t address;
  726. if (rn == rt && wb != NoWriteBack)
  727. HALT_UNALLOC;
  728. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  729. if (wb != Post)
  730. address += offset;
  731. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  732. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u8 (cpu, address));
  733. if (wb == Post)
  734. address += offset;
  735. if (wb != NoWriteBack)
  736. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  737. }
  738. /* 32 bit load zero-extended byte scaled or unscaled zero-
  739. or sign-extended 32-bit register offset. */
  740. static void
  741. ldrb32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  742. {
  743. unsigned rm = INSTR (20, 16);
  744. unsigned rn = INSTR (9, 5);
  745. unsigned rt = INSTR (4, 0);
  746. /* rn may reference SP, rm and rt must reference ZR */
  747. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  748. int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  749. extension);
  750. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  751. /* There is no scaling required for a byte load. */
  752. aarch64_set_reg_u64 (cpu, rt, NO_SP,
  753. aarch64_get_mem_u8 (cpu, address + displacement));
  754. }
  755. /* 64 bit load sign-extended byte unscaled signed 9 bit
  756. with pre- or post-writeback. */
  757. static void
  758. ldrsb_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  759. {
  760. unsigned rn = INSTR (9, 5);
  761. unsigned rt = INSTR (4, 0);
  762. uint64_t address;
  763. int64_t val;
  764. if (rn == rt && wb != NoWriteBack)
  765. HALT_UNALLOC;
  766. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  767. if (wb != Post)
  768. address += offset;
  769. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  770. val = aarch64_get_mem_s8 (cpu, address);
  771. aarch64_set_reg_s64 (cpu, rt, NO_SP, val);
  772. if (wb == Post)
  773. address += offset;
  774. if (wb != NoWriteBack)
  775. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  776. }
  777. /* 64 bit load sign-extended byte scaled unsigned 12 bit. */
  778. static void
  779. ldrsb_abs (sim_cpu *cpu, uint32_t offset)
  780. {
  781. ldrsb_wb (cpu, offset, NoWriteBack);
  782. }
  783. /* 64 bit load sign-extended byte scaled or unscaled zero-
  784. or sign-extended 32-bit register offset. */
  785. static void
  786. ldrsb_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  787. {
  788. unsigned rm = INSTR (20, 16);
  789. unsigned rn = INSTR (9, 5);
  790. unsigned rt = INSTR (4, 0);
  791. /* rn may reference SP, rm and rt must reference ZR */
  792. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  793. int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  794. extension);
  795. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  796. /* There is no scaling required for a byte load. */
  797. aarch64_set_reg_s64 (cpu, rt, NO_SP,
  798. aarch64_get_mem_s8 (cpu, address + displacement));
  799. }
  800. /* 32 bit load zero-extended short scaled unsigned 12 bit. */
  801. static void
  802. ldrh32_abs (sim_cpu *cpu, uint32_t offset)
  803. {
  804. unsigned rn = INSTR (9, 5);
  805. unsigned rt = INSTR (4, 0);
  806. uint32_t val;
  807. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  808. /* The target register may not be SP but the source may be. */
  809. val = aarch64_get_mem_u16 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  810. + SCALE (offset, 16));
  811. aarch64_set_reg_u32 (cpu, rt, NO_SP, val);
  812. }
  813. /* 32 bit load zero-extended short unscaled signed 9 bit
  814. with pre- or post-writeback. */
  815. static void
  816. ldrh32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  817. {
  818. unsigned rn = INSTR (9, 5);
  819. unsigned rt = INSTR (4, 0);
  820. uint64_t address;
  821. if (rn == rt && wb != NoWriteBack)
  822. HALT_UNALLOC;
  823. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  824. if (wb != Post)
  825. address += offset;
  826. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  827. aarch64_set_reg_u32 (cpu, rt, NO_SP, aarch64_get_mem_u16 (cpu, address));
  828. if (wb == Post)
  829. address += offset;
  830. if (wb != NoWriteBack)
  831. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  832. }
  833. /* 32 bit load zero-extended short scaled or unscaled zero-
  834. or sign-extended 32-bit register offset. */
  835. static void
  836. ldrh32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  837. {
  838. unsigned rm = INSTR (20, 16);
  839. unsigned rn = INSTR (9, 5);
  840. unsigned rt = INSTR (4, 0);
  841. /* rn may reference SP, rm and rt must reference ZR */
  842. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  843. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
  844. uint64_t displacement = OPT_SCALE (extended, 16, scaling);
  845. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  846. aarch64_set_reg_u32 (cpu, rt, NO_SP,
  847. aarch64_get_mem_u16 (cpu, address + displacement));
  848. }
  849. /* 32 bit load sign-extended short scaled unsigned 12 bit. */
  850. static void
  851. ldrsh32_abs (sim_cpu *cpu, uint32_t offset)
  852. {
  853. unsigned rn = INSTR (9, 5);
  854. unsigned rt = INSTR (4, 0);
  855. int32_t val;
  856. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  857. /* The target register may not be SP but the source may be. */
  858. val = aarch64_get_mem_s16 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  859. + SCALE (offset, 16));
  860. aarch64_set_reg_s32 (cpu, rt, NO_SP, val);
  861. }
  862. /* 32 bit load sign-extended short unscaled signed 9 bit
  863. with pre- or post-writeback. */
  864. static void
  865. ldrsh32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  866. {
  867. unsigned rn = INSTR (9, 5);
  868. unsigned rt = INSTR (4, 0);
  869. uint64_t address;
  870. if (rn == rt && wb != NoWriteBack)
  871. HALT_UNALLOC;
  872. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  873. if (wb != Post)
  874. address += offset;
  875. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  876. aarch64_set_reg_s32 (cpu, rt, NO_SP,
  877. (int32_t) aarch64_get_mem_s16 (cpu, address));
  878. if (wb == Post)
  879. address += offset;
  880. if (wb != NoWriteBack)
  881. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  882. }
  883. /* 32 bit load sign-extended short scaled or unscaled zero-
  884. or sign-extended 32-bit register offset. */
  885. static void
  886. ldrsh32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  887. {
  888. unsigned rm = INSTR (20, 16);
  889. unsigned rn = INSTR (9, 5);
  890. unsigned rt = INSTR (4, 0);
  891. /* rn may reference SP, rm and rt must reference ZR */
  892. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  893. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
  894. uint64_t displacement = OPT_SCALE (extended, 16, scaling);
  895. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  896. aarch64_set_reg_s32 (cpu, rt, NO_SP,
  897. (int32_t) aarch64_get_mem_s16
  898. (cpu, address + displacement));
  899. }
  900. /* 64 bit load sign-extended short scaled unsigned 12 bit. */
  901. static void
  902. ldrsh_abs (sim_cpu *cpu, uint32_t offset)
  903. {
  904. unsigned rn = INSTR (9, 5);
  905. unsigned rt = INSTR (4, 0);
  906. int64_t val;
  907. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  908. /* The target register may not be SP but the source may be. */
  909. val = aarch64_get_mem_s16 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  910. + SCALE (offset, 16));
  911. aarch64_set_reg_s64 (cpu, rt, NO_SP, val);
  912. }
  913. /* 64 bit load sign-extended short unscaled signed 9 bit
  914. with pre- or post-writeback. */
  915. static void
  916. ldrsh64_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  917. {
  918. unsigned rn = INSTR (9, 5);
  919. unsigned rt = INSTR (4, 0);
  920. uint64_t address;
  921. int64_t val;
  922. if (rn == rt && wb != NoWriteBack)
  923. HALT_UNALLOC;
  924. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  925. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  926. if (wb != Post)
  927. address += offset;
  928. val = aarch64_get_mem_s16 (cpu, address);
  929. aarch64_set_reg_s64 (cpu, rt, NO_SP, val);
  930. if (wb == Post)
  931. address += offset;
  932. if (wb != NoWriteBack)
  933. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  934. }
  935. /* 64 bit load sign-extended short scaled or unscaled zero-
  936. or sign-extended 32-bit register offset. */
  937. static void
  938. ldrsh_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  939. {
  940. unsigned rm = INSTR (20, 16);
  941. unsigned rn = INSTR (9, 5);
  942. unsigned rt = INSTR (4, 0);
  943. /* rn may reference SP, rm and rt must reference ZR */
  944. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  945. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
  946. uint64_t displacement = OPT_SCALE (extended, 16, scaling);
  947. int64_t val;
  948. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  949. val = aarch64_get_mem_s16 (cpu, address + displacement);
  950. aarch64_set_reg_s64 (cpu, rt, NO_SP, val);
  951. }
  952. /* 64 bit load sign-extended 32 bit scaled unsigned 12 bit. */
  953. static void
  954. ldrsw_abs (sim_cpu *cpu, uint32_t offset)
  955. {
  956. unsigned rn = INSTR (9, 5);
  957. unsigned rt = INSTR (4, 0);
  958. int64_t val;
  959. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  960. val = aarch64_get_mem_s32 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  961. + SCALE (offset, 32));
  962. /* The target register may not be SP but the source may be. */
  963. return aarch64_set_reg_s64 (cpu, rt, NO_SP, val);
  964. }
  965. /* 64 bit load sign-extended 32 bit unscaled signed 9 bit
  966. with pre- or post-writeback. */
  967. static void
  968. ldrsw_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  969. {
  970. unsigned rn = INSTR (9, 5);
  971. unsigned rt = INSTR (4, 0);
  972. uint64_t address;
  973. if (rn == rt && wb != NoWriteBack)
  974. HALT_UNALLOC;
  975. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  976. if (wb != Post)
  977. address += offset;
  978. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  979. aarch64_set_reg_s64 (cpu, rt, NO_SP, aarch64_get_mem_s32 (cpu, address));
  980. if (wb == Post)
  981. address += offset;
  982. if (wb != NoWriteBack)
  983. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  984. }
  985. /* 64 bit load sign-extended 32 bit scaled or unscaled zero-
  986. or sign-extended 32-bit register offset. */
  987. static void
  988. ldrsw_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  989. {
  990. unsigned rm = INSTR (20, 16);
  991. unsigned rn = INSTR (9, 5);
  992. unsigned rt = INSTR (4, 0);
  993. /* rn may reference SP, rm and rt must reference ZR */
  994. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  995. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
  996. uint64_t displacement = OPT_SCALE (extended, 32, scaling);
  997. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  998. aarch64_set_reg_s64 (cpu, rt, NO_SP,
  999. aarch64_get_mem_s32 (cpu, address + displacement));
  1000. }
  1001. /* N.B. with stores the value in source is written to the
  1002. address identified by source2 modified by source3/offset. */
  1003. /* 32 bit store scaled unsigned 12 bit. */
  1004. static void
  1005. str32_abs (sim_cpu *cpu, uint32_t offset)
  1006. {
  1007. unsigned rn = INSTR (9, 5);
  1008. unsigned rt = INSTR (4, 0);
  1009. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1010. /* The target register may not be SP but the source may be. */
  1011. aarch64_set_mem_u32 (cpu, (aarch64_get_reg_u64 (cpu, rn, SP_OK)
  1012. + SCALE (offset, 32)),
  1013. aarch64_get_reg_u32 (cpu, rt, NO_SP));
  1014. }
  1015. /* 32 bit store unscaled signed 9 bit with pre- or post-writeback. */
  1016. static void
  1017. str32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  1018. {
  1019. unsigned rn = INSTR (9, 5);
  1020. unsigned rt = INSTR (4, 0);
  1021. uint64_t address;
  1022. if (rn == rt && wb != NoWriteBack)
  1023. HALT_UNALLOC;
  1024. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1025. if (wb != Post)
  1026. address += offset;
  1027. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1028. aarch64_set_mem_u32 (cpu, address, aarch64_get_reg_u32 (cpu, rt, NO_SP));
  1029. if (wb == Post)
  1030. address += offset;
  1031. if (wb != NoWriteBack)
  1032. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  1033. }
  1034. /* 32 bit store scaled or unscaled zero- or
  1035. sign-extended 32-bit register offset. */
  1036. static void
  1037. str32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  1038. {
  1039. unsigned rm = INSTR (20, 16);
  1040. unsigned rn = INSTR (9, 5);
  1041. unsigned rt = INSTR (4, 0);
  1042. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1043. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
  1044. uint64_t displacement = OPT_SCALE (extended, 32, scaling);
  1045. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1046. aarch64_set_mem_u32 (cpu, address + displacement,
  1047. aarch64_get_reg_u64 (cpu, rt, NO_SP));
  1048. }
  1049. /* 64 bit store scaled unsigned 12 bit. */
  1050. static void
  1051. str_abs (sim_cpu *cpu, uint32_t offset)
  1052. {
  1053. unsigned rn = INSTR (9, 5);
  1054. unsigned rt = INSTR (4, 0);
  1055. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1056. aarch64_set_mem_u64 (cpu,
  1057. aarch64_get_reg_u64 (cpu, rn, SP_OK)
  1058. + SCALE (offset, 64),
  1059. aarch64_get_reg_u64 (cpu, rt, NO_SP));
  1060. }
  1061. /* 64 bit store unscaled signed 9 bit with pre- or post-writeback. */
  1062. static void
  1063. str_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  1064. {
  1065. unsigned rn = INSTR (9, 5);
  1066. unsigned rt = INSTR (4, 0);
  1067. uint64_t address;
  1068. if (rn == rt && wb != NoWriteBack)
  1069. HALT_UNALLOC;
  1070. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1071. if (wb != Post)
  1072. address += offset;
  1073. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1074. aarch64_set_mem_u64 (cpu, address, aarch64_get_reg_u64 (cpu, rt, NO_SP));
  1075. if (wb == Post)
  1076. address += offset;
  1077. if (wb != NoWriteBack)
  1078. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  1079. }
  1080. /* 64 bit store scaled or unscaled zero-
  1081. or sign-extended 32-bit register offset. */
  1082. static void
  1083. str_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  1084. {
  1085. unsigned rm = INSTR (20, 16);
  1086. unsigned rn = INSTR (9, 5);
  1087. unsigned rt = INSTR (4, 0);
  1088. /* rn may reference SP, rm and rt must reference ZR */
  1089. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1090. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  1091. extension);
  1092. uint64_t displacement = OPT_SCALE (extended, 64, scaling);
  1093. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1094. aarch64_set_mem_u64 (cpu, address + displacement,
  1095. aarch64_get_reg_u64 (cpu, rt, NO_SP));
  1096. }
  1097. /* 32 bit store byte scaled unsigned 12 bit. */
  1098. static void
  1099. strb_abs (sim_cpu *cpu, uint32_t offset)
  1100. {
  1101. unsigned rn = INSTR (9, 5);
  1102. unsigned rt = INSTR (4, 0);
  1103. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1104. /* The target register may not be SP but the source may be.
  1105. There is no scaling required for a byte load. */
  1106. aarch64_set_mem_u8 (cpu,
  1107. aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
  1108. aarch64_get_reg_u8 (cpu, rt, NO_SP));
  1109. }
  1110. /* 32 bit store byte unscaled signed 9 bit with pre- or post-writeback. */
  1111. static void
  1112. strb_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  1113. {
  1114. unsigned rn = INSTR (9, 5);
  1115. unsigned rt = INSTR (4, 0);
  1116. uint64_t address;
  1117. if (rn == rt && wb != NoWriteBack)
  1118. HALT_UNALLOC;
  1119. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1120. if (wb != Post)
  1121. address += offset;
  1122. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1123. aarch64_set_mem_u8 (cpu, address, aarch64_get_reg_u8 (cpu, rt, NO_SP));
  1124. if (wb == Post)
  1125. address += offset;
  1126. if (wb != NoWriteBack)
  1127. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  1128. }
  1129. /* 32 bit store byte scaled or unscaled zero-
  1130. or sign-extended 32-bit register offset. */
  1131. static void
  1132. strb_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  1133. {
  1134. unsigned rm = INSTR (20, 16);
  1135. unsigned rn = INSTR (9, 5);
  1136. unsigned rt = INSTR (4, 0);
  1137. /* rn may reference SP, rm and rt must reference ZR */
  1138. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1139. int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  1140. extension);
  1141. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1142. /* There is no scaling required for a byte load. */
  1143. aarch64_set_mem_u8 (cpu, address + displacement,
  1144. aarch64_get_reg_u8 (cpu, rt, NO_SP));
  1145. }
  1146. /* 32 bit store short scaled unsigned 12 bit. */
  1147. static void
  1148. strh_abs (sim_cpu *cpu, uint32_t offset)
  1149. {
  1150. unsigned rn = INSTR (9, 5);
  1151. unsigned rt = INSTR (4, 0);
  1152. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1153. /* The target register may not be SP but the source may be. */
  1154. aarch64_set_mem_u16 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
  1155. + SCALE (offset, 16),
  1156. aarch64_get_reg_u16 (cpu, rt, NO_SP));
  1157. }
  1158. /* 32 bit store short unscaled signed 9 bit with pre- or post-writeback. */
  1159. static void
  1160. strh_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  1161. {
  1162. unsigned rn = INSTR (9, 5);
  1163. unsigned rt = INSTR (4, 0);
  1164. uint64_t address;
  1165. if (rn == rt && wb != NoWriteBack)
  1166. HALT_UNALLOC;
  1167. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1168. if (wb != Post)
  1169. address += offset;
  1170. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1171. aarch64_set_mem_u16 (cpu, address, aarch64_get_reg_u16 (cpu, rt, NO_SP));
  1172. if (wb == Post)
  1173. address += offset;
  1174. if (wb != NoWriteBack)
  1175. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  1176. }
  1177. /* 32 bit store short scaled or unscaled zero-
  1178. or sign-extended 32-bit register offset. */
  1179. static void
  1180. strh_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  1181. {
  1182. unsigned rm = INSTR (20, 16);
  1183. unsigned rn = INSTR (9, 5);
  1184. unsigned rt = INSTR (4, 0);
  1185. /* rn may reference SP, rm and rt must reference ZR */
  1186. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1187. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
  1188. uint64_t displacement = OPT_SCALE (extended, 16, scaling);
  1189. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1190. aarch64_set_mem_u16 (cpu, address + displacement,
  1191. aarch64_get_reg_u16 (cpu, rt, NO_SP));
  1192. }
  1193. /* Prefetch unsigned 12 bit. */
  1194. static void
  1195. prfm_abs (sim_cpu *cpu, uint32_t offset)
  1196. {
  1197. /* instr[4,0] = prfop : 00000 ==> PLDL1KEEP, 00001 ==> PLDL1STRM,
  1198. 00010 ==> PLDL2KEEP, 00001 ==> PLDL2STRM,
  1199. 00100 ==> PLDL3KEEP, 00101 ==> PLDL3STRM,
  1200. 10000 ==> PSTL1KEEP, 10001 ==> PSTL1STRM,
  1201. 10010 ==> PSTL2KEEP, 10001 ==> PSTL2STRM,
  1202. 10100 ==> PSTL3KEEP, 10101 ==> PSTL3STRM,
  1203. ow ==> UNALLOC
  1204. PrfOp prfop = prfop (instr, 4, 0);
  1205. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK)
  1206. + SCALE (offset, 64). */
  1207. /* TODO : implement prefetch of address. */
  1208. }
  1209. /* Prefetch scaled or unscaled zero- or sign-extended 32-bit register offset. */
  1210. static void
  1211. prfm_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  1212. {
  1213. /* instr[4,0] = prfop : 00000 ==> PLDL1KEEP, 00001 ==> PLDL1STRM,
  1214. 00010 ==> PLDL2KEEP, 00001 ==> PLDL2STRM,
  1215. 00100 ==> PLDL3KEEP, 00101 ==> PLDL3STRM,
  1216. 10000 ==> PSTL1KEEP, 10001 ==> PSTL1STRM,
  1217. 10010 ==> PSTL2KEEP, 10001 ==> PSTL2STRM,
  1218. 10100 ==> PSTL3KEEP, 10101 ==> PSTL3STRM,
  1219. ow ==> UNALLOC
  1220. rn may reference SP, rm may only reference ZR
  1221. PrfOp prfop = prfop (instr, 4, 0);
  1222. uint64_t base = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1223. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  1224. extension);
  1225. uint64_t displacement = OPT_SCALE (extended, 64, scaling);
  1226. uint64_t address = base + displacement. */
  1227. /* TODO : implement prefetch of address */
  1228. }
  1229. /* 64 bit pc-relative prefetch. */
  1230. static void
  1231. prfm_pcrel (sim_cpu *cpu, int32_t offset)
  1232. {
  1233. /* instr[4,0] = prfop : 00000 ==> PLDL1KEEP, 00001 ==> PLDL1STRM,
  1234. 00010 ==> PLDL2KEEP, 00001 ==> PLDL2STRM,
  1235. 00100 ==> PLDL3KEEP, 00101 ==> PLDL3STRM,
  1236. 10000 ==> PSTL1KEEP, 10001 ==> PSTL1STRM,
  1237. 10010 ==> PSTL2KEEP, 10001 ==> PSTL2STRM,
  1238. 10100 ==> PSTL3KEEP, 10101 ==> PSTL3STRM,
  1239. ow ==> UNALLOC
  1240. PrfOp prfop = prfop (instr, 4, 0);
  1241. uint64_t address = aarch64_get_PC (cpu) + offset. */
  1242. /* TODO : implement this */
  1243. }
  1244. /* Load-store exclusive. */
  1245. static void
  1246. ldxr (sim_cpu *cpu)
  1247. {
  1248. unsigned rn = INSTR (9, 5);
  1249. unsigned rt = INSTR (4, 0);
  1250. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1251. int size = INSTR (31, 30);
  1252. /* int ordered = INSTR (15, 15); */
  1253. /* int exclusive = ! INSTR (23, 23); */
  1254. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1255. switch (size)
  1256. {
  1257. case 0:
  1258. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u8 (cpu, address));
  1259. break;
  1260. case 1:
  1261. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u16 (cpu, address));
  1262. break;
  1263. case 2:
  1264. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32 (cpu, address));
  1265. break;
  1266. case 3:
  1267. aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64 (cpu, address));
  1268. break;
  1269. }
  1270. }
  1271. static void
  1272. stxr (sim_cpu *cpu)
  1273. {
  1274. unsigned rn = INSTR (9, 5);
  1275. unsigned rt = INSTR (4, 0);
  1276. unsigned rs = INSTR (20, 16);
  1277. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1278. int size = INSTR (31, 30);
  1279. uint64_t data = aarch64_get_reg_u64 (cpu, rt, NO_SP);
  1280. switch (size)
  1281. {
  1282. case 0: aarch64_set_mem_u8 (cpu, address, data); break;
  1283. case 1: aarch64_set_mem_u16 (cpu, address, data); break;
  1284. case 2: aarch64_set_mem_u32 (cpu, address, data); break;
  1285. case 3: aarch64_set_mem_u64 (cpu, address, data); break;
  1286. }
  1287. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1288. aarch64_set_reg_u64 (cpu, rs, NO_SP, 0); /* Always exclusive... */
  1289. }
  1290. static void
  1291. dexLoadLiteral (sim_cpu *cpu)
  1292. {
  1293. /* instr[29,27] == 011
  1294. instr[25,24] == 00
  1295. instr[31,30:26] = opc: 000 ==> LDRW, 001 ==> FLDRS
  1296. 010 ==> LDRX, 011 ==> FLDRD
  1297. 100 ==> LDRSW, 101 ==> FLDRQ
  1298. 110 ==> PRFM, 111 ==> UNALLOC
  1299. instr[26] ==> V : 0 ==> GReg, 1 ==> FReg
  1300. instr[23, 5] == simm19 */
  1301. /* unsigned rt = INSTR (4, 0); */
  1302. uint32_t dispatch = (INSTR (31, 30) << 1) | INSTR (26, 26);
  1303. int32_t imm = simm32 (aarch64_get_instr (cpu), 23, 5);
  1304. switch (dispatch)
  1305. {
  1306. case 0: ldr32_pcrel (cpu, imm); break;
  1307. case 1: fldrs_pcrel (cpu, imm); break;
  1308. case 2: ldr_pcrel (cpu, imm); break;
  1309. case 3: fldrd_pcrel (cpu, imm); break;
  1310. case 4: ldrsw_pcrel (cpu, imm); break;
  1311. case 5: fldrq_pcrel (cpu, imm); break;
  1312. case 6: prfm_pcrel (cpu, imm); break;
  1313. case 7:
  1314. default:
  1315. HALT_UNALLOC;
  1316. }
  1317. }
  1318. /* Immediate arithmetic
  1319. The aimm argument is a 12 bit unsigned value or a 12 bit unsigned
  1320. value left shifted by 12 bits (done at decode).
  1321. N.B. the register args (dest, source) can normally be Xn or SP.
  1322. the exception occurs for flag setting instructions which may
  1323. only use Xn for the output (dest). */
  1324. /* 32 bit add immediate. */
  1325. static void
  1326. add32 (sim_cpu *cpu, uint32_t aimm)
  1327. {
  1328. unsigned rn = INSTR (9, 5);
  1329. unsigned rd = INSTR (4, 0);
  1330. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1331. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  1332. aarch64_get_reg_u32 (cpu, rn, SP_OK) + aimm);
  1333. }
  1334. /* 64 bit add immediate. */
  1335. static void
  1336. add64 (sim_cpu *cpu, uint32_t aimm)
  1337. {
  1338. unsigned rn = INSTR (9, 5);
  1339. unsigned rd = INSTR (4, 0);
  1340. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1341. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  1342. aarch64_get_reg_u64 (cpu, rn, SP_OK) + aimm);
  1343. }
  1344. static void
  1345. set_flags_for_add32 (sim_cpu *cpu, int32_t value1, int32_t value2)
  1346. {
  1347. int32_t result = value1 + value2;
  1348. int64_t sresult = (int64_t) value1 + (int64_t) value2;
  1349. uint64_t uresult = (uint64_t)(uint32_t) value1
  1350. + (uint64_t)(uint32_t) value2;
  1351. uint32_t flags = 0;
  1352. if (result == 0)
  1353. flags |= Z;
  1354. if (result & (1 << 31))
  1355. flags |= N;
  1356. if (uresult != (uint32_t)uresult)
  1357. flags |= C;
  1358. if (sresult != (int32_t)sresult)
  1359. flags |= V;
  1360. aarch64_set_CPSR (cpu, flags);
  1361. }
  1362. #define NEG(a) (((a) & signbit) == signbit)
  1363. #define POS(a) (((a) & signbit) == 0)
  1364. static void
  1365. set_flags_for_add64 (sim_cpu *cpu, uint64_t value1, uint64_t value2)
  1366. {
  1367. uint64_t result = value1 + value2;
  1368. uint32_t flags = 0;
  1369. uint64_t signbit = 1ULL << 63;
  1370. if (result == 0)
  1371. flags |= Z;
  1372. if (NEG (result))
  1373. flags |= N;
  1374. if ( (NEG (value1) && NEG (value2))
  1375. || (NEG (value1) && POS (result))
  1376. || (NEG (value2) && POS (result)))
  1377. flags |= C;
  1378. if ( (NEG (value1) && NEG (value2) && POS (result))
  1379. || (POS (value1) && POS (value2) && NEG (result)))
  1380. flags |= V;
  1381. aarch64_set_CPSR (cpu, flags);
  1382. }
  1383. static void
  1384. set_flags_for_sub32 (sim_cpu *cpu, uint32_t value1, uint32_t value2)
  1385. {
  1386. uint32_t result = value1 - value2;
  1387. uint32_t flags = 0;
  1388. uint32_t signbit = 1U << 31;
  1389. if (result == 0)
  1390. flags |= Z;
  1391. if (NEG (result))
  1392. flags |= N;
  1393. if ( (NEG (value1) && POS (value2))
  1394. || (NEG (value1) && POS (result))
  1395. || (POS (value2) && POS (result)))
  1396. flags |= C;
  1397. if ( (NEG (value1) && POS (value2) && POS (result))
  1398. || (POS (value1) && NEG (value2) && NEG (result)))
  1399. flags |= V;
  1400. aarch64_set_CPSR (cpu, flags);
  1401. }
  1402. static void
  1403. set_flags_for_sub64 (sim_cpu *cpu, uint64_t value1, uint64_t value2)
  1404. {
  1405. uint64_t result = value1 - value2;
  1406. uint32_t flags = 0;
  1407. uint64_t signbit = 1ULL << 63;
  1408. if (result == 0)
  1409. flags |= Z;
  1410. if (NEG (result))
  1411. flags |= N;
  1412. if ( (NEG (value1) && POS (value2))
  1413. || (NEG (value1) && POS (result))
  1414. || (POS (value2) && POS (result)))
  1415. flags |= C;
  1416. if ( (NEG (value1) && POS (value2) && POS (result))
  1417. || (POS (value1) && NEG (value2) && NEG (result)))
  1418. flags |= V;
  1419. aarch64_set_CPSR (cpu, flags);
  1420. }
  1421. static void
  1422. set_flags_for_binop32 (sim_cpu *cpu, uint32_t result)
  1423. {
  1424. uint32_t flags = 0;
  1425. if (result == 0)
  1426. flags |= Z;
  1427. else
  1428. flags &= ~ Z;
  1429. if (result & (1 << 31))
  1430. flags |= N;
  1431. else
  1432. flags &= ~ N;
  1433. aarch64_set_CPSR (cpu, flags);
  1434. }
  1435. static void
  1436. set_flags_for_binop64 (sim_cpu *cpu, uint64_t result)
  1437. {
  1438. uint32_t flags = 0;
  1439. if (result == 0)
  1440. flags |= Z;
  1441. else
  1442. flags &= ~ Z;
  1443. if (result & (1ULL << 63))
  1444. flags |= N;
  1445. else
  1446. flags &= ~ N;
  1447. aarch64_set_CPSR (cpu, flags);
  1448. }
  1449. /* 32 bit add immediate set flags. */
  1450. static void
  1451. adds32 (sim_cpu *cpu, uint32_t aimm)
  1452. {
  1453. unsigned rn = INSTR (9, 5);
  1454. unsigned rd = INSTR (4, 0);
  1455. /* TODO : do we need to worry about signs here? */
  1456. int32_t value1 = aarch64_get_reg_s32 (cpu, rn, SP_OK);
  1457. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1458. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + aimm);
  1459. set_flags_for_add32 (cpu, value1, aimm);
  1460. }
  1461. /* 64 bit add immediate set flags. */
  1462. static void
  1463. adds64 (sim_cpu *cpu, uint32_t aimm)
  1464. {
  1465. unsigned rn = INSTR (9, 5);
  1466. unsigned rd = INSTR (4, 0);
  1467. uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1468. uint64_t value2 = aimm;
  1469. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1470. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2);
  1471. set_flags_for_add64 (cpu, value1, value2);
  1472. }
  1473. /* 32 bit sub immediate. */
  1474. static void
  1475. sub32 (sim_cpu *cpu, uint32_t aimm)
  1476. {
  1477. unsigned rn = INSTR (9, 5);
  1478. unsigned rd = INSTR (4, 0);
  1479. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1480. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  1481. aarch64_get_reg_u32 (cpu, rn, SP_OK) - aimm);
  1482. }
  1483. /* 64 bit sub immediate. */
  1484. static void
  1485. sub64 (sim_cpu *cpu, uint32_t aimm)
  1486. {
  1487. unsigned rn = INSTR (9, 5);
  1488. unsigned rd = INSTR (4, 0);
  1489. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1490. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  1491. aarch64_get_reg_u64 (cpu, rn, SP_OK) - aimm);
  1492. }
  1493. /* 32 bit sub immediate set flags. */
  1494. static void
  1495. subs32 (sim_cpu *cpu, uint32_t aimm)
  1496. {
  1497. unsigned rn = INSTR (9, 5);
  1498. unsigned rd = INSTR (4, 0);
  1499. uint32_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1500. uint32_t value2 = aimm;
  1501. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1502. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
  1503. set_flags_for_sub32 (cpu, value1, value2);
  1504. }
  1505. /* 64 bit sub immediate set flags. */
  1506. static void
  1507. subs64 (sim_cpu *cpu, uint32_t aimm)
  1508. {
  1509. unsigned rn = INSTR (9, 5);
  1510. unsigned rd = INSTR (4, 0);
  1511. uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1512. uint32_t value2 = aimm;
  1513. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1514. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
  1515. set_flags_for_sub64 (cpu, value1, value2);
  1516. }
  1517. /* Data Processing Register. */
  1518. /* First two helpers to perform the shift operations. */
  1519. static inline uint32_t
  1520. shifted32 (uint32_t value, Shift shift, uint32_t count)
  1521. {
  1522. switch (shift)
  1523. {
  1524. default:
  1525. case LSL:
  1526. return (value << count);
  1527. case LSR:
  1528. return (value >> count);
  1529. case ASR:
  1530. {
  1531. int32_t svalue = value;
  1532. return (svalue >> count);
  1533. }
  1534. case ROR:
  1535. {
  1536. uint32_t top = value >> count;
  1537. uint32_t bottom = value << (32 - count);
  1538. return (bottom | top);
  1539. }
  1540. }
  1541. }
  1542. static inline uint64_t
  1543. shifted64 (uint64_t value, Shift shift, uint32_t count)
  1544. {
  1545. switch (shift)
  1546. {
  1547. default:
  1548. case LSL:
  1549. return (value << count);
  1550. case LSR:
  1551. return (value >> count);
  1552. case ASR:
  1553. {
  1554. int64_t svalue = value;
  1555. return (svalue >> count);
  1556. }
  1557. case ROR:
  1558. {
  1559. uint64_t top = value >> count;
  1560. uint64_t bottom = value << (64 - count);
  1561. return (bottom | top);
  1562. }
  1563. }
  1564. }
  1565. /* Arithmetic shifted register.
  1566. These allow an optional LSL, ASR or LSR to the second source
  1567. register with a count up to the register bit count.
  1568. N.B register args may not be SP. */
  1569. /* 32 bit ADD shifted register. */
  1570. static void
  1571. add32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  1572. {
  1573. unsigned rm = INSTR (20, 16);
  1574. unsigned rn = INSTR (9, 5);
  1575. unsigned rd = INSTR (4, 0);
  1576. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1577. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  1578. aarch64_get_reg_u32 (cpu, rn, NO_SP)
  1579. + shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  1580. shift, count));
  1581. }
  1582. /* 64 bit ADD shifted register. */
  1583. static void
  1584. add64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  1585. {
  1586. unsigned rm = INSTR (20, 16);
  1587. unsigned rn = INSTR (9, 5);
  1588. unsigned rd = INSTR (4, 0);
  1589. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1590. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  1591. aarch64_get_reg_u64 (cpu, rn, NO_SP)
  1592. + shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
  1593. shift, count));
  1594. }
  1595. /* 32 bit ADD shifted register setting flags. */
  1596. static void
  1597. adds32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  1598. {
  1599. unsigned rm = INSTR (20, 16);
  1600. unsigned rn = INSTR (9, 5);
  1601. unsigned rd = INSTR (4, 0);
  1602. uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  1603. uint32_t value2 = shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  1604. shift, count);
  1605. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1606. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2);
  1607. set_flags_for_add32 (cpu, value1, value2);
  1608. }
  1609. /* 64 bit ADD shifted register setting flags. */
  1610. static void
  1611. adds64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  1612. {
  1613. unsigned rm = INSTR (20, 16);
  1614. unsigned rn = INSTR (9, 5);
  1615. unsigned rd = INSTR (4, 0);
  1616. uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  1617. uint64_t value2 = shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
  1618. shift, count);
  1619. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1620. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2);
  1621. set_flags_for_add64 (cpu, value1, value2);
  1622. }
  1623. /* 32 bit SUB shifted register. */
  1624. static void
  1625. sub32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  1626. {
  1627. unsigned rm = INSTR (20, 16);
  1628. unsigned rn = INSTR (9, 5);
  1629. unsigned rd = INSTR (4, 0);
  1630. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1631. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  1632. aarch64_get_reg_u32 (cpu, rn, NO_SP)
  1633. - shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  1634. shift, count));
  1635. }
  1636. /* 64 bit SUB shifted register. */
  1637. static void
  1638. sub64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  1639. {
  1640. unsigned rm = INSTR (20, 16);
  1641. unsigned rn = INSTR (9, 5);
  1642. unsigned rd = INSTR (4, 0);
  1643. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1644. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  1645. aarch64_get_reg_u64 (cpu, rn, NO_SP)
  1646. - shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
  1647. shift, count));
  1648. }
  1649. /* 32 bit SUB shifted register setting flags. */
  1650. static void
  1651. subs32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  1652. {
  1653. unsigned rm = INSTR (20, 16);
  1654. unsigned rn = INSTR (9, 5);
  1655. unsigned rd = INSTR (4, 0);
  1656. uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  1657. uint32_t value2 = shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  1658. shift, count);
  1659. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1660. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
  1661. set_flags_for_sub32 (cpu, value1, value2);
  1662. }
  1663. /* 64 bit SUB shifted register setting flags. */
  1664. static void
  1665. subs64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  1666. {
  1667. unsigned rm = INSTR (20, 16);
  1668. unsigned rn = INSTR (9, 5);
  1669. unsigned rd = INSTR (4, 0);
  1670. uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  1671. uint64_t value2 = shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
  1672. shift, count);
  1673. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1674. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
  1675. set_flags_for_sub64 (cpu, value1, value2);
  1676. }
  1677. /* First a couple more helpers to fetch the
  1678. relevant source register element either
  1679. sign or zero extended as required by the
  1680. extension value. */
  1681. static uint32_t
  1682. extreg32 (sim_cpu *cpu, unsigned int lo, Extension extension)
  1683. {
  1684. switch (extension)
  1685. {
  1686. case UXTB: return aarch64_get_reg_u8 (cpu, lo, NO_SP);
  1687. case UXTH: return aarch64_get_reg_u16 (cpu, lo, NO_SP);
  1688. case UXTW: /* Fall through. */
  1689. case UXTX: return aarch64_get_reg_u32 (cpu, lo, NO_SP);
  1690. case SXTB: return aarch64_get_reg_s8 (cpu, lo, NO_SP);
  1691. case SXTH: return aarch64_get_reg_s16 (cpu, lo, NO_SP);
  1692. case SXTW: /* Fall through. */
  1693. case SXTX: /* Fall through. */
  1694. default: return aarch64_get_reg_s32 (cpu, lo, NO_SP);
  1695. }
  1696. }
  1697. static uint64_t
  1698. extreg64 (sim_cpu *cpu, unsigned int lo, Extension extension)
  1699. {
  1700. switch (extension)
  1701. {
  1702. case UXTB: return aarch64_get_reg_u8 (cpu, lo, NO_SP);
  1703. case UXTH: return aarch64_get_reg_u16 (cpu, lo, NO_SP);
  1704. case UXTW: return aarch64_get_reg_u32 (cpu, lo, NO_SP);
  1705. case UXTX: return aarch64_get_reg_u64 (cpu, lo, NO_SP);
  1706. case SXTB: return aarch64_get_reg_s8 (cpu, lo, NO_SP);
  1707. case SXTH: return aarch64_get_reg_s16 (cpu, lo, NO_SP);
  1708. case SXTW: return aarch64_get_reg_s32 (cpu, lo, NO_SP);
  1709. case SXTX:
  1710. default: return aarch64_get_reg_s64 (cpu, lo, NO_SP);
  1711. }
  1712. }
  1713. /* Arithmetic extending register
  1714. These allow an optional sign extension of some portion of the
  1715. second source register followed by an optional left shift of
  1716. between 1 and 4 bits (i.e. a shift of 0-4 bits???)
  1717. N.B output (dest) and first input arg (source) may normally be Xn
  1718. or SP. However, for flag setting operations dest can only be
  1719. Xn. Second input registers are always Xn. */
  1720. /* 32 bit ADD extending register. */
  1721. static void
  1722. add32_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
  1723. {
  1724. unsigned rm = INSTR (20, 16);
  1725. unsigned rn = INSTR (9, 5);
  1726. unsigned rd = INSTR (4, 0);
  1727. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1728. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  1729. aarch64_get_reg_u32 (cpu, rn, SP_OK)
  1730. + (extreg32 (cpu, rm, extension) << shift));
  1731. }
  1732. /* 64 bit ADD extending register.
  1733. N.B. This subsumes the case with 64 bit source2 and UXTX #n or LSL #0. */
  1734. static void
  1735. add64_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
  1736. {
  1737. unsigned rm = INSTR (20, 16);
  1738. unsigned rn = INSTR (9, 5);
  1739. unsigned rd = INSTR (4, 0);
  1740. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1741. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  1742. aarch64_get_reg_u64 (cpu, rn, SP_OK)
  1743. + (extreg64 (cpu, rm, extension) << shift));
  1744. }
  1745. /* 32 bit ADD extending register setting flags. */
  1746. static void
  1747. adds32_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
  1748. {
  1749. unsigned rm = INSTR (20, 16);
  1750. unsigned rn = INSTR (9, 5);
  1751. unsigned rd = INSTR (4, 0);
  1752. uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, SP_OK);
  1753. uint32_t value2 = extreg32 (cpu, rm, extension) << shift;
  1754. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1755. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2);
  1756. set_flags_for_add32 (cpu, value1, value2);
  1757. }
  1758. /* 64 bit ADD extending register setting flags */
  1759. /* N.B. this subsumes the case with 64 bit source2 and UXTX #n or LSL #0 */
  1760. static void
  1761. adds64_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
  1762. {
  1763. unsigned rm = INSTR (20, 16);
  1764. unsigned rn = INSTR (9, 5);
  1765. unsigned rd = INSTR (4, 0);
  1766. uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1767. uint64_t value2 = extreg64 (cpu, rm, extension) << shift;
  1768. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1769. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2);
  1770. set_flags_for_add64 (cpu, value1, value2);
  1771. }
  1772. /* 32 bit SUB extending register. */
  1773. static void
  1774. sub32_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
  1775. {
  1776. unsigned rm = INSTR (20, 16);
  1777. unsigned rn = INSTR (9, 5);
  1778. unsigned rd = INSTR (4, 0);
  1779. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1780. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  1781. aarch64_get_reg_u32 (cpu, rn, SP_OK)
  1782. - (extreg32 (cpu, rm, extension) << shift));
  1783. }
  1784. /* 64 bit SUB extending register. */
  1785. /* N.B. this subsumes the case with 64 bit source2 and UXTX #n or LSL #0. */
  1786. static void
  1787. sub64_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
  1788. {
  1789. unsigned rm = INSTR (20, 16);
  1790. unsigned rn = INSTR (9, 5);
  1791. unsigned rd = INSTR (4, 0);
  1792. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1793. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  1794. aarch64_get_reg_u64 (cpu, rn, SP_OK)
  1795. - (extreg64 (cpu, rm, extension) << shift));
  1796. }
  1797. /* 32 bit SUB extending register setting flags. */
  1798. static void
  1799. subs32_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
  1800. {
  1801. unsigned rm = INSTR (20, 16);
  1802. unsigned rn = INSTR (9, 5);
  1803. unsigned rd = INSTR (4, 0);
  1804. uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, SP_OK);
  1805. uint32_t value2 = extreg32 (cpu, rm, extension) << shift;
  1806. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1807. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
  1808. set_flags_for_sub32 (cpu, value1, value2);
  1809. }
  1810. /* 64 bit SUB extending register setting flags */
  1811. /* N.B. this subsumes the case with 64 bit source2 and UXTX #n or LSL #0 */
  1812. static void
  1813. subs64_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
  1814. {
  1815. unsigned rm = INSTR (20, 16);
  1816. unsigned rn = INSTR (9, 5);
  1817. unsigned rd = INSTR (4, 0);
  1818. uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  1819. uint64_t value2 = extreg64 (cpu, rm, extension) << shift;
  1820. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1821. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
  1822. set_flags_for_sub64 (cpu, value1, value2);
  1823. }
  1824. static void
  1825. dexAddSubtractImmediate (sim_cpu *cpu)
  1826. {
  1827. /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  1828. instr[30] = op : 0 ==> ADD, 1 ==> SUB
  1829. instr[29] = set : 0 ==> no flags, 1 ==> set flags
  1830. instr[28,24] = 10001
  1831. instr[23,22] = shift : 00 == LSL#0, 01 = LSL#12 1x = UNALLOC
  1832. instr[21,10] = uimm12
  1833. instr[9,5] = Rn
  1834. instr[4,0] = Rd */
  1835. /* N.B. the shift is applied at decode before calling the add/sub routine. */
  1836. uint32_t shift = INSTR (23, 22);
  1837. uint32_t imm = INSTR (21, 10);
  1838. uint32_t dispatch = INSTR (31, 29);
  1839. NYI_assert (28, 24, 0x11);
  1840. if (shift > 1)
  1841. HALT_UNALLOC;
  1842. if (shift)
  1843. imm <<= 12;
  1844. switch (dispatch)
  1845. {
  1846. case 0: add32 (cpu, imm); break;
  1847. case 1: adds32 (cpu, imm); break;
  1848. case 2: sub32 (cpu, imm); break;
  1849. case 3: subs32 (cpu, imm); break;
  1850. case 4: add64 (cpu, imm); break;
  1851. case 5: adds64 (cpu, imm); break;
  1852. case 6: sub64 (cpu, imm); break;
  1853. case 7: subs64 (cpu, imm); break;
  1854. }
  1855. }
  1856. static void
  1857. dexAddSubtractShiftedRegister (sim_cpu *cpu)
  1858. {
  1859. /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  1860. instr[30,29] = op : 00 ==> ADD, 01 ==> ADDS, 10 ==> SUB, 11 ==> SUBS
  1861. instr[28,24] = 01011
  1862. instr[23,22] = shift : 0 ==> LSL, 1 ==> LSR, 2 ==> ASR, 3 ==> UNALLOC
  1863. instr[21] = 0
  1864. instr[20,16] = Rm
  1865. instr[15,10] = count : must be 0xxxxx for 32 bit
  1866. instr[9,5] = Rn
  1867. instr[4,0] = Rd */
  1868. uint32_t size = INSTR (31, 31);
  1869. uint32_t count = INSTR (15, 10);
  1870. Shift shiftType = INSTR (23, 22);
  1871. NYI_assert (28, 24, 0x0B);
  1872. NYI_assert (21, 21, 0);
  1873. /* Shift encoded as ROR is unallocated. */
  1874. if (shiftType == ROR)
  1875. HALT_UNALLOC;
  1876. /* 32 bit operations must have count[5] = 0
  1877. or else we have an UNALLOC. */
  1878. if (size == 0 && uimm (count, 5, 5))
  1879. HALT_UNALLOC;
  1880. /* Dispatch on size:op i.e instr [31,29]. */
  1881. switch (INSTR (31, 29))
  1882. {
  1883. case 0: add32_shift (cpu, shiftType, count); break;
  1884. case 1: adds32_shift (cpu, shiftType, count); break;
  1885. case 2: sub32_shift (cpu, shiftType, count); break;
  1886. case 3: subs32_shift (cpu, shiftType, count); break;
  1887. case 4: add64_shift (cpu, shiftType, count); break;
  1888. case 5: adds64_shift (cpu, shiftType, count); break;
  1889. case 6: sub64_shift (cpu, shiftType, count); break;
  1890. case 7: subs64_shift (cpu, shiftType, count); break;
  1891. }
  1892. }
  1893. static void
  1894. dexAddSubtractExtendedRegister (sim_cpu *cpu)
  1895. {
  1896. /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  1897. instr[30] = op : 0 ==> ADD, 1 ==> SUB
  1898. instr[29] = set? : 0 ==> no flags, 1 ==> set flags
  1899. instr[28,24] = 01011
  1900. instr[23,22] = opt : 0 ==> ok, 1,2,3 ==> UNALLOC
  1901. instr[21] = 1
  1902. instr[20,16] = Rm
  1903. instr[15,13] = option : 000 ==> UXTB, 001 ==> UXTH,
  1904. 000 ==> LSL|UXTW, 001 ==> UXTZ,
  1905. 000 ==> SXTB, 001 ==> SXTH,
  1906. 000 ==> SXTW, 001 ==> SXTX,
  1907. instr[12,10] = shift : 0,1,2,3,4 ==> ok, 5,6,7 ==> UNALLOC
  1908. instr[9,5] = Rn
  1909. instr[4,0] = Rd */
  1910. Extension extensionType = INSTR (15, 13);
  1911. uint32_t shift = INSTR (12, 10);
  1912. NYI_assert (28, 24, 0x0B);
  1913. NYI_assert (21, 21, 1);
  1914. /* Shift may not exceed 4. */
  1915. if (shift > 4)
  1916. HALT_UNALLOC;
  1917. /* Dispatch on size:op:set?. */
  1918. switch (INSTR (31, 29))
  1919. {
  1920. case 0: add32_ext (cpu, extensionType, shift); break;
  1921. case 1: adds32_ext (cpu, extensionType, shift); break;
  1922. case 2: sub32_ext (cpu, extensionType, shift); break;
  1923. case 3: subs32_ext (cpu, extensionType, shift); break;
  1924. case 4: add64_ext (cpu, extensionType, shift); break;
  1925. case 5: adds64_ext (cpu, extensionType, shift); break;
  1926. case 6: sub64_ext (cpu, extensionType, shift); break;
  1927. case 7: subs64_ext (cpu, extensionType, shift); break;
  1928. }
  1929. }
  1930. /* Conditional data processing
  1931. Condition register is implicit 3rd source. */
  1932. /* 32 bit add with carry. */
  1933. /* N.B register args may not be SP. */
  1934. static void
  1935. adc32 (sim_cpu *cpu)
  1936. {
  1937. unsigned rm = INSTR (20, 16);
  1938. unsigned rn = INSTR (9, 5);
  1939. unsigned rd = INSTR (4, 0);
  1940. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1941. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  1942. aarch64_get_reg_u32 (cpu, rn, NO_SP)
  1943. + aarch64_get_reg_u32 (cpu, rm, NO_SP)
  1944. + IS_SET (C));
  1945. }
  1946. /* 64 bit add with carry */
  1947. static void
  1948. adc64 (sim_cpu *cpu)
  1949. {
  1950. unsigned rm = INSTR (20, 16);
  1951. unsigned rn = INSTR (9, 5);
  1952. unsigned rd = INSTR (4, 0);
  1953. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1954. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  1955. aarch64_get_reg_u64 (cpu, rn, NO_SP)
  1956. + aarch64_get_reg_u64 (cpu, rm, NO_SP)
  1957. + IS_SET (C));
  1958. }
  1959. /* 32 bit add with carry setting flags. */
  1960. static void
  1961. adcs32 (sim_cpu *cpu)
  1962. {
  1963. unsigned rm = INSTR (20, 16);
  1964. unsigned rn = INSTR (9, 5);
  1965. unsigned rd = INSTR (4, 0);
  1966. uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  1967. uint32_t value2 = aarch64_get_reg_u32 (cpu, rm, NO_SP);
  1968. uint32_t carry = IS_SET (C);
  1969. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1970. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2 + carry);
  1971. set_flags_for_add32 (cpu, value1, value2 + carry);
  1972. }
  1973. /* 64 bit add with carry setting flags. */
  1974. static void
  1975. adcs64 (sim_cpu *cpu)
  1976. {
  1977. unsigned rm = INSTR (20, 16);
  1978. unsigned rn = INSTR (9, 5);
  1979. unsigned rd = INSTR (4, 0);
  1980. uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  1981. uint64_t value2 = aarch64_get_reg_u64 (cpu, rm, NO_SP);
  1982. uint64_t carry = IS_SET (C);
  1983. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1984. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2 + carry);
  1985. set_flags_for_add64 (cpu, value1, value2 + carry);
  1986. }
  1987. /* 32 bit sub with carry. */
  1988. static void
  1989. sbc32 (sim_cpu *cpu)
  1990. {
  1991. unsigned rm = INSTR (20, 16);
  1992. unsigned rn = INSTR (9, 5); /* ngc iff rn == 31. */
  1993. unsigned rd = INSTR (4, 0);
  1994. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  1995. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  1996. aarch64_get_reg_u32 (cpu, rn, NO_SP)
  1997. - aarch64_get_reg_u32 (cpu, rm, NO_SP)
  1998. - 1 + IS_SET (C));
  1999. }
  2000. /* 64 bit sub with carry */
  2001. static void
  2002. sbc64 (sim_cpu *cpu)
  2003. {
  2004. unsigned rm = INSTR (20, 16);
  2005. unsigned rn = INSTR (9, 5);
  2006. unsigned rd = INSTR (4, 0);
  2007. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2008. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  2009. aarch64_get_reg_u64 (cpu, rn, NO_SP)
  2010. - aarch64_get_reg_u64 (cpu, rm, NO_SP)
  2011. - 1 + IS_SET (C));
  2012. }
  2013. /* 32 bit sub with carry setting flags */
  2014. static void
  2015. sbcs32 (sim_cpu *cpu)
  2016. {
  2017. unsigned rm = INSTR (20, 16);
  2018. unsigned rn = INSTR (9, 5);
  2019. unsigned rd = INSTR (4, 0);
  2020. uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  2021. uint32_t value2 = aarch64_get_reg_u32 (cpu, rm, NO_SP);
  2022. uint32_t carry = IS_SET (C);
  2023. uint32_t result = value1 - value2 + 1 - carry;
  2024. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2025. aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
  2026. set_flags_for_sub32 (cpu, value1, value2 + 1 - carry);
  2027. }
  2028. /* 64 bit sub with carry setting flags */
  2029. static void
  2030. sbcs64 (sim_cpu *cpu)
  2031. {
  2032. unsigned rm = INSTR (20, 16);
  2033. unsigned rn = INSTR (9, 5);
  2034. unsigned rd = INSTR (4, 0);
  2035. uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  2036. uint64_t value2 = aarch64_get_reg_u64 (cpu, rm, NO_SP);
  2037. uint64_t carry = IS_SET (C);
  2038. uint64_t result = value1 - value2 + 1 - carry;
  2039. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2040. aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
  2041. set_flags_for_sub64 (cpu, value1, value2 + 1 - carry);
  2042. }
  2043. static void
  2044. dexAddSubtractWithCarry (sim_cpu *cpu)
  2045. {
  2046. /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  2047. instr[30] = op : 0 ==> ADC, 1 ==> SBC
  2048. instr[29] = set? : 0 ==> no flags, 1 ==> set flags
  2049. instr[28,21] = 1 1010 000
  2050. instr[20,16] = Rm
  2051. instr[15,10] = op2 : 00000 ==> ok, ow ==> UNALLOC
  2052. instr[9,5] = Rn
  2053. instr[4,0] = Rd */
  2054. uint32_t op2 = INSTR (15, 10);
  2055. NYI_assert (28, 21, 0xD0);
  2056. if (op2 != 0)
  2057. HALT_UNALLOC;
  2058. /* Dispatch on size:op:set?. */
  2059. switch (INSTR (31, 29))
  2060. {
  2061. case 0: adc32 (cpu); break;
  2062. case 1: adcs32 (cpu); break;
  2063. case 2: sbc32 (cpu); break;
  2064. case 3: sbcs32 (cpu); break;
  2065. case 4: adc64 (cpu); break;
  2066. case 5: adcs64 (cpu); break;
  2067. case 6: sbc64 (cpu); break;
  2068. case 7: sbcs64 (cpu); break;
  2069. }
  2070. }
  2071. static uint32_t
  2072. testConditionCode (sim_cpu *cpu, CondCode cc)
  2073. {
  2074. /* This should be reduceable to branchless logic
  2075. by some careful testing of bits in CC followed
  2076. by the requisite masking and combining of bits
  2077. from the flag register.
  2078. For now we do it with a switch. */
  2079. int res;
  2080. switch (cc)
  2081. {
  2082. case EQ: res = IS_SET (Z); break;
  2083. case NE: res = IS_CLEAR (Z); break;
  2084. case CS: res = IS_SET (C); break;
  2085. case CC: res = IS_CLEAR (C); break;
  2086. case MI: res = IS_SET (N); break;
  2087. case PL: res = IS_CLEAR (N); break;
  2088. case VS: res = IS_SET (V); break;
  2089. case VC: res = IS_CLEAR (V); break;
  2090. case HI: res = IS_SET (C) && IS_CLEAR (Z); break;
  2091. case LS: res = IS_CLEAR (C) || IS_SET (Z); break;
  2092. case GE: res = IS_SET (N) == IS_SET (V); break;
  2093. case LT: res = IS_SET (N) != IS_SET (V); break;
  2094. case GT: res = IS_CLEAR (Z) && (IS_SET (N) == IS_SET (V)); break;
  2095. case LE: res = IS_SET (Z) || (IS_SET (N) != IS_SET (V)); break;
  2096. case AL:
  2097. case NV:
  2098. default:
  2099. res = 1;
  2100. break;
  2101. }
  2102. return res;
  2103. }
  2104. static void
  2105. CondCompare (sim_cpu *cpu) /* aka: ccmp and ccmn */
  2106. {
  2107. /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  2108. instr[30] = compare with positive (1) or negative value (0)
  2109. instr[29,21] = 1 1101 0010
  2110. instr[20,16] = Rm or const
  2111. instr[15,12] = cond
  2112. instr[11] = compare reg (0) or const (1)
  2113. instr[10] = 0
  2114. instr[9,5] = Rn
  2115. instr[4] = 0
  2116. instr[3,0] = value for CPSR bits if the comparison does not take place. */
  2117. signed int negate;
  2118. unsigned rm;
  2119. unsigned rn;
  2120. NYI_assert (29, 21, 0x1d2);
  2121. NYI_assert (10, 10, 0);
  2122. NYI_assert (4, 4, 0);
  2123. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2124. if (! testConditionCode (cpu, INSTR (15, 12)))
  2125. {
  2126. aarch64_set_CPSR (cpu, INSTR (3, 0));
  2127. return;
  2128. }
  2129. negate = INSTR (30, 30) ? 1 : -1;
  2130. rm = INSTR (20, 16);
  2131. rn = INSTR ( 9, 5);
  2132. if (INSTR (31, 31))
  2133. {
  2134. if (INSTR (11, 11))
  2135. set_flags_for_sub64 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK),
  2136. negate * (uint64_t) rm);
  2137. else
  2138. set_flags_for_sub64 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK),
  2139. negate * aarch64_get_reg_u64 (cpu, rm, SP_OK));
  2140. }
  2141. else
  2142. {
  2143. if (INSTR (11, 11))
  2144. set_flags_for_sub32 (cpu, aarch64_get_reg_u32 (cpu, rn, SP_OK),
  2145. negate * rm);
  2146. else
  2147. set_flags_for_sub32 (cpu, aarch64_get_reg_u32 (cpu, rn, SP_OK),
  2148. negate * aarch64_get_reg_u32 (cpu, rm, SP_OK));
  2149. }
  2150. }
  2151. static void
  2152. do_vec_MOV_whole_vector (sim_cpu *cpu)
  2153. {
  2154. /* MOV Vd.T, Vs.T (alias for ORR Vd.T, Vn.T, Vm.T where Vn == Vm)
  2155. instr[31] = 0
  2156. instr[30] = half(0)/full(1)
  2157. instr[29,21] = 001110101
  2158. instr[20,16] = Vs
  2159. instr[15,10] = 000111
  2160. instr[9,5] = Vs
  2161. instr[4,0] = Vd */
  2162. unsigned vs = INSTR (9, 5);
  2163. unsigned vd = INSTR (4, 0);
  2164. NYI_assert (29, 21, 0x075);
  2165. NYI_assert (15, 10, 0x07);
  2166. if (INSTR (20, 16) != vs)
  2167. HALT_NYI;
  2168. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2169. if (INSTR (30, 30))
  2170. aarch64_set_vec_u64 (cpu, vd, 1, aarch64_get_vec_u64 (cpu, vs, 1));
  2171. aarch64_set_vec_u64 (cpu, vd, 0, aarch64_get_vec_u64 (cpu, vs, 0));
  2172. }
  2173. static void
  2174. do_vec_SMOV_into_scalar (sim_cpu *cpu)
  2175. {
  2176. /* instr[31] = 0
  2177. instr[30] = word(0)/long(1)
  2178. instr[29,21] = 00 1110 000
  2179. instr[20,16] = element size and index
  2180. instr[15,10] = 00 0010 11
  2181. instr[9,5] = V source
  2182. instr[4,0] = R dest */
  2183. unsigned vs = INSTR (9, 5);
  2184. unsigned rd = INSTR (4, 0);
  2185. unsigned imm5 = INSTR (20, 16);
  2186. unsigned full = INSTR (30, 30);
  2187. int size, index;
  2188. NYI_assert (29, 21, 0x070);
  2189. NYI_assert (15, 10, 0x0B);
  2190. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2191. if (imm5 & 0x1)
  2192. {
  2193. size = 0;
  2194. index = (imm5 >> 1) & 0xF;
  2195. }
  2196. else if (imm5 & 0x2)
  2197. {
  2198. size = 1;
  2199. index = (imm5 >> 2) & 0x7;
  2200. }
  2201. else if (full && (imm5 & 0x4))
  2202. {
  2203. size = 2;
  2204. index = (imm5 >> 3) & 0x3;
  2205. }
  2206. else
  2207. HALT_UNALLOC;
  2208. switch (size)
  2209. {
  2210. case 0:
  2211. if (full)
  2212. aarch64_set_reg_s64 (cpu, rd, NO_SP,
  2213. aarch64_get_vec_s8 (cpu, vs, index));
  2214. else
  2215. aarch64_set_reg_s32 (cpu, rd, NO_SP,
  2216. aarch64_get_vec_s8 (cpu, vs, index));
  2217. break;
  2218. case 1:
  2219. if (full)
  2220. aarch64_set_reg_s64 (cpu, rd, NO_SP,
  2221. aarch64_get_vec_s16 (cpu, vs, index));
  2222. else
  2223. aarch64_set_reg_s32 (cpu, rd, NO_SP,
  2224. aarch64_get_vec_s16 (cpu, vs, index));
  2225. break;
  2226. case 2:
  2227. aarch64_set_reg_s64 (cpu, rd, NO_SP,
  2228. aarch64_get_vec_s32 (cpu, vs, index));
  2229. break;
  2230. default:
  2231. HALT_UNALLOC;
  2232. }
  2233. }
  2234. static void
  2235. do_vec_UMOV_into_scalar (sim_cpu *cpu)
  2236. {
  2237. /* instr[31] = 0
  2238. instr[30] = word(0)/long(1)
  2239. instr[29,21] = 00 1110 000
  2240. instr[20,16] = element size and index
  2241. instr[15,10] = 00 0011 11
  2242. instr[9,5] = V source
  2243. instr[4,0] = R dest */
  2244. unsigned vs = INSTR (9, 5);
  2245. unsigned rd = INSTR (4, 0);
  2246. unsigned imm5 = INSTR (20, 16);
  2247. unsigned full = INSTR (30, 30);
  2248. int size, index;
  2249. NYI_assert (29, 21, 0x070);
  2250. NYI_assert (15, 10, 0x0F);
  2251. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2252. if (!full)
  2253. {
  2254. if (imm5 & 0x1)
  2255. {
  2256. size = 0;
  2257. index = (imm5 >> 1) & 0xF;
  2258. }
  2259. else if (imm5 & 0x2)
  2260. {
  2261. size = 1;
  2262. index = (imm5 >> 2) & 0x7;
  2263. }
  2264. else if (imm5 & 0x4)
  2265. {
  2266. size = 2;
  2267. index = (imm5 >> 3) & 0x3;
  2268. }
  2269. else
  2270. HALT_UNALLOC;
  2271. }
  2272. else if (imm5 & 0x8)
  2273. {
  2274. size = 3;
  2275. index = (imm5 >> 4) & 0x1;
  2276. }
  2277. else
  2278. HALT_UNALLOC;
  2279. switch (size)
  2280. {
  2281. case 0:
  2282. aarch64_set_reg_u32 (cpu, rd, NO_SP,
  2283. aarch64_get_vec_u8 (cpu, vs, index));
  2284. break;
  2285. case 1:
  2286. aarch64_set_reg_u32 (cpu, rd, NO_SP,
  2287. aarch64_get_vec_u16 (cpu, vs, index));
  2288. break;
  2289. case 2:
  2290. aarch64_set_reg_u32 (cpu, rd, NO_SP,
  2291. aarch64_get_vec_u32 (cpu, vs, index));
  2292. break;
  2293. case 3:
  2294. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  2295. aarch64_get_vec_u64 (cpu, vs, index));
  2296. break;
  2297. default:
  2298. HALT_UNALLOC;
  2299. }
  2300. }
  2301. static void
  2302. do_vec_INS (sim_cpu *cpu)
  2303. {
  2304. /* instr[31,21] = 01001110000
  2305. instr[20,16] = element size and index
  2306. instr[15,10] = 000111
  2307. instr[9,5] = W source
  2308. instr[4,0] = V dest */
  2309. int index;
  2310. unsigned rs = INSTR (9, 5);
  2311. unsigned vd = INSTR (4, 0);
  2312. NYI_assert (31, 21, 0x270);
  2313. NYI_assert (15, 10, 0x07);
  2314. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2315. if (INSTR (16, 16))
  2316. {
  2317. index = INSTR (20, 17);
  2318. aarch64_set_vec_u8 (cpu, vd, index,
  2319. aarch64_get_reg_u8 (cpu, rs, NO_SP));
  2320. }
  2321. else if (INSTR (17, 17))
  2322. {
  2323. index = INSTR (20, 18);
  2324. aarch64_set_vec_u16 (cpu, vd, index,
  2325. aarch64_get_reg_u16 (cpu, rs, NO_SP));
  2326. }
  2327. else if (INSTR (18, 18))
  2328. {
  2329. index = INSTR (20, 19);
  2330. aarch64_set_vec_u32 (cpu, vd, index,
  2331. aarch64_get_reg_u32 (cpu, rs, NO_SP));
  2332. }
  2333. else if (INSTR (19, 19))
  2334. {
  2335. index = INSTR (20, 20);
  2336. aarch64_set_vec_u64 (cpu, vd, index,
  2337. aarch64_get_reg_u64 (cpu, rs, NO_SP));
  2338. }
  2339. else
  2340. HALT_NYI;
  2341. }
  2342. static void
  2343. do_vec_DUP_vector_into_vector (sim_cpu *cpu)
  2344. {
  2345. /* instr[31] = 0
  2346. instr[30] = half(0)/full(1)
  2347. instr[29,21] = 00 1110 000
  2348. instr[20,16] = element size and index
  2349. instr[15,10] = 0000 01
  2350. instr[9,5] = V source
  2351. instr[4,0] = V dest. */
  2352. unsigned full = INSTR (30, 30);
  2353. unsigned vs = INSTR (9, 5);
  2354. unsigned vd = INSTR (4, 0);
  2355. int i, index;
  2356. NYI_assert (29, 21, 0x070);
  2357. NYI_assert (15, 10, 0x01);
  2358. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2359. if (INSTR (16, 16))
  2360. {
  2361. index = INSTR (20, 17);
  2362. for (i = 0; i < (full ? 16 : 8); i++)
  2363. aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u8 (cpu, vs, index));
  2364. }
  2365. else if (INSTR (17, 17))
  2366. {
  2367. index = INSTR (20, 18);
  2368. for (i = 0; i < (full ? 8 : 4); i++)
  2369. aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vs, index));
  2370. }
  2371. else if (INSTR (18, 18))
  2372. {
  2373. index = INSTR (20, 19);
  2374. for (i = 0; i < (full ? 4 : 2); i++)
  2375. aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vs, index));
  2376. }
  2377. else
  2378. {
  2379. if (INSTR (19, 19) == 0)
  2380. HALT_UNALLOC;
  2381. if (! full)
  2382. HALT_UNALLOC;
  2383. index = INSTR (20, 20);
  2384. for (i = 0; i < 2; i++)
  2385. aarch64_set_vec_u64 (cpu, vd, i, aarch64_get_vec_u64 (cpu, vs, index));
  2386. }
  2387. }
  2388. static void
  2389. do_vec_TBL (sim_cpu *cpu)
  2390. {
  2391. /* instr[31] = 0
  2392. instr[30] = half(0)/full(1)
  2393. instr[29,21] = 00 1110 000
  2394. instr[20,16] = Vm
  2395. instr[15] = 0
  2396. instr[14,13] = vec length
  2397. instr[12,10] = 000
  2398. instr[9,5] = V start
  2399. instr[4,0] = V dest */
  2400. int full = INSTR (30, 30);
  2401. int len = INSTR (14, 13) + 1;
  2402. unsigned vm = INSTR (20, 16);
  2403. unsigned vn = INSTR (9, 5);
  2404. unsigned vd = INSTR (4, 0);
  2405. unsigned i;
  2406. NYI_assert (29, 21, 0x070);
  2407. NYI_assert (12, 10, 0);
  2408. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2409. for (i = 0; i < (full ? 16 : 8); i++)
  2410. {
  2411. unsigned int selector = aarch64_get_vec_u8 (cpu, vm, i);
  2412. uint8_t val;
  2413. if (selector < 16)
  2414. val = aarch64_get_vec_u8 (cpu, vn, selector);
  2415. else if (selector < 32)
  2416. val = len < 2 ? 0 : aarch64_get_vec_u8 (cpu, vn + 1, selector - 16);
  2417. else if (selector < 48)
  2418. val = len < 3 ? 0 : aarch64_get_vec_u8 (cpu, vn + 2, selector - 32);
  2419. else if (selector < 64)
  2420. val = len < 4 ? 0 : aarch64_get_vec_u8 (cpu, vn + 3, selector - 48);
  2421. else
  2422. val = 0;
  2423. aarch64_set_vec_u8 (cpu, vd, i, val);
  2424. }
  2425. }
  2426. static void
  2427. do_vec_TRN (sim_cpu *cpu)
  2428. {
  2429. /* instr[31] = 0
  2430. instr[30] = half(0)/full(1)
  2431. instr[29,24] = 00 1110
  2432. instr[23,22] = size
  2433. instr[21] = 0
  2434. instr[20,16] = Vm
  2435. instr[15] = 0
  2436. instr[14] = TRN1 (0) / TRN2 (1)
  2437. instr[13,10] = 1010
  2438. instr[9,5] = V source
  2439. instr[4,0] = V dest. */
  2440. int full = INSTR (30, 30);
  2441. int second = INSTR (14, 14);
  2442. unsigned vm = INSTR (20, 16);
  2443. unsigned vn = INSTR (9, 5);
  2444. unsigned vd = INSTR (4, 0);
  2445. unsigned i;
  2446. NYI_assert (29, 24, 0x0E);
  2447. NYI_assert (13, 10, 0xA);
  2448. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2449. switch (INSTR (23, 22))
  2450. {
  2451. case 0:
  2452. for (i = 0; i < (full ? 8 : 4); i++)
  2453. {
  2454. aarch64_set_vec_u8
  2455. (cpu, vd, i * 2,
  2456. aarch64_get_vec_u8 (cpu, second ? vm : vn, i * 2));
  2457. aarch64_set_vec_u8
  2458. (cpu, vd, 1 * 2 + 1,
  2459. aarch64_get_vec_u8 (cpu, second ? vn : vm, i * 2 + 1));
  2460. }
  2461. break;
  2462. case 1:
  2463. for (i = 0; i < (full ? 4 : 2); i++)
  2464. {
  2465. aarch64_set_vec_u16
  2466. (cpu, vd, i * 2,
  2467. aarch64_get_vec_u16 (cpu, second ? vm : vn, i * 2));
  2468. aarch64_set_vec_u16
  2469. (cpu, vd, 1 * 2 + 1,
  2470. aarch64_get_vec_u16 (cpu, second ? vn : vm, i * 2 + 1));
  2471. }
  2472. break;
  2473. case 2:
  2474. aarch64_set_vec_u32
  2475. (cpu, vd, 0, aarch64_get_vec_u32 (cpu, second ? vm : vn, 0));
  2476. aarch64_set_vec_u32
  2477. (cpu, vd, 1, aarch64_get_vec_u32 (cpu, second ? vn : vm, 1));
  2478. aarch64_set_vec_u32
  2479. (cpu, vd, 2, aarch64_get_vec_u32 (cpu, second ? vm : vn, 2));
  2480. aarch64_set_vec_u32
  2481. (cpu, vd, 3, aarch64_get_vec_u32 (cpu, second ? vn : vm, 3));
  2482. break;
  2483. case 3:
  2484. if (! full)
  2485. HALT_UNALLOC;
  2486. aarch64_set_vec_u64 (cpu, vd, 0,
  2487. aarch64_get_vec_u64 (cpu, second ? vm : vn, 0));
  2488. aarch64_set_vec_u64 (cpu, vd, 1,
  2489. aarch64_get_vec_u64 (cpu, second ? vn : vm, 1));
  2490. break;
  2491. }
  2492. }
  2493. static void
  2494. do_vec_DUP_scalar_into_vector (sim_cpu *cpu)
  2495. {
  2496. /* instr[31] = 0
  2497. instr[30] = 0=> zero top 64-bits, 1=> duplicate into top 64-bits
  2498. [must be 1 for 64-bit xfer]
  2499. instr[29,20] = 00 1110 0000
  2500. instr[19,16] = element size: 0001=> 8-bits, 0010=> 16-bits,
  2501. 0100=> 32-bits. 1000=>64-bits
  2502. instr[15,10] = 0000 11
  2503. instr[9,5] = W source
  2504. instr[4,0] = V dest. */
  2505. unsigned i;
  2506. unsigned Vd = INSTR (4, 0);
  2507. unsigned Rs = INSTR (9, 5);
  2508. int both = INSTR (30, 30);
  2509. NYI_assert (29, 20, 0x0E0);
  2510. NYI_assert (15, 10, 0x03);
  2511. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2512. switch (INSTR (19, 16))
  2513. {
  2514. case 1:
  2515. for (i = 0; i < (both ? 16 : 8); i++)
  2516. aarch64_set_vec_u8 (cpu, Vd, i, aarch64_get_reg_u8 (cpu, Rs, NO_SP));
  2517. break;
  2518. case 2:
  2519. for (i = 0; i < (both ? 8 : 4); i++)
  2520. aarch64_set_vec_u16 (cpu, Vd, i, aarch64_get_reg_u16 (cpu, Rs, NO_SP));
  2521. break;
  2522. case 4:
  2523. for (i = 0; i < (both ? 4 : 2); i++)
  2524. aarch64_set_vec_u32 (cpu, Vd, i, aarch64_get_reg_u32 (cpu, Rs, NO_SP));
  2525. break;
  2526. case 8:
  2527. if (!both)
  2528. HALT_NYI;
  2529. aarch64_set_vec_u64 (cpu, Vd, 0, aarch64_get_reg_u64 (cpu, Rs, NO_SP));
  2530. aarch64_set_vec_u64 (cpu, Vd, 1, aarch64_get_reg_u64 (cpu, Rs, NO_SP));
  2531. break;
  2532. default:
  2533. HALT_NYI;
  2534. }
  2535. }
  2536. static void
  2537. do_vec_UZP (sim_cpu *cpu)
  2538. {
  2539. /* instr[31] = 0
  2540. instr[30] = half(0)/full(1)
  2541. instr[29,24] = 00 1110
  2542. instr[23,22] = size: byte(00), half(01), word (10), long (11)
  2543. instr[21] = 0
  2544. instr[20,16] = Vm
  2545. instr[15] = 0
  2546. instr[14] = lower (0) / upper (1)
  2547. instr[13,10] = 0110
  2548. instr[9,5] = Vn
  2549. instr[4,0] = Vd. */
  2550. int full = INSTR (30, 30);
  2551. int upper = INSTR (14, 14);
  2552. unsigned vm = INSTR (20, 16);
  2553. unsigned vn = INSTR (9, 5);
  2554. unsigned vd = INSTR (4, 0);
  2555. uint64_t val_m1 = aarch64_get_vec_u64 (cpu, vm, 0);
  2556. uint64_t val_m2 = aarch64_get_vec_u64 (cpu, vm, 1);
  2557. uint64_t val_n1 = aarch64_get_vec_u64 (cpu, vn, 0);
  2558. uint64_t val_n2 = aarch64_get_vec_u64 (cpu, vn, 1);
  2559. uint64_t val1;
  2560. uint64_t val2;
  2561. uint64_t input2 = full ? val_n2 : val_m1;
  2562. NYI_assert (29, 24, 0x0E);
  2563. NYI_assert (21, 21, 0);
  2564. NYI_assert (15, 15, 0);
  2565. NYI_assert (13, 10, 6);
  2566. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2567. switch (INSTR (23, 22))
  2568. {
  2569. case 0:
  2570. val1 = (val_n1 >> (upper * 8)) & 0xFFULL;
  2571. val1 |= (val_n1 >> ((upper * 8) + 8)) & 0xFF00ULL;
  2572. val1 |= (val_n1 >> ((upper * 8) + 16)) & 0xFF0000ULL;
  2573. val1 |= (val_n1 >> ((upper * 8) + 24)) & 0xFF000000ULL;
  2574. val1 |= (input2 << (32 - (upper * 8))) & 0xFF00000000ULL;
  2575. val1 |= (input2 << (24 - (upper * 8))) & 0xFF0000000000ULL;
  2576. val1 |= (input2 << (16 - (upper * 8))) & 0xFF000000000000ULL;
  2577. val1 |= (input2 << (8 - (upper * 8))) & 0xFF00000000000000ULL;
  2578. if (full)
  2579. {
  2580. val2 = (val_m1 >> (upper * 8)) & 0xFFULL;
  2581. val2 |= (val_m1 >> ((upper * 8) + 8)) & 0xFF00ULL;
  2582. val2 |= (val_m1 >> ((upper * 8) + 16)) & 0xFF0000ULL;
  2583. val2 |= (val_m1 >> ((upper * 8) + 24)) & 0xFF000000ULL;
  2584. val2 |= (val_m2 << (32 - (upper * 8))) & 0xFF00000000ULL;
  2585. val2 |= (val_m2 << (24 - (upper * 8))) & 0xFF0000000000ULL;
  2586. val2 |= (val_m2 << (16 - (upper * 8))) & 0xFF000000000000ULL;
  2587. val2 |= (val_m2 << (8 - (upper * 8))) & 0xFF00000000000000ULL;
  2588. }
  2589. break;
  2590. case 1:
  2591. val1 = (val_n1 >> (upper * 16)) & 0xFFFFULL;
  2592. val1 |= (val_n1 >> ((upper * 16) + 16)) & 0xFFFF0000ULL;
  2593. val1 |= (input2 << (32 - (upper * 16))) & 0xFFFF00000000ULL;;
  2594. val1 |= (input2 << (16 - (upper * 16))) & 0xFFFF000000000000ULL;
  2595. if (full)
  2596. {
  2597. val2 = (val_m1 >> (upper * 16)) & 0xFFFFULL;
  2598. val2 |= (val_m1 >> ((upper * 16) + 16)) & 0xFFFF0000ULL;
  2599. val2 |= (val_m2 << (32 - (upper * 16))) & 0xFFFF00000000ULL;
  2600. val2 |= (val_m2 << (16 - (upper * 16))) & 0xFFFF000000000000ULL;
  2601. }
  2602. break;
  2603. case 2:
  2604. val1 = (val_n1 >> (upper * 32)) & 0xFFFFFFFF;
  2605. val1 |= (input2 << (32 - (upper * 32))) & 0xFFFFFFFF00000000ULL;
  2606. if (full)
  2607. {
  2608. val2 = (val_m1 >> (upper * 32)) & 0xFFFFFFFF;
  2609. val2 |= (val_m2 << (32 - (upper * 32))) & 0xFFFFFFFF00000000ULL;
  2610. }
  2611. break;
  2612. case 3:
  2613. if (! full)
  2614. HALT_UNALLOC;
  2615. val1 = upper ? val_n2 : val_n1;
  2616. val2 = upper ? val_m2 : val_m1;
  2617. break;
  2618. }
  2619. aarch64_set_vec_u64 (cpu, vd, 0, val1);
  2620. if (full)
  2621. aarch64_set_vec_u64 (cpu, vd, 1, val2);
  2622. }
  2623. static void
  2624. do_vec_ZIP (sim_cpu *cpu)
  2625. {
  2626. /* instr[31] = 0
  2627. instr[30] = half(0)/full(1)
  2628. instr[29,24] = 00 1110
  2629. instr[23,22] = size: byte(00), hald(01), word (10), long (11)
  2630. instr[21] = 0
  2631. instr[20,16] = Vm
  2632. instr[15] = 0
  2633. instr[14] = lower (0) / upper (1)
  2634. instr[13,10] = 1110
  2635. instr[9,5] = Vn
  2636. instr[4,0] = Vd. */
  2637. int full = INSTR (30, 30);
  2638. int upper = INSTR (14, 14);
  2639. unsigned vm = INSTR (20, 16);
  2640. unsigned vn = INSTR (9, 5);
  2641. unsigned vd = INSTR (4, 0);
  2642. uint64_t val_m1 = aarch64_get_vec_u64 (cpu, vm, 0);
  2643. uint64_t val_m2 = aarch64_get_vec_u64 (cpu, vm, 1);
  2644. uint64_t val_n1 = aarch64_get_vec_u64 (cpu, vn, 0);
  2645. uint64_t val_n2 = aarch64_get_vec_u64 (cpu, vn, 1);
  2646. uint64_t val1 = 0;
  2647. uint64_t val2 = 0;
  2648. uint64_t input1 = upper ? val_n1 : val_m1;
  2649. uint64_t input2 = upper ? val_n2 : val_m2;
  2650. NYI_assert (29, 24, 0x0E);
  2651. NYI_assert (21, 21, 0);
  2652. NYI_assert (15, 15, 0);
  2653. NYI_assert (13, 10, 0xE);
  2654. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2655. switch (INSTR (23, 23))
  2656. {
  2657. case 0:
  2658. val1 =
  2659. ((input1 << 0) & (0xFF << 0))
  2660. | ((input2 << 8) & (0xFF << 8))
  2661. | ((input1 << 8) & (0xFF << 16))
  2662. | ((input2 << 16) & (0xFF << 24))
  2663. | ((input1 << 16) & (0xFFULL << 32))
  2664. | ((input2 << 24) & (0xFFULL << 40))
  2665. | ((input1 << 24) & (0xFFULL << 48))
  2666. | ((input2 << 32) & (0xFFULL << 56));
  2667. val2 =
  2668. ((input1 >> 32) & (0xFF << 0))
  2669. | ((input2 >> 24) & (0xFF << 8))
  2670. | ((input1 >> 24) & (0xFF << 16))
  2671. | ((input2 >> 16) & (0xFF << 24))
  2672. | ((input1 >> 16) & (0xFFULL << 32))
  2673. | ((input2 >> 8) & (0xFFULL << 40))
  2674. | ((input1 >> 8) & (0xFFULL << 48))
  2675. | ((input2 >> 0) & (0xFFULL << 56));
  2676. break;
  2677. case 1:
  2678. val1 =
  2679. ((input1 << 0) & (0xFFFF << 0))
  2680. | ((input2 << 16) & (0xFFFF << 16))
  2681. | ((input1 << 16) & (0xFFFFULL << 32))
  2682. | ((input2 << 32) & (0xFFFFULL << 48));
  2683. val2 =
  2684. ((input1 >> 32) & (0xFFFF << 0))
  2685. | ((input2 >> 16) & (0xFFFF << 16))
  2686. | ((input1 >> 16) & (0xFFFFULL << 32))
  2687. | ((input2 >> 0) & (0xFFFFULL << 48));
  2688. break;
  2689. case 2:
  2690. val1 = (input1 & 0xFFFFFFFFULL) | (input2 << 32);
  2691. val2 = (input2 & 0xFFFFFFFFULL) | (input1 << 32);
  2692. break;
  2693. case 3:
  2694. val1 = input1;
  2695. val2 = input2;
  2696. break;
  2697. }
  2698. aarch64_set_vec_u64 (cpu, vd, 0, val1);
  2699. if (full)
  2700. aarch64_set_vec_u64 (cpu, vd, 1, val2);
  2701. }
  2702. /* Floating point immediates are encoded in 8 bits.
  2703. fpimm[7] = sign bit.
  2704. fpimm[6:4] = signed exponent.
  2705. fpimm[3:0] = fraction (assuming leading 1).
  2706. i.e. F = s * 1.f * 2^(e - b). */
  2707. static float
  2708. fp_immediate_for_encoding_32 (uint32_t imm8)
  2709. {
  2710. float u;
  2711. uint32_t s, e, f, i;
  2712. s = (imm8 >> 7) & 0x1;
  2713. e = (imm8 >> 4) & 0x7;
  2714. f = imm8 & 0xf;
  2715. /* The fp value is s * n/16 * 2r where n is 16+e. */
  2716. u = (16.0 + f) / 16.0;
  2717. /* N.B. exponent is signed. */
  2718. if (e < 4)
  2719. {
  2720. int epos = e;
  2721. for (i = 0; i <= epos; i++)
  2722. u *= 2.0;
  2723. }
  2724. else
  2725. {
  2726. int eneg = 7 - e;
  2727. for (i = 0; i < eneg; i++)
  2728. u /= 2.0;
  2729. }
  2730. if (s)
  2731. u = - u;
  2732. return u;
  2733. }
  2734. static double
  2735. fp_immediate_for_encoding_64 (uint32_t imm8)
  2736. {
  2737. double u;
  2738. uint32_t s, e, f, i;
  2739. s = (imm8 >> 7) & 0x1;
  2740. e = (imm8 >> 4) & 0x7;
  2741. f = imm8 & 0xf;
  2742. /* The fp value is s * n/16 * 2r where n is 16+e. */
  2743. u = (16.0 + f) / 16.0;
  2744. /* N.B. exponent is signed. */
  2745. if (e < 4)
  2746. {
  2747. int epos = e;
  2748. for (i = 0; i <= epos; i++)
  2749. u *= 2.0;
  2750. }
  2751. else
  2752. {
  2753. int eneg = 7 - e;
  2754. for (i = 0; i < eneg; i++)
  2755. u /= 2.0;
  2756. }
  2757. if (s)
  2758. u = - u;
  2759. return u;
  2760. }
  2761. static void
  2762. do_vec_MOV_immediate (sim_cpu *cpu)
  2763. {
  2764. /* instr[31] = 0
  2765. instr[30] = full/half selector
  2766. instr[29,19] = 00111100000
  2767. instr[18,16] = high 3 bits of uimm8
  2768. instr[15,12] = size & shift:
  2769. 0000 => 32-bit
  2770. 0010 => 32-bit + LSL#8
  2771. 0100 => 32-bit + LSL#16
  2772. 0110 => 32-bit + LSL#24
  2773. 1010 => 16-bit + LSL#8
  2774. 1000 => 16-bit
  2775. 1101 => 32-bit + MSL#16
  2776. 1100 => 32-bit + MSL#8
  2777. 1110 => 8-bit
  2778. 1111 => double
  2779. instr[11,10] = 01
  2780. instr[9,5] = low 5-bits of uimm8
  2781. instr[4,0] = Vd. */
  2782. int full = INSTR (30, 30);
  2783. unsigned vd = INSTR (4, 0);
  2784. unsigned val = (INSTR (18, 16) << 5) | INSTR (9, 5);
  2785. unsigned i;
  2786. NYI_assert (29, 19, 0x1E0);
  2787. NYI_assert (11, 10, 1);
  2788. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2789. switch (INSTR (15, 12))
  2790. {
  2791. case 0x0: /* 32-bit, no shift. */
  2792. case 0x2: /* 32-bit, shift by 8. */
  2793. case 0x4: /* 32-bit, shift by 16. */
  2794. case 0x6: /* 32-bit, shift by 24. */
  2795. val <<= (8 * INSTR (14, 13));
  2796. for (i = 0; i < (full ? 4 : 2); i++)
  2797. aarch64_set_vec_u32 (cpu, vd, i, val);
  2798. break;
  2799. case 0xa: /* 16-bit, shift by 8. */
  2800. val <<= 8;
  2801. /* Fall through. */
  2802. case 0x8: /* 16-bit, no shift. */
  2803. for (i = 0; i < (full ? 8 : 4); i++)
  2804. aarch64_set_vec_u16 (cpu, vd, i, val);
  2805. break;
  2806. case 0xd: /* 32-bit, mask shift by 16. */
  2807. val <<= 8;
  2808. val |= 0xFF;
  2809. /* Fall through. */
  2810. case 0xc: /* 32-bit, mask shift by 8. */
  2811. val <<= 8;
  2812. val |= 0xFF;
  2813. for (i = 0; i < (full ? 4 : 2); i++)
  2814. aarch64_set_vec_u32 (cpu, vd, i, val);
  2815. break;
  2816. case 0xe: /* 8-bit, no shift. */
  2817. for (i = 0; i < (full ? 16 : 8); i++)
  2818. aarch64_set_vec_u8 (cpu, vd, i, val);
  2819. break;
  2820. case 0xf: /* FMOV Vs.{2|4}S, #fpimm. */
  2821. {
  2822. float u = fp_immediate_for_encoding_32 (val);
  2823. for (i = 0; i < (full ? 4 : 2); i++)
  2824. aarch64_set_vec_float (cpu, vd, i, u);
  2825. break;
  2826. }
  2827. default:
  2828. HALT_NYI;
  2829. }
  2830. }
  2831. static void
  2832. do_vec_MVNI (sim_cpu *cpu)
  2833. {
  2834. /* instr[31] = 0
  2835. instr[30] = full/half selector
  2836. instr[29,19] = 10111100000
  2837. instr[18,16] = high 3 bits of uimm8
  2838. instr[15,12] = selector
  2839. instr[11,10] = 01
  2840. instr[9,5] = low 5-bits of uimm8
  2841. instr[4,0] = Vd. */
  2842. int full = INSTR (30, 30);
  2843. unsigned vd = INSTR (4, 0);
  2844. unsigned val = (INSTR (18, 16) << 5) | INSTR (9, 5);
  2845. unsigned i;
  2846. NYI_assert (29, 19, 0x5E0);
  2847. NYI_assert (11, 10, 1);
  2848. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2849. switch (INSTR (15, 12))
  2850. {
  2851. case 0x0: /* 32-bit, no shift. */
  2852. case 0x2: /* 32-bit, shift by 8. */
  2853. case 0x4: /* 32-bit, shift by 16. */
  2854. case 0x6: /* 32-bit, shift by 24. */
  2855. val <<= (8 * INSTR (14, 13));
  2856. val = ~ val;
  2857. for (i = 0; i < (full ? 4 : 2); i++)
  2858. aarch64_set_vec_u32 (cpu, vd, i, val);
  2859. return;
  2860. case 0xa: /* 16-bit, 8 bit shift. */
  2861. val <<= 8;
  2862. case 0x8: /* 16-bit, no shift. */
  2863. val = ~ val;
  2864. for (i = 0; i < (full ? 8 : 4); i++)
  2865. aarch64_set_vec_u16 (cpu, vd, i, val);
  2866. return;
  2867. case 0xd: /* 32-bit, mask shift by 16. */
  2868. val <<= 8;
  2869. val |= 0xFF;
  2870. case 0xc: /* 32-bit, mask shift by 8. */
  2871. val <<= 8;
  2872. val |= 0xFF;
  2873. val = ~ val;
  2874. for (i = 0; i < (full ? 4 : 2); i++)
  2875. aarch64_set_vec_u32 (cpu, vd, i, val);
  2876. return;
  2877. case 0xE: /* MOVI Dn, #mask64 */
  2878. {
  2879. uint64_t mask = 0;
  2880. for (i = 0; i < 8; i++)
  2881. if (val & (1 << i))
  2882. mask |= (0xFFUL << (i * 8));
  2883. aarch64_set_vec_u64 (cpu, vd, 0, mask);
  2884. aarch64_set_vec_u64 (cpu, vd, 1, mask);
  2885. return;
  2886. }
  2887. case 0xf: /* FMOV Vd.2D, #fpimm. */
  2888. {
  2889. double u = fp_immediate_for_encoding_64 (val);
  2890. if (! full)
  2891. HALT_UNALLOC;
  2892. aarch64_set_vec_double (cpu, vd, 0, u);
  2893. aarch64_set_vec_double (cpu, vd, 1, u);
  2894. return;
  2895. }
  2896. default:
  2897. HALT_NYI;
  2898. }
  2899. }
  2900. #define ABS(A) ((A) < 0 ? - (A) : (A))
  2901. static void
  2902. do_vec_ABS (sim_cpu *cpu)
  2903. {
  2904. /* instr[31] = 0
  2905. instr[30] = half(0)/full(1)
  2906. instr[29,24] = 00 1110
  2907. instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit, 11=> 64-bit
  2908. instr[21,10] = 10 0000 1011 10
  2909. instr[9,5] = Vn
  2910. instr[4.0] = Vd. */
  2911. unsigned vn = INSTR (9, 5);
  2912. unsigned vd = INSTR (4, 0);
  2913. unsigned full = INSTR (30, 30);
  2914. unsigned i;
  2915. NYI_assert (29, 24, 0x0E);
  2916. NYI_assert (21, 10, 0x82E);
  2917. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2918. switch (INSTR (23, 22))
  2919. {
  2920. case 0:
  2921. for (i = 0; i < (full ? 16 : 8); i++)
  2922. aarch64_set_vec_s8 (cpu, vd, i,
  2923. ABS (aarch64_get_vec_s8 (cpu, vn, i)));
  2924. break;
  2925. case 1:
  2926. for (i = 0; i < (full ? 8 : 4); i++)
  2927. aarch64_set_vec_s16 (cpu, vd, i,
  2928. ABS (aarch64_get_vec_s16 (cpu, vn, i)));
  2929. break;
  2930. case 2:
  2931. for (i = 0; i < (full ? 4 : 2); i++)
  2932. aarch64_set_vec_s32 (cpu, vd, i,
  2933. ABS (aarch64_get_vec_s32 (cpu, vn, i)));
  2934. break;
  2935. case 3:
  2936. if (! full)
  2937. HALT_NYI;
  2938. for (i = 0; i < 2; i++)
  2939. aarch64_set_vec_s64 (cpu, vd, i,
  2940. ABS (aarch64_get_vec_s64 (cpu, vn, i)));
  2941. break;
  2942. }
  2943. }
  2944. static void
  2945. do_vec_ADDV (sim_cpu *cpu)
  2946. {
  2947. /* instr[31] = 0
  2948. instr[30] = full/half selector
  2949. instr[29,24] = 00 1110
  2950. instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit, 11=> 64-bit
  2951. instr[21,10] = 11 0001 1011 10
  2952. instr[9,5] = Vm
  2953. instr[4.0] = Rd. */
  2954. unsigned vm = INSTR (9, 5);
  2955. unsigned rd = INSTR (4, 0);
  2956. unsigned i;
  2957. int full = INSTR (30, 30);
  2958. NYI_assert (29, 24, 0x0E);
  2959. NYI_assert (21, 10, 0xC6E);
  2960. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  2961. switch (INSTR (23, 22))
  2962. {
  2963. case 0:
  2964. {
  2965. uint8_t val = 0;
  2966. for (i = 0; i < (full ? 16 : 8); i++)
  2967. val += aarch64_get_vec_u8 (cpu, vm, i);
  2968. aarch64_set_vec_u64 (cpu, rd, 0, val);
  2969. return;
  2970. }
  2971. case 1:
  2972. {
  2973. uint16_t val = 0;
  2974. for (i = 0; i < (full ? 8 : 4); i++)
  2975. val += aarch64_get_vec_u16 (cpu, vm, i);
  2976. aarch64_set_vec_u64 (cpu, rd, 0, val);
  2977. return;
  2978. }
  2979. case 2:
  2980. {
  2981. uint32_t val = 0;
  2982. if (! full)
  2983. HALT_UNALLOC;
  2984. for (i = 0; i < 4; i++)
  2985. val += aarch64_get_vec_u32 (cpu, vm, i);
  2986. aarch64_set_vec_u64 (cpu, rd, 0, val);
  2987. return;
  2988. }
  2989. case 3:
  2990. HALT_UNALLOC;
  2991. }
  2992. }
  2993. static void
  2994. do_vec_ins_2 (sim_cpu *cpu)
  2995. {
  2996. /* instr[31,21] = 01001110000
  2997. instr[20,18] = size & element selector
  2998. instr[17,14] = 0000
  2999. instr[13] = direction: to vec(0), from vec (1)
  3000. instr[12,10] = 111
  3001. instr[9,5] = Vm
  3002. instr[4,0] = Vd. */
  3003. unsigned elem;
  3004. unsigned vm = INSTR (9, 5);
  3005. unsigned vd = INSTR (4, 0);
  3006. NYI_assert (31, 21, 0x270);
  3007. NYI_assert (17, 14, 0);
  3008. NYI_assert (12, 10, 7);
  3009. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3010. if (INSTR (13, 13) == 1)
  3011. {
  3012. if (INSTR (18, 18) == 1)
  3013. {
  3014. /* 32-bit moves. */
  3015. elem = INSTR (20, 19);
  3016. aarch64_set_reg_u64 (cpu, vd, NO_SP,
  3017. aarch64_get_vec_u32 (cpu, vm, elem));
  3018. }
  3019. else
  3020. {
  3021. /* 64-bit moves. */
  3022. if (INSTR (19, 19) != 1)
  3023. HALT_NYI;
  3024. elem = INSTR (20, 20);
  3025. aarch64_set_reg_u64 (cpu, vd, NO_SP,
  3026. aarch64_get_vec_u64 (cpu, vm, elem));
  3027. }
  3028. }
  3029. else
  3030. {
  3031. if (INSTR (18, 18) == 1)
  3032. {
  3033. /* 32-bit moves. */
  3034. elem = INSTR (20, 19);
  3035. aarch64_set_vec_u32 (cpu, vd, elem,
  3036. aarch64_get_reg_u32 (cpu, vm, NO_SP));
  3037. }
  3038. else
  3039. {
  3040. /* 64-bit moves. */
  3041. if (INSTR (19, 19) != 1)
  3042. HALT_NYI;
  3043. elem = INSTR (20, 20);
  3044. aarch64_set_vec_u64 (cpu, vd, elem,
  3045. aarch64_get_reg_u64 (cpu, vm, NO_SP));
  3046. }
  3047. }
  3048. }
  3049. #define DO_VEC_WIDENING_MUL(N, DST_TYPE, READ_TYPE, WRITE_TYPE) \
  3050. do \
  3051. { \
  3052. DST_TYPE a[N], b[N]; \
  3053. \
  3054. for (i = 0; i < (N); i++) \
  3055. { \
  3056. a[i] = aarch64_get_vec_##READ_TYPE (cpu, vn, i + bias); \
  3057. b[i] = aarch64_get_vec_##READ_TYPE (cpu, vm, i + bias); \
  3058. } \
  3059. for (i = 0; i < (N); i++) \
  3060. aarch64_set_vec_##WRITE_TYPE (cpu, vd, i, a[i] * b[i]); \
  3061. } \
  3062. while (0)
  3063. static void
  3064. do_vec_mull (sim_cpu *cpu)
  3065. {
  3066. /* instr[31] = 0
  3067. instr[30] = lower(0)/upper(1) selector
  3068. instr[29] = signed(0)/unsigned(1)
  3069. instr[28,24] = 0 1110
  3070. instr[23,22] = size: 8-bit (00), 16-bit (01), 32-bit (10)
  3071. instr[21] = 1
  3072. instr[20,16] = Vm
  3073. instr[15,10] = 11 0000
  3074. instr[9,5] = Vn
  3075. instr[4.0] = Vd. */
  3076. int unsign = INSTR (29, 29);
  3077. int bias = INSTR (30, 30);
  3078. unsigned vm = INSTR (20, 16);
  3079. unsigned vn = INSTR ( 9, 5);
  3080. unsigned vd = INSTR ( 4, 0);
  3081. unsigned i;
  3082. NYI_assert (28, 24, 0x0E);
  3083. NYI_assert (15, 10, 0x30);
  3084. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3085. /* NB: Read source values before writing results, in case
  3086. the source and destination vectors are the same. */
  3087. switch (INSTR (23, 22))
  3088. {
  3089. case 0:
  3090. if (bias)
  3091. bias = 8;
  3092. if (unsign)
  3093. DO_VEC_WIDENING_MUL (8, uint16_t, u8, u16);
  3094. else
  3095. DO_VEC_WIDENING_MUL (8, int16_t, s8, s16);
  3096. return;
  3097. case 1:
  3098. if (bias)
  3099. bias = 4;
  3100. if (unsign)
  3101. DO_VEC_WIDENING_MUL (4, uint32_t, u16, u32);
  3102. else
  3103. DO_VEC_WIDENING_MUL (4, int32_t, s16, s32);
  3104. return;
  3105. case 2:
  3106. if (bias)
  3107. bias = 2;
  3108. if (unsign)
  3109. DO_VEC_WIDENING_MUL (2, uint64_t, u32, u64);
  3110. else
  3111. DO_VEC_WIDENING_MUL (2, int64_t, s32, s64);
  3112. return;
  3113. case 3:
  3114. HALT_NYI;
  3115. }
  3116. }
  3117. static void
  3118. do_vec_fadd (sim_cpu *cpu)
  3119. {
  3120. /* instr[31] = 0
  3121. instr[30] = half(0)/full(1)
  3122. instr[29,24] = 001110
  3123. instr[23] = FADD(0)/FSUB(1)
  3124. instr[22] = float (0)/double(1)
  3125. instr[21] = 1
  3126. instr[20,16] = Vm
  3127. instr[15,10] = 110101
  3128. instr[9,5] = Vn
  3129. instr[4.0] = Vd. */
  3130. unsigned vm = INSTR (20, 16);
  3131. unsigned vn = INSTR (9, 5);
  3132. unsigned vd = INSTR (4, 0);
  3133. unsigned i;
  3134. int full = INSTR (30, 30);
  3135. NYI_assert (29, 24, 0x0E);
  3136. NYI_assert (21, 21, 1);
  3137. NYI_assert (15, 10, 0x35);
  3138. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3139. if (INSTR (23, 23))
  3140. {
  3141. if (INSTR (22, 22))
  3142. {
  3143. if (! full)
  3144. HALT_NYI;
  3145. for (i = 0; i < 2; i++)
  3146. aarch64_set_vec_double (cpu, vd, i,
  3147. aarch64_get_vec_double (cpu, vn, i)
  3148. - aarch64_get_vec_double (cpu, vm, i));
  3149. }
  3150. else
  3151. {
  3152. for (i = 0; i < (full ? 4 : 2); i++)
  3153. aarch64_set_vec_float (cpu, vd, i,
  3154. aarch64_get_vec_float (cpu, vn, i)
  3155. - aarch64_get_vec_float (cpu, vm, i));
  3156. }
  3157. }
  3158. else
  3159. {
  3160. if (INSTR (22, 22))
  3161. {
  3162. if (! full)
  3163. HALT_NYI;
  3164. for (i = 0; i < 2; i++)
  3165. aarch64_set_vec_double (cpu, vd, i,
  3166. aarch64_get_vec_double (cpu, vm, i)
  3167. + aarch64_get_vec_double (cpu, vn, i));
  3168. }
  3169. else
  3170. {
  3171. for (i = 0; i < (full ? 4 : 2); i++)
  3172. aarch64_set_vec_float (cpu, vd, i,
  3173. aarch64_get_vec_float (cpu, vm, i)
  3174. + aarch64_get_vec_float (cpu, vn, i));
  3175. }
  3176. }
  3177. }
  3178. static void
  3179. do_vec_add (sim_cpu *cpu)
  3180. {
  3181. /* instr[31] = 0
  3182. instr[30] = full/half selector
  3183. instr[29,24] = 001110
  3184. instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit, 11=> 64-bit
  3185. instr[21] = 1
  3186. instr[20,16] = Vn
  3187. instr[15,10] = 100001
  3188. instr[9,5] = Vm
  3189. instr[4.0] = Vd. */
  3190. unsigned vm = INSTR (20, 16);
  3191. unsigned vn = INSTR (9, 5);
  3192. unsigned vd = INSTR (4, 0);
  3193. unsigned i;
  3194. int full = INSTR (30, 30);
  3195. NYI_assert (29, 24, 0x0E);
  3196. NYI_assert (21, 21, 1);
  3197. NYI_assert (15, 10, 0x21);
  3198. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3199. switch (INSTR (23, 22))
  3200. {
  3201. case 0:
  3202. for (i = 0; i < (full ? 16 : 8); i++)
  3203. aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u8 (cpu, vn, i)
  3204. + aarch64_get_vec_u8 (cpu, vm, i));
  3205. return;
  3206. case 1:
  3207. for (i = 0; i < (full ? 8 : 4); i++)
  3208. aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vn, i)
  3209. + aarch64_get_vec_u16 (cpu, vm, i));
  3210. return;
  3211. case 2:
  3212. for (i = 0; i < (full ? 4 : 2); i++)
  3213. aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vn, i)
  3214. + aarch64_get_vec_u32 (cpu, vm, i));
  3215. return;
  3216. case 3:
  3217. if (! full)
  3218. HALT_UNALLOC;
  3219. aarch64_set_vec_u64 (cpu, vd, 0, aarch64_get_vec_u64 (cpu, vn, 0)
  3220. + aarch64_get_vec_u64 (cpu, vm, 0));
  3221. aarch64_set_vec_u64 (cpu, vd, 1,
  3222. aarch64_get_vec_u64 (cpu, vn, 1)
  3223. + aarch64_get_vec_u64 (cpu, vm, 1));
  3224. return;
  3225. }
  3226. }
  3227. static void
  3228. do_vec_mul (sim_cpu *cpu)
  3229. {
  3230. /* instr[31] = 0
  3231. instr[30] = full/half selector
  3232. instr[29,24] = 00 1110
  3233. instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit
  3234. instr[21] = 1
  3235. instr[20,16] = Vn
  3236. instr[15,10] = 10 0111
  3237. instr[9,5] = Vm
  3238. instr[4.0] = Vd. */
  3239. unsigned vm = INSTR (20, 16);
  3240. unsigned vn = INSTR (9, 5);
  3241. unsigned vd = INSTR (4, 0);
  3242. unsigned i;
  3243. int full = INSTR (30, 30);
  3244. int bias = 0;
  3245. NYI_assert (29, 24, 0x0E);
  3246. NYI_assert (21, 21, 1);
  3247. NYI_assert (15, 10, 0x27);
  3248. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3249. switch (INSTR (23, 22))
  3250. {
  3251. case 0:
  3252. DO_VEC_WIDENING_MUL (full ? 16 : 8, uint8_t, u8, u8);
  3253. return;
  3254. case 1:
  3255. DO_VEC_WIDENING_MUL (full ? 8 : 4, uint16_t, u16, u16);
  3256. return;
  3257. case 2:
  3258. DO_VEC_WIDENING_MUL (full ? 4 : 2, uint32_t, u32, u32);
  3259. return;
  3260. case 3:
  3261. HALT_UNALLOC;
  3262. }
  3263. }
  3264. static void
  3265. do_vec_MLA (sim_cpu *cpu)
  3266. {
  3267. /* instr[31] = 0
  3268. instr[30] = full/half selector
  3269. instr[29,24] = 00 1110
  3270. instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit
  3271. instr[21] = 1
  3272. instr[20,16] = Vn
  3273. instr[15,10] = 1001 01
  3274. instr[9,5] = Vm
  3275. instr[4.0] = Vd. */
  3276. unsigned vm = INSTR (20, 16);
  3277. unsigned vn = INSTR (9, 5);
  3278. unsigned vd = INSTR (4, 0);
  3279. unsigned i;
  3280. int full = INSTR (30, 30);
  3281. NYI_assert (29, 24, 0x0E);
  3282. NYI_assert (21, 21, 1);
  3283. NYI_assert (15, 10, 0x25);
  3284. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3285. switch (INSTR (23, 22))
  3286. {
  3287. case 0:
  3288. for (i = 0; i < (full ? 16 : 8); i++)
  3289. aarch64_set_vec_u8 (cpu, vd, i,
  3290. aarch64_get_vec_u8 (cpu, vd, i)
  3291. + (aarch64_get_vec_u8 (cpu, vn, i)
  3292. * aarch64_get_vec_u8 (cpu, vm, i)));
  3293. return;
  3294. case 1:
  3295. for (i = 0; i < (full ? 8 : 4); i++)
  3296. aarch64_set_vec_u16 (cpu, vd, i,
  3297. aarch64_get_vec_u16 (cpu, vd, i)
  3298. + (aarch64_get_vec_u16 (cpu, vn, i)
  3299. * aarch64_get_vec_u16 (cpu, vm, i)));
  3300. return;
  3301. case 2:
  3302. for (i = 0; i < (full ? 4 : 2); i++)
  3303. aarch64_set_vec_u32 (cpu, vd, i,
  3304. aarch64_get_vec_u32 (cpu, vd, i)
  3305. + (aarch64_get_vec_u32 (cpu, vn, i)
  3306. * aarch64_get_vec_u32 (cpu, vm, i)));
  3307. return;
  3308. default:
  3309. HALT_UNALLOC;
  3310. }
  3311. }
  3312. static float
  3313. fmaxnm (float a, float b)
  3314. {
  3315. if (! isnan (a))
  3316. {
  3317. if (! isnan (b))
  3318. return a > b ? a : b;
  3319. return a;
  3320. }
  3321. else if (! isnan (b))
  3322. return b;
  3323. return a;
  3324. }
  3325. static float
  3326. fminnm (float a, float b)
  3327. {
  3328. if (! isnan (a))
  3329. {
  3330. if (! isnan (b))
  3331. return a < b ? a : b;
  3332. return a;
  3333. }
  3334. else if (! isnan (b))
  3335. return b;
  3336. return a;
  3337. }
  3338. static double
  3339. dmaxnm (double a, double b)
  3340. {
  3341. if (! isnan (a))
  3342. {
  3343. if (! isnan (b))
  3344. return a > b ? a : b;
  3345. return a;
  3346. }
  3347. else if (! isnan (b))
  3348. return b;
  3349. return a;
  3350. }
  3351. static double
  3352. dminnm (double a, double b)
  3353. {
  3354. if (! isnan (a))
  3355. {
  3356. if (! isnan (b))
  3357. return a < b ? a : b;
  3358. return a;
  3359. }
  3360. else if (! isnan (b))
  3361. return b;
  3362. return a;
  3363. }
  3364. static void
  3365. do_vec_FminmaxNMP (sim_cpu *cpu)
  3366. {
  3367. /* instr [31] = 0
  3368. instr [30] = half (0)/full (1)
  3369. instr [29,24] = 10 1110
  3370. instr [23] = max(0)/min(1)
  3371. instr [22] = float (0)/double (1)
  3372. instr [21] = 1
  3373. instr [20,16] = Vn
  3374. instr [15,10] = 1100 01
  3375. instr [9,5] = Vm
  3376. instr [4.0] = Vd. */
  3377. unsigned vm = INSTR (20, 16);
  3378. unsigned vn = INSTR (9, 5);
  3379. unsigned vd = INSTR (4, 0);
  3380. int full = INSTR (30, 30);
  3381. NYI_assert (29, 24, 0x2E);
  3382. NYI_assert (21, 21, 1);
  3383. NYI_assert (15, 10, 0x31);
  3384. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3385. if (INSTR (22, 22))
  3386. {
  3387. double (* fn)(double, double) = INSTR (23, 23)
  3388. ? dminnm : dmaxnm;
  3389. if (! full)
  3390. HALT_NYI;
  3391. aarch64_set_vec_double (cpu, vd, 0,
  3392. fn (aarch64_get_vec_double (cpu, vn, 0),
  3393. aarch64_get_vec_double (cpu, vn, 1)));
  3394. aarch64_set_vec_double (cpu, vd, 0,
  3395. fn (aarch64_get_vec_double (cpu, vm, 0),
  3396. aarch64_get_vec_double (cpu, vm, 1)));
  3397. }
  3398. else
  3399. {
  3400. float (* fn)(float, float) = INSTR (23, 23)
  3401. ? fminnm : fmaxnm;
  3402. aarch64_set_vec_float (cpu, vd, 0,
  3403. fn (aarch64_get_vec_float (cpu, vn, 0),
  3404. aarch64_get_vec_float (cpu, vn, 1)));
  3405. if (full)
  3406. aarch64_set_vec_float (cpu, vd, 1,
  3407. fn (aarch64_get_vec_float (cpu, vn, 2),
  3408. aarch64_get_vec_float (cpu, vn, 3)));
  3409. aarch64_set_vec_float (cpu, vd, (full ? 2 : 1),
  3410. fn (aarch64_get_vec_float (cpu, vm, 0),
  3411. aarch64_get_vec_float (cpu, vm, 1)));
  3412. if (full)
  3413. aarch64_set_vec_float (cpu, vd, 3,
  3414. fn (aarch64_get_vec_float (cpu, vm, 2),
  3415. aarch64_get_vec_float (cpu, vm, 3)));
  3416. }
  3417. }
  3418. static void
  3419. do_vec_AND (sim_cpu *cpu)
  3420. {
  3421. /* instr[31] = 0
  3422. instr[30] = half (0)/full (1)
  3423. instr[29,21] = 001110001
  3424. instr[20,16] = Vm
  3425. instr[15,10] = 000111
  3426. instr[9,5] = Vn
  3427. instr[4.0] = Vd. */
  3428. unsigned vm = INSTR (20, 16);
  3429. unsigned vn = INSTR (9, 5);
  3430. unsigned vd = INSTR (4, 0);
  3431. unsigned i;
  3432. int full = INSTR (30, 30);
  3433. NYI_assert (29, 21, 0x071);
  3434. NYI_assert (15, 10, 0x07);
  3435. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3436. for (i = 0; i < (full ? 4 : 2); i++)
  3437. aarch64_set_vec_u32 (cpu, vd, i,
  3438. aarch64_get_vec_u32 (cpu, vn, i)
  3439. & aarch64_get_vec_u32 (cpu, vm, i));
  3440. }
  3441. static void
  3442. do_vec_BSL (sim_cpu *cpu)
  3443. {
  3444. /* instr[31] = 0
  3445. instr[30] = half (0)/full (1)
  3446. instr[29,21] = 101110011
  3447. instr[20,16] = Vm
  3448. instr[15,10] = 000111
  3449. instr[9,5] = Vn
  3450. instr[4.0] = Vd. */
  3451. unsigned vm = INSTR (20, 16);
  3452. unsigned vn = INSTR (9, 5);
  3453. unsigned vd = INSTR (4, 0);
  3454. unsigned i;
  3455. int full = INSTR (30, 30);
  3456. NYI_assert (29, 21, 0x173);
  3457. NYI_assert (15, 10, 0x07);
  3458. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3459. for (i = 0; i < (full ? 16 : 8); i++)
  3460. aarch64_set_vec_u8 (cpu, vd, i,
  3461. ( aarch64_get_vec_u8 (cpu, vd, i)
  3462. & aarch64_get_vec_u8 (cpu, vn, i))
  3463. | ((~ aarch64_get_vec_u8 (cpu, vd, i))
  3464. & aarch64_get_vec_u8 (cpu, vm, i)));
  3465. }
  3466. static void
  3467. do_vec_EOR (sim_cpu *cpu)
  3468. {
  3469. /* instr[31] = 0
  3470. instr[30] = half (0)/full (1)
  3471. instr[29,21] = 10 1110 001
  3472. instr[20,16] = Vm
  3473. instr[15,10] = 000111
  3474. instr[9,5] = Vn
  3475. instr[4.0] = Vd. */
  3476. unsigned vm = INSTR (20, 16);
  3477. unsigned vn = INSTR (9, 5);
  3478. unsigned vd = INSTR (4, 0);
  3479. unsigned i;
  3480. int full = INSTR (30, 30);
  3481. NYI_assert (29, 21, 0x171);
  3482. NYI_assert (15, 10, 0x07);
  3483. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3484. for (i = 0; i < (full ? 4 : 2); i++)
  3485. aarch64_set_vec_u32 (cpu, vd, i,
  3486. aarch64_get_vec_u32 (cpu, vn, i)
  3487. ^ aarch64_get_vec_u32 (cpu, vm, i));
  3488. }
  3489. static void
  3490. do_vec_bit (sim_cpu *cpu)
  3491. {
  3492. /* instr[31] = 0
  3493. instr[30] = half (0)/full (1)
  3494. instr[29,23] = 10 1110 1
  3495. instr[22] = BIT (0) / BIF (1)
  3496. instr[21] = 1
  3497. instr[20,16] = Vm
  3498. instr[15,10] = 0001 11
  3499. instr[9,5] = Vn
  3500. instr[4.0] = Vd. */
  3501. unsigned vm = INSTR (20, 16);
  3502. unsigned vn = INSTR (9, 5);
  3503. unsigned vd = INSTR (4, 0);
  3504. unsigned full = INSTR (30, 30);
  3505. unsigned test_false = INSTR (22, 22);
  3506. unsigned i;
  3507. NYI_assert (29, 23, 0x5D);
  3508. NYI_assert (21, 21, 1);
  3509. NYI_assert (15, 10, 0x07);
  3510. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3511. for (i = 0; i < (full ? 4 : 2); i++)
  3512. {
  3513. uint32_t vd_val = aarch64_get_vec_u32 (cpu, vd, i);
  3514. uint32_t vn_val = aarch64_get_vec_u32 (cpu, vn, i);
  3515. uint32_t vm_val = aarch64_get_vec_u32 (cpu, vm, i);
  3516. if (test_false)
  3517. aarch64_set_vec_u32 (cpu, vd, i,
  3518. (vd_val & vm_val) | (vn_val & ~vm_val));
  3519. else
  3520. aarch64_set_vec_u32 (cpu, vd, i,
  3521. (vd_val & ~vm_val) | (vn_val & vm_val));
  3522. }
  3523. }
  3524. static void
  3525. do_vec_ORN (sim_cpu *cpu)
  3526. {
  3527. /* instr[31] = 0
  3528. instr[30] = half (0)/full (1)
  3529. instr[29,21] = 00 1110 111
  3530. instr[20,16] = Vm
  3531. instr[15,10] = 00 0111
  3532. instr[9,5] = Vn
  3533. instr[4.0] = Vd. */
  3534. unsigned vm = INSTR (20, 16);
  3535. unsigned vn = INSTR (9, 5);
  3536. unsigned vd = INSTR (4, 0);
  3537. unsigned i;
  3538. int full = INSTR (30, 30);
  3539. NYI_assert (29, 21, 0x077);
  3540. NYI_assert (15, 10, 0x07);
  3541. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3542. for (i = 0; i < (full ? 16 : 8); i++)
  3543. aarch64_set_vec_u8 (cpu, vd, i,
  3544. aarch64_get_vec_u8 (cpu, vn, i)
  3545. | ~ aarch64_get_vec_u8 (cpu, vm, i));
  3546. }
  3547. static void
  3548. do_vec_ORR (sim_cpu *cpu)
  3549. {
  3550. /* instr[31] = 0
  3551. instr[30] = half (0)/full (1)
  3552. instr[29,21] = 00 1110 101
  3553. instr[20,16] = Vm
  3554. instr[15,10] = 0001 11
  3555. instr[9,5] = Vn
  3556. instr[4.0] = Vd. */
  3557. unsigned vm = INSTR (20, 16);
  3558. unsigned vn = INSTR (9, 5);
  3559. unsigned vd = INSTR (4, 0);
  3560. unsigned i;
  3561. int full = INSTR (30, 30);
  3562. NYI_assert (29, 21, 0x075);
  3563. NYI_assert (15, 10, 0x07);
  3564. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3565. for (i = 0; i < (full ? 16 : 8); i++)
  3566. aarch64_set_vec_u8 (cpu, vd, i,
  3567. aarch64_get_vec_u8 (cpu, vn, i)
  3568. | aarch64_get_vec_u8 (cpu, vm, i));
  3569. }
  3570. static void
  3571. do_vec_BIC (sim_cpu *cpu)
  3572. {
  3573. /* instr[31] = 0
  3574. instr[30] = half (0)/full (1)
  3575. instr[29,21] = 00 1110 011
  3576. instr[20,16] = Vm
  3577. instr[15,10] = 00 0111
  3578. instr[9,5] = Vn
  3579. instr[4.0] = Vd. */
  3580. unsigned vm = INSTR (20, 16);
  3581. unsigned vn = INSTR (9, 5);
  3582. unsigned vd = INSTR (4, 0);
  3583. unsigned i;
  3584. int full = INSTR (30, 30);
  3585. NYI_assert (29, 21, 0x073);
  3586. NYI_assert (15, 10, 0x07);
  3587. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3588. for (i = 0; i < (full ? 16 : 8); i++)
  3589. aarch64_set_vec_u8 (cpu, vd, i,
  3590. aarch64_get_vec_u8 (cpu, vn, i)
  3591. & ~ aarch64_get_vec_u8 (cpu, vm, i));
  3592. }
  3593. static void
  3594. do_vec_XTN (sim_cpu *cpu)
  3595. {
  3596. /* instr[31] = 0
  3597. instr[30] = first part (0)/ second part (1)
  3598. instr[29,24] = 00 1110
  3599. instr[23,22] = size: byte(00), half(01), word (10)
  3600. instr[21,10] = 1000 0100 1010
  3601. instr[9,5] = Vs
  3602. instr[4,0] = Vd. */
  3603. unsigned vs = INSTR (9, 5);
  3604. unsigned vd = INSTR (4, 0);
  3605. unsigned bias = INSTR (30, 30);
  3606. unsigned i;
  3607. NYI_assert (29, 24, 0x0E);
  3608. NYI_assert (21, 10, 0x84A);
  3609. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3610. switch (INSTR (23, 22))
  3611. {
  3612. case 0:
  3613. for (i = 0; i < 8; i++)
  3614. aarch64_set_vec_u8 (cpu, vd, i + (bias * 8),
  3615. aarch64_get_vec_u16 (cpu, vs, i));
  3616. return;
  3617. case 1:
  3618. for (i = 0; i < 4; i++)
  3619. aarch64_set_vec_u16 (cpu, vd, i + (bias * 4),
  3620. aarch64_get_vec_u32 (cpu, vs, i));
  3621. return;
  3622. case 2:
  3623. for (i = 0; i < 2; i++)
  3624. aarch64_set_vec_u32 (cpu, vd, i + (bias * 2),
  3625. aarch64_get_vec_u64 (cpu, vs, i));
  3626. return;
  3627. }
  3628. }
  3629. /* Return the number of bits set in the input value. */
  3630. #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
  3631. # define popcount __builtin_popcount
  3632. #else
  3633. static int
  3634. popcount (unsigned char x)
  3635. {
  3636. static const unsigned char popcnt[16] =
  3637. {
  3638. 0, 1, 1, 2,
  3639. 1, 2, 2, 3,
  3640. 1, 2, 2, 3,
  3641. 2, 3, 3, 4
  3642. };
  3643. /* Only counts the low 8 bits of the input as that is all we need. */
  3644. return popcnt[x % 16] + popcnt[x / 16];
  3645. }
  3646. #endif
  3647. static void
  3648. do_vec_CNT (sim_cpu *cpu)
  3649. {
  3650. /* instr[31] = 0
  3651. instr[30] = half (0)/ full (1)
  3652. instr[29,24] = 00 1110
  3653. instr[23,22] = size: byte(00)
  3654. instr[21,10] = 1000 0001 0110
  3655. instr[9,5] = Vs
  3656. instr[4,0] = Vd. */
  3657. unsigned vs = INSTR (9, 5);
  3658. unsigned vd = INSTR (4, 0);
  3659. int full = INSTR (30, 30);
  3660. int size = INSTR (23, 22);
  3661. int i;
  3662. NYI_assert (29, 24, 0x0E);
  3663. NYI_assert (21, 10, 0x816);
  3664. if (size != 0)
  3665. HALT_UNALLOC;
  3666. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3667. for (i = 0; i < (full ? 16 : 8); i++)
  3668. aarch64_set_vec_u8 (cpu, vd, i,
  3669. popcount (aarch64_get_vec_u8 (cpu, vs, i)));
  3670. }
  3671. static void
  3672. do_vec_maxv (sim_cpu *cpu)
  3673. {
  3674. /* instr[31] = 0
  3675. instr[30] = half(0)/full(1)
  3676. instr[29] = signed (0)/unsigned(1)
  3677. instr[28,24] = 0 1110
  3678. instr[23,22] = size: byte(00), half(01), word (10)
  3679. instr[21] = 1
  3680. instr[20,17] = 1 000
  3681. instr[16] = max(0)/min(1)
  3682. instr[15,10] = 1010 10
  3683. instr[9,5] = V source
  3684. instr[4.0] = R dest. */
  3685. unsigned vs = INSTR (9, 5);
  3686. unsigned rd = INSTR (4, 0);
  3687. unsigned full = INSTR (30, 30);
  3688. unsigned i;
  3689. NYI_assert (28, 24, 0x0E);
  3690. NYI_assert (21, 21, 1);
  3691. NYI_assert (20, 17, 8);
  3692. NYI_assert (15, 10, 0x2A);
  3693. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3694. switch ((INSTR (29, 29) << 1) | INSTR (16, 16))
  3695. {
  3696. case 0: /* SMAXV. */
  3697. {
  3698. int64_t smax;
  3699. switch (INSTR (23, 22))
  3700. {
  3701. case 0:
  3702. smax = aarch64_get_vec_s8 (cpu, vs, 0);
  3703. for (i = 1; i < (full ? 16 : 8); i++)
  3704. smax = max (smax, aarch64_get_vec_s8 (cpu, vs, i));
  3705. break;
  3706. case 1:
  3707. smax = aarch64_get_vec_s16 (cpu, vs, 0);
  3708. for (i = 1; i < (full ? 8 : 4); i++)
  3709. smax = max (smax, aarch64_get_vec_s16 (cpu, vs, i));
  3710. break;
  3711. case 2:
  3712. smax = aarch64_get_vec_s32 (cpu, vs, 0);
  3713. for (i = 1; i < (full ? 4 : 2); i++)
  3714. smax = max (smax, aarch64_get_vec_s32 (cpu, vs, i));
  3715. break;
  3716. case 3:
  3717. HALT_UNALLOC;
  3718. }
  3719. aarch64_set_reg_s64 (cpu, rd, NO_SP, smax);
  3720. return;
  3721. }
  3722. case 1: /* SMINV. */
  3723. {
  3724. int64_t smin;
  3725. switch (INSTR (23, 22))
  3726. {
  3727. case 0:
  3728. smin = aarch64_get_vec_s8 (cpu, vs, 0);
  3729. for (i = 1; i < (full ? 16 : 8); i++)
  3730. smin = min (smin, aarch64_get_vec_s8 (cpu, vs, i));
  3731. break;
  3732. case 1:
  3733. smin = aarch64_get_vec_s16 (cpu, vs, 0);
  3734. for (i = 1; i < (full ? 8 : 4); i++)
  3735. smin = min (smin, aarch64_get_vec_s16 (cpu, vs, i));
  3736. break;
  3737. case 2:
  3738. smin = aarch64_get_vec_s32 (cpu, vs, 0);
  3739. for (i = 1; i < (full ? 4 : 2); i++)
  3740. smin = min (smin, aarch64_get_vec_s32 (cpu, vs, i));
  3741. break;
  3742. case 3:
  3743. HALT_UNALLOC;
  3744. }
  3745. aarch64_set_reg_s64 (cpu, rd, NO_SP, smin);
  3746. return;
  3747. }
  3748. case 2: /* UMAXV. */
  3749. {
  3750. uint64_t umax;
  3751. switch (INSTR (23, 22))
  3752. {
  3753. case 0:
  3754. umax = aarch64_get_vec_u8 (cpu, vs, 0);
  3755. for (i = 1; i < (full ? 16 : 8); i++)
  3756. umax = max (umax, aarch64_get_vec_u8 (cpu, vs, i));
  3757. break;
  3758. case 1:
  3759. umax = aarch64_get_vec_u16 (cpu, vs, 0);
  3760. for (i = 1; i < (full ? 8 : 4); i++)
  3761. umax = max (umax, aarch64_get_vec_u16 (cpu, vs, i));
  3762. break;
  3763. case 2:
  3764. umax = aarch64_get_vec_u32 (cpu, vs, 0);
  3765. for (i = 1; i < (full ? 4 : 2); i++)
  3766. umax = max (umax, aarch64_get_vec_u32 (cpu, vs, i));
  3767. break;
  3768. case 3:
  3769. HALT_UNALLOC;
  3770. }
  3771. aarch64_set_reg_u64 (cpu, rd, NO_SP, umax);
  3772. return;
  3773. }
  3774. case 3: /* UMINV. */
  3775. {
  3776. uint64_t umin;
  3777. switch (INSTR (23, 22))
  3778. {
  3779. case 0:
  3780. umin = aarch64_get_vec_u8 (cpu, vs, 0);
  3781. for (i = 1; i < (full ? 16 : 8); i++)
  3782. umin = min (umin, aarch64_get_vec_u8 (cpu, vs, i));
  3783. break;
  3784. case 1:
  3785. umin = aarch64_get_vec_u16 (cpu, vs, 0);
  3786. for (i = 1; i < (full ? 8 : 4); i++)
  3787. umin = min (umin, aarch64_get_vec_u16 (cpu, vs, i));
  3788. break;
  3789. case 2:
  3790. umin = aarch64_get_vec_u32 (cpu, vs, 0);
  3791. for (i = 1; i < (full ? 4 : 2); i++)
  3792. umin = min (umin, aarch64_get_vec_u32 (cpu, vs, i));
  3793. break;
  3794. case 3:
  3795. HALT_UNALLOC;
  3796. }
  3797. aarch64_set_reg_u64 (cpu, rd, NO_SP, umin);
  3798. return;
  3799. }
  3800. }
  3801. }
  3802. static void
  3803. do_vec_fminmaxV (sim_cpu *cpu)
  3804. {
  3805. /* instr[31,24] = 0110 1110
  3806. instr[23] = max(0)/min(1)
  3807. instr[22,14] = 011 0000 11
  3808. instr[13,12] = nm(00)/normal(11)
  3809. instr[11,10] = 10
  3810. instr[9,5] = V source
  3811. instr[4.0] = R dest. */
  3812. unsigned vs = INSTR (9, 5);
  3813. unsigned rd = INSTR (4, 0);
  3814. unsigned i;
  3815. float res = aarch64_get_vec_float (cpu, vs, 0);
  3816. NYI_assert (31, 24, 0x6E);
  3817. NYI_assert (22, 14, 0x0C3);
  3818. NYI_assert (11, 10, 2);
  3819. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3820. if (INSTR (23, 23))
  3821. {
  3822. switch (INSTR (13, 12))
  3823. {
  3824. case 0: /* FMNINNMV. */
  3825. for (i = 1; i < 4; i++)
  3826. res = fminnm (res, aarch64_get_vec_float (cpu, vs, i));
  3827. break;
  3828. case 3: /* FMINV. */
  3829. for (i = 1; i < 4; i++)
  3830. res = min (res, aarch64_get_vec_float (cpu, vs, i));
  3831. break;
  3832. default:
  3833. HALT_NYI;
  3834. }
  3835. }
  3836. else
  3837. {
  3838. switch (INSTR (13, 12))
  3839. {
  3840. case 0: /* FMNAXNMV. */
  3841. for (i = 1; i < 4; i++)
  3842. res = fmaxnm (res, aarch64_get_vec_float (cpu, vs, i));
  3843. break;
  3844. case 3: /* FMAXV. */
  3845. for (i = 1; i < 4; i++)
  3846. res = max (res, aarch64_get_vec_float (cpu, vs, i));
  3847. break;
  3848. default:
  3849. HALT_NYI;
  3850. }
  3851. }
  3852. aarch64_set_FP_float (cpu, rd, res);
  3853. }
  3854. static void
  3855. do_vec_Fminmax (sim_cpu *cpu)
  3856. {
  3857. /* instr[31] = 0
  3858. instr[30] = half(0)/full(1)
  3859. instr[29,24] = 00 1110
  3860. instr[23] = max(0)/min(1)
  3861. instr[22] = float(0)/double(1)
  3862. instr[21] = 1
  3863. instr[20,16] = Vm
  3864. instr[15,14] = 11
  3865. instr[13,12] = nm(00)/normal(11)
  3866. instr[11,10] = 01
  3867. instr[9,5] = Vn
  3868. instr[4,0] = Vd. */
  3869. unsigned vm = INSTR (20, 16);
  3870. unsigned vn = INSTR (9, 5);
  3871. unsigned vd = INSTR (4, 0);
  3872. unsigned full = INSTR (30, 30);
  3873. unsigned min = INSTR (23, 23);
  3874. unsigned i;
  3875. NYI_assert (29, 24, 0x0E);
  3876. NYI_assert (21, 21, 1);
  3877. NYI_assert (15, 14, 3);
  3878. NYI_assert (11, 10, 1);
  3879. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3880. if (INSTR (22, 22))
  3881. {
  3882. double (* func)(double, double);
  3883. if (! full)
  3884. HALT_NYI;
  3885. if (INSTR (13, 12) == 0)
  3886. func = min ? dminnm : dmaxnm;
  3887. else if (INSTR (13, 12) == 3)
  3888. func = min ? fmin : fmax;
  3889. else
  3890. HALT_NYI;
  3891. for (i = 0; i < 2; i++)
  3892. aarch64_set_vec_double (cpu, vd, i,
  3893. func (aarch64_get_vec_double (cpu, vn, i),
  3894. aarch64_get_vec_double (cpu, vm, i)));
  3895. }
  3896. else
  3897. {
  3898. float (* func)(float, float);
  3899. if (INSTR (13, 12) == 0)
  3900. func = min ? fminnm : fmaxnm;
  3901. else if (INSTR (13, 12) == 3)
  3902. func = min ? fminf : fmaxf;
  3903. else
  3904. HALT_NYI;
  3905. for (i = 0; i < (full ? 4 : 2); i++)
  3906. aarch64_set_vec_float (cpu, vd, i,
  3907. func (aarch64_get_vec_float (cpu, vn, i),
  3908. aarch64_get_vec_float (cpu, vm, i)));
  3909. }
  3910. }
  3911. static void
  3912. do_vec_SCVTF (sim_cpu *cpu)
  3913. {
  3914. /* instr[31] = 0
  3915. instr[30] = Q
  3916. instr[29,23] = 00 1110 0
  3917. instr[22] = float(0)/double(1)
  3918. instr[21,10] = 10 0001 1101 10
  3919. instr[9,5] = Vn
  3920. instr[4,0] = Vd. */
  3921. unsigned vn = INSTR (9, 5);
  3922. unsigned vd = INSTR (4, 0);
  3923. unsigned full = INSTR (30, 30);
  3924. unsigned size = INSTR (22, 22);
  3925. unsigned i;
  3926. NYI_assert (29, 23, 0x1C);
  3927. NYI_assert (21, 10, 0x876);
  3928. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  3929. if (size)
  3930. {
  3931. if (! full)
  3932. HALT_UNALLOC;
  3933. for (i = 0; i < 2; i++)
  3934. {
  3935. double val = (double) aarch64_get_vec_u64 (cpu, vn, i);
  3936. aarch64_set_vec_double (cpu, vd, i, val);
  3937. }
  3938. }
  3939. else
  3940. {
  3941. for (i = 0; i < (full ? 4 : 2); i++)
  3942. {
  3943. float val = (float) aarch64_get_vec_u32 (cpu, vn, i);
  3944. aarch64_set_vec_float (cpu, vd, i, val);
  3945. }
  3946. }
  3947. }
  3948. #define VEC_CMP(SOURCE, CMP) \
  3949. do \
  3950. { \
  3951. switch (size) \
  3952. { \
  3953. case 0: \
  3954. for (i = 0; i < (full ? 16 : 8); i++) \
  3955. aarch64_set_vec_u8 (cpu, vd, i, \
  3956. aarch64_get_vec_##SOURCE##8 (cpu, vn, i) \
  3957. CMP \
  3958. aarch64_get_vec_##SOURCE##8 (cpu, vm, i) \
  3959. ? -1 : 0); \
  3960. return; \
  3961. case 1: \
  3962. for (i = 0; i < (full ? 8 : 4); i++) \
  3963. aarch64_set_vec_u16 (cpu, vd, i, \
  3964. aarch64_get_vec_##SOURCE##16 (cpu, vn, i) \
  3965. CMP \
  3966. aarch64_get_vec_##SOURCE##16 (cpu, vm, i) \
  3967. ? -1 : 0); \
  3968. return; \
  3969. case 2: \
  3970. for (i = 0; i < (full ? 4 : 2); i++) \
  3971. aarch64_set_vec_u32 (cpu, vd, i, \
  3972. aarch64_get_vec_##SOURCE##32 (cpu, vn, i) \
  3973. CMP \
  3974. aarch64_get_vec_##SOURCE##32 (cpu, vm, i) \
  3975. ? -1 : 0); \
  3976. return; \
  3977. case 3: \
  3978. if (! full) \
  3979. HALT_UNALLOC; \
  3980. for (i = 0; i < 2; i++) \
  3981. aarch64_set_vec_u64 (cpu, vd, i, \
  3982. aarch64_get_vec_##SOURCE##64 (cpu, vn, i) \
  3983. CMP \
  3984. aarch64_get_vec_##SOURCE##64 (cpu, vm, i) \
  3985. ? -1ULL : 0); \
  3986. return; \
  3987. } \
  3988. } \
  3989. while (0)
  3990. #define VEC_CMP0(SOURCE, CMP) \
  3991. do \
  3992. { \
  3993. switch (size) \
  3994. { \
  3995. case 0: \
  3996. for (i = 0; i < (full ? 16 : 8); i++) \
  3997. aarch64_set_vec_u8 (cpu, vd, i, \
  3998. aarch64_get_vec_##SOURCE##8 (cpu, vn, i) \
  3999. CMP 0 ? -1 : 0); \
  4000. return; \
  4001. case 1: \
  4002. for (i = 0; i < (full ? 8 : 4); i++) \
  4003. aarch64_set_vec_u16 (cpu, vd, i, \
  4004. aarch64_get_vec_##SOURCE##16 (cpu, vn, i) \
  4005. CMP 0 ? -1 : 0); \
  4006. return; \
  4007. case 2: \
  4008. for (i = 0; i < (full ? 4 : 2); i++) \
  4009. aarch64_set_vec_u32 (cpu, vd, i, \
  4010. aarch64_get_vec_##SOURCE##32 (cpu, vn, i) \
  4011. CMP 0 ? -1 : 0); \
  4012. return; \
  4013. case 3: \
  4014. if (! full) \
  4015. HALT_UNALLOC; \
  4016. for (i = 0; i < 2; i++) \
  4017. aarch64_set_vec_u64 (cpu, vd, i, \
  4018. aarch64_get_vec_##SOURCE##64 (cpu, vn, i) \
  4019. CMP 0 ? -1ULL : 0); \
  4020. return; \
  4021. } \
  4022. } \
  4023. while (0)
  4024. #define VEC_FCMP0(CMP) \
  4025. do \
  4026. { \
  4027. if (vm != 0) \
  4028. HALT_NYI; \
  4029. if (INSTR (22, 22)) \
  4030. { \
  4031. if (! full) \
  4032. HALT_NYI; \
  4033. for (i = 0; i < 2; i++) \
  4034. aarch64_set_vec_u64 (cpu, vd, i, \
  4035. aarch64_get_vec_double (cpu, vn, i) \
  4036. CMP 0.0 ? -1 : 0); \
  4037. } \
  4038. else \
  4039. { \
  4040. for (i = 0; i < (full ? 4 : 2); i++) \
  4041. aarch64_set_vec_u32 (cpu, vd, i, \
  4042. aarch64_get_vec_float (cpu, vn, i) \
  4043. CMP 0.0 ? -1 : 0); \
  4044. } \
  4045. return; \
  4046. } \
  4047. while (0)
  4048. #define VEC_FCMP(CMP) \
  4049. do \
  4050. { \
  4051. if (INSTR (22, 22)) \
  4052. { \
  4053. if (! full) \
  4054. HALT_NYI; \
  4055. for (i = 0; i < 2; i++) \
  4056. aarch64_set_vec_u64 (cpu, vd, i, \
  4057. aarch64_get_vec_double (cpu, vn, i) \
  4058. CMP \
  4059. aarch64_get_vec_double (cpu, vm, i) \
  4060. ? -1 : 0); \
  4061. } \
  4062. else \
  4063. { \
  4064. for (i = 0; i < (full ? 4 : 2); i++) \
  4065. aarch64_set_vec_u32 (cpu, vd, i, \
  4066. aarch64_get_vec_float (cpu, vn, i) \
  4067. CMP \
  4068. aarch64_get_vec_float (cpu, vm, i) \
  4069. ? -1 : 0); \
  4070. } \
  4071. return; \
  4072. } \
  4073. while (0)
  4074. static void
  4075. do_vec_compare (sim_cpu *cpu)
  4076. {
  4077. /* instr[31] = 0
  4078. instr[30] = half(0)/full(1)
  4079. instr[29] = part-of-comparison-type
  4080. instr[28,24] = 0 1110
  4081. instr[23,22] = size of integer compares: byte(00), half(01), word (10), long (11)
  4082. type of float compares: single (-0) / double (-1)
  4083. instr[21] = 1
  4084. instr[20,16] = Vm or 00000 (compare vs 0)
  4085. instr[15,10] = part-of-comparison-type
  4086. instr[9,5] = Vn
  4087. instr[4.0] = Vd. */
  4088. int full = INSTR (30, 30);
  4089. int size = INSTR (23, 22);
  4090. unsigned vm = INSTR (20, 16);
  4091. unsigned vn = INSTR (9, 5);
  4092. unsigned vd = INSTR (4, 0);
  4093. unsigned i;
  4094. NYI_assert (28, 24, 0x0E);
  4095. NYI_assert (21, 21, 1);
  4096. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4097. if ((INSTR (11, 11)
  4098. && INSTR (14, 14))
  4099. || ((INSTR (11, 11) == 0
  4100. && INSTR (10, 10) == 0)))
  4101. {
  4102. /* A compare vs 0. */
  4103. if (vm != 0)
  4104. {
  4105. if (INSTR (15, 10) == 0x2A)
  4106. do_vec_maxv (cpu);
  4107. else if (INSTR (15, 10) == 0x32
  4108. || INSTR (15, 10) == 0x3E)
  4109. do_vec_fminmaxV (cpu);
  4110. else if (INSTR (29, 23) == 0x1C
  4111. && INSTR (21, 10) == 0x876)
  4112. do_vec_SCVTF (cpu);
  4113. else
  4114. HALT_NYI;
  4115. return;
  4116. }
  4117. }
  4118. if (INSTR (14, 14))
  4119. {
  4120. /* A floating point compare. */
  4121. unsigned decode = (INSTR (29, 29) << 5) | (INSTR (23, 23) << 4)
  4122. | INSTR (13, 10);
  4123. NYI_assert (15, 15, 1);
  4124. switch (decode)
  4125. {
  4126. case /* 0b010010: GT#0 */ 0x12: VEC_FCMP0 (>);
  4127. case /* 0b110010: GE#0 */ 0x32: VEC_FCMP0 (>=);
  4128. case /* 0b010110: EQ#0 */ 0x16: VEC_FCMP0 (==);
  4129. case /* 0b110110: LE#0 */ 0x36: VEC_FCMP0 (<=);
  4130. case /* 0b011010: LT#0 */ 0x1A: VEC_FCMP0 (<);
  4131. case /* 0b111001: GT */ 0x39: VEC_FCMP (>);
  4132. case /* 0b101001: GE */ 0x29: VEC_FCMP (>=);
  4133. case /* 0b001001: EQ */ 0x09: VEC_FCMP (==);
  4134. default:
  4135. HALT_NYI;
  4136. }
  4137. }
  4138. else
  4139. {
  4140. unsigned decode = (INSTR (29, 29) << 6) | INSTR (15, 10);
  4141. switch (decode)
  4142. {
  4143. case 0x0D: /* 0001101 GT */ VEC_CMP (s, > );
  4144. case 0x0F: /* 0001111 GE */ VEC_CMP (s, >= );
  4145. case 0x22: /* 0100010 GT #0 */ VEC_CMP0 (s, > );
  4146. case 0x23: /* 0100011 TST */ VEC_CMP (u, & );
  4147. case 0x26: /* 0100110 EQ #0 */ VEC_CMP0 (s, == );
  4148. case 0x2A: /* 0101010 LT #0 */ VEC_CMP0 (s, < );
  4149. case 0x4D: /* 1001101 HI */ VEC_CMP (u, > );
  4150. case 0x4F: /* 1001111 HS */ VEC_CMP (u, >= );
  4151. case 0x62: /* 1100010 GE #0 */ VEC_CMP0 (s, >= );
  4152. case 0x63: /* 1100011 EQ */ VEC_CMP (u, == );
  4153. case 0x66: /* 1100110 LE #0 */ VEC_CMP0 (s, <= );
  4154. default:
  4155. if (vm == 0)
  4156. HALT_NYI;
  4157. do_vec_maxv (cpu);
  4158. }
  4159. }
  4160. }
  4161. static void
  4162. do_vec_SSHL (sim_cpu *cpu)
  4163. {
  4164. /* instr[31] = 0
  4165. instr[30] = first part (0)/ second part (1)
  4166. instr[29,24] = 00 1110
  4167. instr[23,22] = size: byte(00), half(01), word (10), long (11)
  4168. instr[21] = 1
  4169. instr[20,16] = Vm
  4170. instr[15,10] = 0100 01
  4171. instr[9,5] = Vn
  4172. instr[4,0] = Vd. */
  4173. unsigned full = INSTR (30, 30);
  4174. unsigned vm = INSTR (20, 16);
  4175. unsigned vn = INSTR (9, 5);
  4176. unsigned vd = INSTR (4, 0);
  4177. unsigned i;
  4178. signed int shift;
  4179. NYI_assert (29, 24, 0x0E);
  4180. NYI_assert (21, 21, 1);
  4181. NYI_assert (15, 10, 0x11);
  4182. /* FIXME: What is a signed shift left in this context ?. */
  4183. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4184. switch (INSTR (23, 22))
  4185. {
  4186. case 0:
  4187. for (i = 0; i < (full ? 16 : 8); i++)
  4188. {
  4189. shift = aarch64_get_vec_s8 (cpu, vm, i);
  4190. if (shift >= 0)
  4191. aarch64_set_vec_s8 (cpu, vd, i, aarch64_get_vec_s8 (cpu, vn, i)
  4192. << shift);
  4193. else
  4194. aarch64_set_vec_s8 (cpu, vd, i, aarch64_get_vec_s8 (cpu, vn, i)
  4195. >> - shift);
  4196. }
  4197. return;
  4198. case 1:
  4199. for (i = 0; i < (full ? 8 : 4); i++)
  4200. {
  4201. shift = aarch64_get_vec_s8 (cpu, vm, i * 2);
  4202. if (shift >= 0)
  4203. aarch64_set_vec_s16 (cpu, vd, i, aarch64_get_vec_s16 (cpu, vn, i)
  4204. << shift);
  4205. else
  4206. aarch64_set_vec_s16 (cpu, vd, i, aarch64_get_vec_s16 (cpu, vn, i)
  4207. >> - shift);
  4208. }
  4209. return;
  4210. case 2:
  4211. for (i = 0; i < (full ? 4 : 2); i++)
  4212. {
  4213. shift = aarch64_get_vec_s8 (cpu, vm, i * 4);
  4214. if (shift >= 0)
  4215. aarch64_set_vec_s32 (cpu, vd, i, aarch64_get_vec_s32 (cpu, vn, i)
  4216. << shift);
  4217. else
  4218. aarch64_set_vec_s32 (cpu, vd, i, aarch64_get_vec_s32 (cpu, vn, i)
  4219. >> - shift);
  4220. }
  4221. return;
  4222. case 3:
  4223. if (! full)
  4224. HALT_UNALLOC;
  4225. for (i = 0; i < 2; i++)
  4226. {
  4227. shift = aarch64_get_vec_s8 (cpu, vm, i * 8);
  4228. if (shift >= 0)
  4229. aarch64_set_vec_s64 (cpu, vd, i, aarch64_get_vec_s64 (cpu, vn, i)
  4230. << shift);
  4231. else
  4232. aarch64_set_vec_s64 (cpu, vd, i, aarch64_get_vec_s64 (cpu, vn, i)
  4233. >> - shift);
  4234. }
  4235. return;
  4236. }
  4237. }
  4238. static void
  4239. do_vec_USHL (sim_cpu *cpu)
  4240. {
  4241. /* instr[31] = 0
  4242. instr[30] = first part (0)/ second part (1)
  4243. instr[29,24] = 10 1110
  4244. instr[23,22] = size: byte(00), half(01), word (10), long (11)
  4245. instr[21] = 1
  4246. instr[20,16] = Vm
  4247. instr[15,10] = 0100 01
  4248. instr[9,5] = Vn
  4249. instr[4,0] = Vd */
  4250. unsigned full = INSTR (30, 30);
  4251. unsigned vm = INSTR (20, 16);
  4252. unsigned vn = INSTR (9, 5);
  4253. unsigned vd = INSTR (4, 0);
  4254. unsigned i;
  4255. signed int shift;
  4256. NYI_assert (29, 24, 0x2E);
  4257. NYI_assert (15, 10, 0x11);
  4258. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4259. switch (INSTR (23, 22))
  4260. {
  4261. case 0:
  4262. for (i = 0; i < (full ? 16 : 8); i++)
  4263. {
  4264. shift = aarch64_get_vec_s8 (cpu, vm, i);
  4265. if (shift >= 0)
  4266. aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u8 (cpu, vn, i)
  4267. << shift);
  4268. else
  4269. aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u8 (cpu, vn, i)
  4270. >> - shift);
  4271. }
  4272. return;
  4273. case 1:
  4274. for (i = 0; i < (full ? 8 : 4); i++)
  4275. {
  4276. shift = aarch64_get_vec_s8 (cpu, vm, i * 2);
  4277. if (shift >= 0)
  4278. aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vn, i)
  4279. << shift);
  4280. else
  4281. aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vn, i)
  4282. >> - shift);
  4283. }
  4284. return;
  4285. case 2:
  4286. for (i = 0; i < (full ? 4 : 2); i++)
  4287. {
  4288. shift = aarch64_get_vec_s8 (cpu, vm, i * 4);
  4289. if (shift >= 0)
  4290. aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vn, i)
  4291. << shift);
  4292. else
  4293. aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vn, i)
  4294. >> - shift);
  4295. }
  4296. return;
  4297. case 3:
  4298. if (! full)
  4299. HALT_UNALLOC;
  4300. for (i = 0; i < 2; i++)
  4301. {
  4302. shift = aarch64_get_vec_s8 (cpu, vm, i * 8);
  4303. if (shift >= 0)
  4304. aarch64_set_vec_u64 (cpu, vd, i, aarch64_get_vec_u64 (cpu, vn, i)
  4305. << shift);
  4306. else
  4307. aarch64_set_vec_u64 (cpu, vd, i, aarch64_get_vec_u64 (cpu, vn, i)
  4308. >> - shift);
  4309. }
  4310. return;
  4311. }
  4312. }
  4313. static void
  4314. do_vec_FMLA (sim_cpu *cpu)
  4315. {
  4316. /* instr[31] = 0
  4317. instr[30] = full/half selector
  4318. instr[29,23] = 0011100
  4319. instr[22] = size: 0=>float, 1=>double
  4320. instr[21] = 1
  4321. instr[20,16] = Vn
  4322. instr[15,10] = 1100 11
  4323. instr[9,5] = Vm
  4324. instr[4.0] = Vd. */
  4325. unsigned vm = INSTR (20, 16);
  4326. unsigned vn = INSTR (9, 5);
  4327. unsigned vd = INSTR (4, 0);
  4328. unsigned i;
  4329. int full = INSTR (30, 30);
  4330. NYI_assert (29, 23, 0x1C);
  4331. NYI_assert (21, 21, 1);
  4332. NYI_assert (15, 10, 0x33);
  4333. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4334. if (INSTR (22, 22))
  4335. {
  4336. if (! full)
  4337. HALT_UNALLOC;
  4338. for (i = 0; i < 2; i++)
  4339. aarch64_set_vec_double (cpu, vd, i,
  4340. aarch64_get_vec_double (cpu, vn, i) *
  4341. aarch64_get_vec_double (cpu, vm, i) +
  4342. aarch64_get_vec_double (cpu, vd, i));
  4343. }
  4344. else
  4345. {
  4346. for (i = 0; i < (full ? 4 : 2); i++)
  4347. aarch64_set_vec_float (cpu, vd, i,
  4348. aarch64_get_vec_float (cpu, vn, i) *
  4349. aarch64_get_vec_float (cpu, vm, i) +
  4350. aarch64_get_vec_float (cpu, vd, i));
  4351. }
  4352. }
  4353. static void
  4354. do_vec_max (sim_cpu *cpu)
  4355. {
  4356. /* instr[31] = 0
  4357. instr[30] = full/half selector
  4358. instr[29] = SMAX (0) / UMAX (1)
  4359. instr[28,24] = 0 1110
  4360. instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit
  4361. instr[21] = 1
  4362. instr[20,16] = Vn
  4363. instr[15,10] = 0110 01
  4364. instr[9,5] = Vm
  4365. instr[4.0] = Vd. */
  4366. unsigned vm = INSTR (20, 16);
  4367. unsigned vn = INSTR (9, 5);
  4368. unsigned vd = INSTR (4, 0);
  4369. unsigned i;
  4370. int full = INSTR (30, 30);
  4371. NYI_assert (28, 24, 0x0E);
  4372. NYI_assert (21, 21, 1);
  4373. NYI_assert (15, 10, 0x19);
  4374. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4375. if (INSTR (29, 29))
  4376. {
  4377. switch (INSTR (23, 22))
  4378. {
  4379. case 0:
  4380. for (i = 0; i < (full ? 16 : 8); i++)
  4381. aarch64_set_vec_u8 (cpu, vd, i,
  4382. aarch64_get_vec_u8 (cpu, vn, i)
  4383. > aarch64_get_vec_u8 (cpu, vm, i)
  4384. ? aarch64_get_vec_u8 (cpu, vn, i)
  4385. : aarch64_get_vec_u8 (cpu, vm, i));
  4386. return;
  4387. case 1:
  4388. for (i = 0; i < (full ? 8 : 4); i++)
  4389. aarch64_set_vec_u16 (cpu, vd, i,
  4390. aarch64_get_vec_u16 (cpu, vn, i)
  4391. > aarch64_get_vec_u16 (cpu, vm, i)
  4392. ? aarch64_get_vec_u16 (cpu, vn, i)
  4393. : aarch64_get_vec_u16 (cpu, vm, i));
  4394. return;
  4395. case 2:
  4396. for (i = 0; i < (full ? 4 : 2); i++)
  4397. aarch64_set_vec_u32 (cpu, vd, i,
  4398. aarch64_get_vec_u32 (cpu, vn, i)
  4399. > aarch64_get_vec_u32 (cpu, vm, i)
  4400. ? aarch64_get_vec_u32 (cpu, vn, i)
  4401. : aarch64_get_vec_u32 (cpu, vm, i));
  4402. return;
  4403. case 3:
  4404. HALT_UNALLOC;
  4405. }
  4406. }
  4407. else
  4408. {
  4409. switch (INSTR (23, 22))
  4410. {
  4411. case 0:
  4412. for (i = 0; i < (full ? 16 : 8); i++)
  4413. aarch64_set_vec_s8 (cpu, vd, i,
  4414. aarch64_get_vec_s8 (cpu, vn, i)
  4415. > aarch64_get_vec_s8 (cpu, vm, i)
  4416. ? aarch64_get_vec_s8 (cpu, vn, i)
  4417. : aarch64_get_vec_s8 (cpu, vm, i));
  4418. return;
  4419. case 1:
  4420. for (i = 0; i < (full ? 8 : 4); i++)
  4421. aarch64_set_vec_s16 (cpu, vd, i,
  4422. aarch64_get_vec_s16 (cpu, vn, i)
  4423. > aarch64_get_vec_s16 (cpu, vm, i)
  4424. ? aarch64_get_vec_s16 (cpu, vn, i)
  4425. : aarch64_get_vec_s16 (cpu, vm, i));
  4426. return;
  4427. case 2:
  4428. for (i = 0; i < (full ? 4 : 2); i++)
  4429. aarch64_set_vec_s32 (cpu, vd, i,
  4430. aarch64_get_vec_s32 (cpu, vn, i)
  4431. > aarch64_get_vec_s32 (cpu, vm, i)
  4432. ? aarch64_get_vec_s32 (cpu, vn, i)
  4433. : aarch64_get_vec_s32 (cpu, vm, i));
  4434. return;
  4435. case 3:
  4436. HALT_UNALLOC;
  4437. }
  4438. }
  4439. }
  4440. static void
  4441. do_vec_min (sim_cpu *cpu)
  4442. {
  4443. /* instr[31] = 0
  4444. instr[30] = full/half selector
  4445. instr[29] = SMIN (0) / UMIN (1)
  4446. instr[28,24] = 0 1110
  4447. instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit
  4448. instr[21] = 1
  4449. instr[20,16] = Vn
  4450. instr[15,10] = 0110 11
  4451. instr[9,5] = Vm
  4452. instr[4.0] = Vd. */
  4453. unsigned vm = INSTR (20, 16);
  4454. unsigned vn = INSTR (9, 5);
  4455. unsigned vd = INSTR (4, 0);
  4456. unsigned i;
  4457. int full = INSTR (30, 30);
  4458. NYI_assert (28, 24, 0x0E);
  4459. NYI_assert (21, 21, 1);
  4460. NYI_assert (15, 10, 0x1B);
  4461. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4462. if (INSTR (29, 29))
  4463. {
  4464. switch (INSTR (23, 22))
  4465. {
  4466. case 0:
  4467. for (i = 0; i < (full ? 16 : 8); i++)
  4468. aarch64_set_vec_u8 (cpu, vd, i,
  4469. aarch64_get_vec_u8 (cpu, vn, i)
  4470. < aarch64_get_vec_u8 (cpu, vm, i)
  4471. ? aarch64_get_vec_u8 (cpu, vn, i)
  4472. : aarch64_get_vec_u8 (cpu, vm, i));
  4473. return;
  4474. case 1:
  4475. for (i = 0; i < (full ? 8 : 4); i++)
  4476. aarch64_set_vec_u16 (cpu, vd, i,
  4477. aarch64_get_vec_u16 (cpu, vn, i)
  4478. < aarch64_get_vec_u16 (cpu, vm, i)
  4479. ? aarch64_get_vec_u16 (cpu, vn, i)
  4480. : aarch64_get_vec_u16 (cpu, vm, i));
  4481. return;
  4482. case 2:
  4483. for (i = 0; i < (full ? 4 : 2); i++)
  4484. aarch64_set_vec_u32 (cpu, vd, i,
  4485. aarch64_get_vec_u32 (cpu, vn, i)
  4486. < aarch64_get_vec_u32 (cpu, vm, i)
  4487. ? aarch64_get_vec_u32 (cpu, vn, i)
  4488. : aarch64_get_vec_u32 (cpu, vm, i));
  4489. return;
  4490. case 3:
  4491. HALT_UNALLOC;
  4492. }
  4493. }
  4494. else
  4495. {
  4496. switch (INSTR (23, 22))
  4497. {
  4498. case 0:
  4499. for (i = 0; i < (full ? 16 : 8); i++)
  4500. aarch64_set_vec_s8 (cpu, vd, i,
  4501. aarch64_get_vec_s8 (cpu, vn, i)
  4502. < aarch64_get_vec_s8 (cpu, vm, i)
  4503. ? aarch64_get_vec_s8 (cpu, vn, i)
  4504. : aarch64_get_vec_s8 (cpu, vm, i));
  4505. return;
  4506. case 1:
  4507. for (i = 0; i < (full ? 8 : 4); i++)
  4508. aarch64_set_vec_s16 (cpu, vd, i,
  4509. aarch64_get_vec_s16 (cpu, vn, i)
  4510. < aarch64_get_vec_s16 (cpu, vm, i)
  4511. ? aarch64_get_vec_s16 (cpu, vn, i)
  4512. : aarch64_get_vec_s16 (cpu, vm, i));
  4513. return;
  4514. case 2:
  4515. for (i = 0; i < (full ? 4 : 2); i++)
  4516. aarch64_set_vec_s32 (cpu, vd, i,
  4517. aarch64_get_vec_s32 (cpu, vn, i)
  4518. < aarch64_get_vec_s32 (cpu, vm, i)
  4519. ? aarch64_get_vec_s32 (cpu, vn, i)
  4520. : aarch64_get_vec_s32 (cpu, vm, i));
  4521. return;
  4522. case 3:
  4523. HALT_UNALLOC;
  4524. }
  4525. }
  4526. }
  4527. static void
  4528. do_vec_sub_long (sim_cpu *cpu)
  4529. {
  4530. /* instr[31] = 0
  4531. instr[30] = lower (0) / upper (1)
  4532. instr[29] = signed (0) / unsigned (1)
  4533. instr[28,24] = 0 1110
  4534. instr[23,22] = size: bytes (00), half (01), word (10)
  4535. instr[21] = 1
  4536. insrt[20,16] = Vm
  4537. instr[15,10] = 0010 00
  4538. instr[9,5] = Vn
  4539. instr[4,0] = V dest. */
  4540. unsigned size = INSTR (23, 22);
  4541. unsigned vm = INSTR (20, 16);
  4542. unsigned vn = INSTR (9, 5);
  4543. unsigned vd = INSTR (4, 0);
  4544. unsigned bias = 0;
  4545. unsigned i;
  4546. NYI_assert (28, 24, 0x0E);
  4547. NYI_assert (21, 21, 1);
  4548. NYI_assert (15, 10, 0x08);
  4549. if (size == 3)
  4550. HALT_UNALLOC;
  4551. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4552. switch (INSTR (30, 29))
  4553. {
  4554. case 2: /* SSUBL2. */
  4555. bias = 2;
  4556. case 0: /* SSUBL. */
  4557. switch (size)
  4558. {
  4559. case 0:
  4560. bias *= 3;
  4561. for (i = 0; i < 8; i++)
  4562. aarch64_set_vec_s16 (cpu, vd, i,
  4563. aarch64_get_vec_s8 (cpu, vn, i + bias)
  4564. - aarch64_get_vec_s8 (cpu, vm, i + bias));
  4565. break;
  4566. case 1:
  4567. bias *= 2;
  4568. for (i = 0; i < 4; i++)
  4569. aarch64_set_vec_s32 (cpu, vd, i,
  4570. aarch64_get_vec_s16 (cpu, vn, i + bias)
  4571. - aarch64_get_vec_s16 (cpu, vm, i + bias));
  4572. break;
  4573. case 2:
  4574. for (i = 0; i < 2; i++)
  4575. aarch64_set_vec_s64 (cpu, vd, i,
  4576. aarch64_get_vec_s32 (cpu, vn, i + bias)
  4577. - aarch64_get_vec_s32 (cpu, vm, i + bias));
  4578. break;
  4579. default:
  4580. HALT_UNALLOC;
  4581. }
  4582. break;
  4583. case 3: /* USUBL2. */
  4584. bias = 2;
  4585. case 1: /* USUBL. */
  4586. switch (size)
  4587. {
  4588. case 0:
  4589. bias *= 3;
  4590. for (i = 0; i < 8; i++)
  4591. aarch64_set_vec_u16 (cpu, vd, i,
  4592. aarch64_get_vec_u8 (cpu, vn, i + bias)
  4593. - aarch64_get_vec_u8 (cpu, vm, i + bias));
  4594. break;
  4595. case 1:
  4596. bias *= 2;
  4597. for (i = 0; i < 4; i++)
  4598. aarch64_set_vec_u32 (cpu, vd, i,
  4599. aarch64_get_vec_u16 (cpu, vn, i + bias)
  4600. - aarch64_get_vec_u16 (cpu, vm, i + bias));
  4601. break;
  4602. case 2:
  4603. for (i = 0; i < 2; i++)
  4604. aarch64_set_vec_u64 (cpu, vd, i,
  4605. aarch64_get_vec_u32 (cpu, vn, i + bias)
  4606. - aarch64_get_vec_u32 (cpu, vm, i + bias));
  4607. break;
  4608. default:
  4609. HALT_UNALLOC;
  4610. }
  4611. break;
  4612. }
  4613. }
  4614. static void
  4615. do_vec_ADDP (sim_cpu *cpu)
  4616. {
  4617. /* instr[31] = 0
  4618. instr[30] = half(0)/full(1)
  4619. instr[29,24] = 00 1110
  4620. instr[23,22] = size: bytes (00), half (01), word (10), long (11)
  4621. instr[21] = 1
  4622. insrt[20,16] = Vm
  4623. instr[15,10] = 1011 11
  4624. instr[9,5] = Vn
  4625. instr[4,0] = V dest. */
  4626. FRegister copy_vn;
  4627. FRegister copy_vm;
  4628. unsigned full = INSTR (30, 30);
  4629. unsigned size = INSTR (23, 22);
  4630. unsigned vm = INSTR (20, 16);
  4631. unsigned vn = INSTR (9, 5);
  4632. unsigned vd = INSTR (4, 0);
  4633. unsigned i, range;
  4634. NYI_assert (29, 24, 0x0E);
  4635. NYI_assert (21, 21, 1);
  4636. NYI_assert (15, 10, 0x2F);
  4637. /* Make copies of the source registers in case vd == vn/vm. */
  4638. copy_vn = cpu->fr[vn];
  4639. copy_vm = cpu->fr[vm];
  4640. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4641. switch (size)
  4642. {
  4643. case 0:
  4644. range = full ? 8 : 4;
  4645. for (i = 0; i < range; i++)
  4646. {
  4647. aarch64_set_vec_u8 (cpu, vd, i,
  4648. copy_vn.b[i * 2] + copy_vn.b[i * 2 + 1]);
  4649. aarch64_set_vec_u8 (cpu, vd, i + range,
  4650. copy_vm.b[i * 2] + copy_vm.b[i * 2 + 1]);
  4651. }
  4652. return;
  4653. case 1:
  4654. range = full ? 4 : 2;
  4655. for (i = 0; i < range; i++)
  4656. {
  4657. aarch64_set_vec_u16 (cpu, vd, i,
  4658. copy_vn.h[i * 2] + copy_vn.h[i * 2 + 1]);
  4659. aarch64_set_vec_u16 (cpu, vd, i + range,
  4660. copy_vm.h[i * 2] + copy_vm.h[i * 2 + 1]);
  4661. }
  4662. return;
  4663. case 2:
  4664. range = full ? 2 : 1;
  4665. for (i = 0; i < range; i++)
  4666. {
  4667. aarch64_set_vec_u32 (cpu, vd, i,
  4668. copy_vn.w[i * 2] + copy_vn.w[i * 2 + 1]);
  4669. aarch64_set_vec_u32 (cpu, vd, i + range,
  4670. copy_vm.w[i * 2] + copy_vm.w[i * 2 + 1]);
  4671. }
  4672. return;
  4673. case 3:
  4674. if (! full)
  4675. HALT_UNALLOC;
  4676. aarch64_set_vec_u64 (cpu, vd, 0, copy_vn.v[0] + copy_vn.v[1]);
  4677. aarch64_set_vec_u64 (cpu, vd, 1, copy_vm.v[0] + copy_vm.v[1]);
  4678. return;
  4679. }
  4680. }
  4681. /* Float point vector convert to longer (precision). */
  4682. static void
  4683. do_vec_FCVTL (sim_cpu *cpu)
  4684. {
  4685. /* instr[31] = 0
  4686. instr[30] = half (0) / all (1)
  4687. instr[29,23] = 00 1110 0
  4688. instr[22] = single (0) / double (1)
  4689. instr[21,10] = 10 0001 0111 10
  4690. instr[9,5] = Rn
  4691. instr[4,0] = Rd. */
  4692. unsigned rn = INSTR (9, 5);
  4693. unsigned rd = INSTR (4, 0);
  4694. unsigned full = INSTR (30, 30);
  4695. unsigned i;
  4696. NYI_assert (31, 31, 0);
  4697. NYI_assert (29, 23, 0x1C);
  4698. NYI_assert (21, 10, 0x85E);
  4699. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4700. if (INSTR (22, 22))
  4701. {
  4702. for (i = 0; i < 2; i++)
  4703. aarch64_set_vec_double (cpu, rd, i,
  4704. aarch64_get_vec_float (cpu, rn, i + 2*full));
  4705. }
  4706. else
  4707. {
  4708. HALT_NYI;
  4709. #if 0
  4710. /* TODO: Implement missing half-float support. */
  4711. for (i = 0; i < 4; i++)
  4712. aarch64_set_vec_float (cpu, rd, i,
  4713. aarch64_get_vec_halffloat (cpu, rn, i + 4*full));
  4714. #endif
  4715. }
  4716. }
  4717. static void
  4718. do_vec_FABS (sim_cpu *cpu)
  4719. {
  4720. /* instr[31] = 0
  4721. instr[30] = half(0)/full(1)
  4722. instr[29,23] = 00 1110 1
  4723. instr[22] = float(0)/double(1)
  4724. instr[21,16] = 10 0000
  4725. instr[15,10] = 1111 10
  4726. instr[9,5] = Vn
  4727. instr[4,0] = Vd. */
  4728. unsigned vn = INSTR (9, 5);
  4729. unsigned vd = INSTR (4, 0);
  4730. unsigned full = INSTR (30, 30);
  4731. unsigned i;
  4732. NYI_assert (29, 23, 0x1D);
  4733. NYI_assert (21, 10, 0x83E);
  4734. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4735. if (INSTR (22, 22))
  4736. {
  4737. if (! full)
  4738. HALT_NYI;
  4739. for (i = 0; i < 2; i++)
  4740. aarch64_set_vec_double (cpu, vd, i,
  4741. fabs (aarch64_get_vec_double (cpu, vn, i)));
  4742. }
  4743. else
  4744. {
  4745. for (i = 0; i < (full ? 4 : 2); i++)
  4746. aarch64_set_vec_float (cpu, vd, i,
  4747. fabsf (aarch64_get_vec_float (cpu, vn, i)));
  4748. }
  4749. }
  4750. static void
  4751. do_vec_FCVTZS (sim_cpu *cpu)
  4752. {
  4753. /* instr[31] = 0
  4754. instr[30] = half (0) / all (1)
  4755. instr[29,23] = 00 1110 1
  4756. instr[22] = single (0) / double (1)
  4757. instr[21,10] = 10 0001 1011 10
  4758. instr[9,5] = Rn
  4759. instr[4,0] = Rd. */
  4760. unsigned rn = INSTR (9, 5);
  4761. unsigned rd = INSTR (4, 0);
  4762. unsigned full = INSTR (30, 30);
  4763. unsigned i;
  4764. NYI_assert (31, 31, 0);
  4765. NYI_assert (29, 23, 0x1D);
  4766. NYI_assert (21, 10, 0x86E);
  4767. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4768. if (INSTR (22, 22))
  4769. {
  4770. if (! full)
  4771. HALT_UNALLOC;
  4772. for (i = 0; i < 2; i++)
  4773. aarch64_set_vec_s64 (cpu, rd, i,
  4774. (int64_t) aarch64_get_vec_double (cpu, rn, i));
  4775. }
  4776. else
  4777. for (i = 0; i < (full ? 4 : 2); i++)
  4778. aarch64_set_vec_s32 (cpu, rd, i,
  4779. (int32_t) aarch64_get_vec_float (cpu, rn, i));
  4780. }
  4781. static void
  4782. do_vec_REV64 (sim_cpu *cpu)
  4783. {
  4784. /* instr[31] = 0
  4785. instr[30] = full/half
  4786. instr[29,24] = 00 1110
  4787. instr[23,22] = size
  4788. instr[21,10] = 10 0000 0000 10
  4789. instr[9,5] = Rn
  4790. instr[4,0] = Rd. */
  4791. unsigned rn = INSTR (9, 5);
  4792. unsigned rd = INSTR (4, 0);
  4793. unsigned size = INSTR (23, 22);
  4794. unsigned full = INSTR (30, 30);
  4795. unsigned i;
  4796. FRegister val;
  4797. NYI_assert (29, 24, 0x0E);
  4798. NYI_assert (21, 10, 0x802);
  4799. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4800. switch (size)
  4801. {
  4802. case 0:
  4803. for (i = 0; i < (full ? 16 : 8); i++)
  4804. val.b[i ^ 0x7] = aarch64_get_vec_u8 (cpu, rn, i);
  4805. break;
  4806. case 1:
  4807. for (i = 0; i < (full ? 8 : 4); i++)
  4808. val.h[i ^ 0x3] = aarch64_get_vec_u16 (cpu, rn, i);
  4809. break;
  4810. case 2:
  4811. for (i = 0; i < (full ? 4 : 2); i++)
  4812. val.w[i ^ 0x1] = aarch64_get_vec_u32 (cpu, rn, i);
  4813. break;
  4814. case 3:
  4815. HALT_UNALLOC;
  4816. }
  4817. aarch64_set_vec_u64 (cpu, rd, 0, val.v[0]);
  4818. if (full)
  4819. aarch64_set_vec_u64 (cpu, rd, 1, val.v[1]);
  4820. }
  4821. static void
  4822. do_vec_REV16 (sim_cpu *cpu)
  4823. {
  4824. /* instr[31] = 0
  4825. instr[30] = full/half
  4826. instr[29,24] = 00 1110
  4827. instr[23,22] = size
  4828. instr[21,10] = 10 0000 0001 10
  4829. instr[9,5] = Rn
  4830. instr[4,0] = Rd. */
  4831. unsigned rn = INSTR (9, 5);
  4832. unsigned rd = INSTR (4, 0);
  4833. unsigned size = INSTR (23, 22);
  4834. unsigned full = INSTR (30, 30);
  4835. unsigned i;
  4836. FRegister val;
  4837. NYI_assert (29, 24, 0x0E);
  4838. NYI_assert (21, 10, 0x806);
  4839. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4840. switch (size)
  4841. {
  4842. case 0:
  4843. for (i = 0; i < (full ? 16 : 8); i++)
  4844. val.b[i ^ 0x1] = aarch64_get_vec_u8 (cpu, rn, i);
  4845. break;
  4846. default:
  4847. HALT_UNALLOC;
  4848. }
  4849. aarch64_set_vec_u64 (cpu, rd, 0, val.v[0]);
  4850. if (full)
  4851. aarch64_set_vec_u64 (cpu, rd, 1, val.v[1]);
  4852. }
  4853. static void
  4854. do_vec_op1 (sim_cpu *cpu)
  4855. {
  4856. /* instr[31] = 0
  4857. instr[30] = half/full
  4858. instr[29,24] = 00 1110
  4859. instr[23,21] = ???
  4860. instr[20,16] = Vm
  4861. instr[15,10] = sub-opcode
  4862. instr[9,5] = Vn
  4863. instr[4,0] = Vd */
  4864. NYI_assert (29, 24, 0x0E);
  4865. if (INSTR (21, 21) == 0)
  4866. {
  4867. if (INSTR (23, 22) == 0)
  4868. {
  4869. if (INSTR (30, 30) == 1
  4870. && INSTR (17, 14) == 0
  4871. && INSTR (12, 10) == 7)
  4872. return do_vec_ins_2 (cpu);
  4873. switch (INSTR (15, 10))
  4874. {
  4875. case 0x01: do_vec_DUP_vector_into_vector (cpu); return;
  4876. case 0x03: do_vec_DUP_scalar_into_vector (cpu); return;
  4877. case 0x07: do_vec_INS (cpu); return;
  4878. case 0x0B: do_vec_SMOV_into_scalar (cpu); return;
  4879. case 0x0F: do_vec_UMOV_into_scalar (cpu); return;
  4880. case 0x00:
  4881. case 0x08:
  4882. case 0x10:
  4883. case 0x18:
  4884. do_vec_TBL (cpu); return;
  4885. case 0x06:
  4886. case 0x16:
  4887. do_vec_UZP (cpu); return;
  4888. case 0x0A: do_vec_TRN (cpu); return;
  4889. case 0x0E:
  4890. case 0x1E:
  4891. do_vec_ZIP (cpu); return;
  4892. default:
  4893. HALT_NYI;
  4894. }
  4895. }
  4896. switch (INSTR (13, 10))
  4897. {
  4898. case 0x6: do_vec_UZP (cpu); return;
  4899. case 0xE: do_vec_ZIP (cpu); return;
  4900. case 0xA: do_vec_TRN (cpu); return;
  4901. default: HALT_NYI;
  4902. }
  4903. }
  4904. switch (INSTR (15, 10))
  4905. {
  4906. case 0x02: do_vec_REV64 (cpu); return;
  4907. case 0x06: do_vec_REV16 (cpu); return;
  4908. case 0x07:
  4909. switch (INSTR (23, 21))
  4910. {
  4911. case 1: do_vec_AND (cpu); return;
  4912. case 3: do_vec_BIC (cpu); return;
  4913. case 5: do_vec_ORR (cpu); return;
  4914. case 7: do_vec_ORN (cpu); return;
  4915. default: HALT_NYI;
  4916. }
  4917. case 0x08: do_vec_sub_long (cpu); return;
  4918. case 0x0a: do_vec_XTN (cpu); return;
  4919. case 0x11: do_vec_SSHL (cpu); return;
  4920. case 0x16: do_vec_CNT (cpu); return;
  4921. case 0x19: do_vec_max (cpu); return;
  4922. case 0x1B: do_vec_min (cpu); return;
  4923. case 0x21: do_vec_add (cpu); return;
  4924. case 0x25: do_vec_MLA (cpu); return;
  4925. case 0x27: do_vec_mul (cpu); return;
  4926. case 0x2F: do_vec_ADDP (cpu); return;
  4927. case 0x30: do_vec_mull (cpu); return;
  4928. case 0x33: do_vec_FMLA (cpu); return;
  4929. case 0x35: do_vec_fadd (cpu); return;
  4930. case 0x1E:
  4931. switch (INSTR (20, 16))
  4932. {
  4933. case 0x01: do_vec_FCVTL (cpu); return;
  4934. default: HALT_NYI;
  4935. }
  4936. case 0x2E:
  4937. switch (INSTR (20, 16))
  4938. {
  4939. case 0x00: do_vec_ABS (cpu); return;
  4940. case 0x01: do_vec_FCVTZS (cpu); return;
  4941. case 0x11: do_vec_ADDV (cpu); return;
  4942. default: HALT_NYI;
  4943. }
  4944. case 0x31:
  4945. case 0x3B:
  4946. do_vec_Fminmax (cpu); return;
  4947. case 0x0D:
  4948. case 0x0F:
  4949. case 0x22:
  4950. case 0x23:
  4951. case 0x26:
  4952. case 0x2A:
  4953. case 0x32:
  4954. case 0x36:
  4955. case 0x39:
  4956. case 0x3A:
  4957. do_vec_compare (cpu); return;
  4958. case 0x3E:
  4959. do_vec_FABS (cpu); return;
  4960. default:
  4961. HALT_NYI;
  4962. }
  4963. }
  4964. static void
  4965. do_vec_xtl (sim_cpu *cpu)
  4966. {
  4967. /* instr[31] = 0
  4968. instr[30,29] = SXTL (00), UXTL (01), SXTL2 (10), UXTL2 (11)
  4969. instr[28,22] = 0 1111 00
  4970. instr[21,16] = size & shift (USHLL, SSHLL, USHLL2, SSHLL2)
  4971. instr[15,10] = 1010 01
  4972. instr[9,5] = V source
  4973. instr[4,0] = V dest. */
  4974. unsigned vs = INSTR (9, 5);
  4975. unsigned vd = INSTR (4, 0);
  4976. unsigned i, shift, bias = 0;
  4977. NYI_assert (28, 22, 0x3C);
  4978. NYI_assert (15, 10, 0x29);
  4979. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  4980. switch (INSTR (30, 29))
  4981. {
  4982. case 2: /* SXTL2, SSHLL2. */
  4983. bias = 2;
  4984. case 0: /* SXTL, SSHLL. */
  4985. if (INSTR (21, 21))
  4986. {
  4987. int64_t val1, val2;
  4988. shift = INSTR (20, 16);
  4989. /* Get the source values before setting the destination values
  4990. in case the source and destination are the same. */
  4991. val1 = aarch64_get_vec_s32 (cpu, vs, bias) << shift;
  4992. val2 = aarch64_get_vec_s32 (cpu, vs, bias + 1) << shift;
  4993. aarch64_set_vec_s64 (cpu, vd, 0, val1);
  4994. aarch64_set_vec_s64 (cpu, vd, 1, val2);
  4995. }
  4996. else if (INSTR (20, 20))
  4997. {
  4998. int32_t v[4];
  4999. int32_t v1,v2,v3,v4;
  5000. shift = INSTR (19, 16);
  5001. bias *= 2;
  5002. for (i = 0; i < 4; i++)
  5003. v[i] = aarch64_get_vec_s16 (cpu, vs, bias + i) << shift;
  5004. for (i = 0; i < 4; i++)
  5005. aarch64_set_vec_s32 (cpu, vd, i, v[i]);
  5006. }
  5007. else
  5008. {
  5009. int16_t v[8];
  5010. NYI_assert (19, 19, 1);
  5011. shift = INSTR (18, 16);
  5012. bias *= 4;
  5013. for (i = 0; i < 8; i++)
  5014. v[i] = aarch64_get_vec_s8 (cpu, vs, i + bias) << shift;
  5015. for (i = 0; i < 8; i++)
  5016. aarch64_set_vec_s16 (cpu, vd, i, v[i]);
  5017. }
  5018. return;
  5019. case 3: /* UXTL2, USHLL2. */
  5020. bias = 2;
  5021. case 1: /* UXTL, USHLL. */
  5022. if (INSTR (21, 21))
  5023. {
  5024. uint64_t v1, v2;
  5025. shift = INSTR (20, 16);
  5026. v1 = aarch64_get_vec_u32 (cpu, vs, bias) << shift;
  5027. v2 = aarch64_get_vec_u32 (cpu, vs, bias + 1) << shift;
  5028. aarch64_set_vec_u64 (cpu, vd, 0, v1);
  5029. aarch64_set_vec_u64 (cpu, vd, 1, v2);
  5030. }
  5031. else if (INSTR (20, 20))
  5032. {
  5033. uint32_t v[4];
  5034. shift = INSTR (19, 16);
  5035. bias *= 2;
  5036. for (i = 0; i < 4; i++)
  5037. v[i] = aarch64_get_vec_u16 (cpu, vs, i + bias) << shift;
  5038. for (i = 0; i < 4; i++)
  5039. aarch64_set_vec_u32 (cpu, vd, i, v[i]);
  5040. }
  5041. else
  5042. {
  5043. uint16_t v[8];
  5044. NYI_assert (19, 19, 1);
  5045. shift = INSTR (18, 16);
  5046. bias *= 4;
  5047. for (i = 0; i < 8; i++)
  5048. v[i] = aarch64_get_vec_u8 (cpu, vs, i + bias) << shift;
  5049. for (i = 0; i < 8; i++)
  5050. aarch64_set_vec_u16 (cpu, vd, i, v[i]);
  5051. }
  5052. return;
  5053. }
  5054. }
  5055. static void
  5056. do_vec_SHL (sim_cpu *cpu)
  5057. {
  5058. /* instr [31] = 0
  5059. instr [30] = half(0)/full(1)
  5060. instr [29,23] = 001 1110
  5061. instr [22,16] = size and shift amount
  5062. instr [15,10] = 01 0101
  5063. instr [9, 5] = Vs
  5064. instr [4, 0] = Vd. */
  5065. int shift;
  5066. int full = INSTR (30, 30);
  5067. unsigned vs = INSTR (9, 5);
  5068. unsigned vd = INSTR (4, 0);
  5069. unsigned i;
  5070. NYI_assert (29, 23, 0x1E);
  5071. NYI_assert (15, 10, 0x15);
  5072. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5073. if (INSTR (22, 22))
  5074. {
  5075. shift = INSTR (21, 16);
  5076. if (full == 0)
  5077. HALT_UNALLOC;
  5078. for (i = 0; i < 2; i++)
  5079. {
  5080. uint64_t val = aarch64_get_vec_u64 (cpu, vs, i);
  5081. aarch64_set_vec_u64 (cpu, vd, i, val << shift);
  5082. }
  5083. return;
  5084. }
  5085. if (INSTR (21, 21))
  5086. {
  5087. shift = INSTR (20, 16);
  5088. for (i = 0; i < (full ? 4 : 2); i++)
  5089. {
  5090. uint32_t val = aarch64_get_vec_u32 (cpu, vs, i);
  5091. aarch64_set_vec_u32 (cpu, vd, i, val << shift);
  5092. }
  5093. return;
  5094. }
  5095. if (INSTR (20, 20))
  5096. {
  5097. shift = INSTR (19, 16);
  5098. for (i = 0; i < (full ? 8 : 4); i++)
  5099. {
  5100. uint16_t val = aarch64_get_vec_u16 (cpu, vs, i);
  5101. aarch64_set_vec_u16 (cpu, vd, i, val << shift);
  5102. }
  5103. return;
  5104. }
  5105. if (INSTR (19, 19) == 0)
  5106. HALT_UNALLOC;
  5107. shift = INSTR (18, 16);
  5108. for (i = 0; i < (full ? 16 : 8); i++)
  5109. {
  5110. uint8_t val = aarch64_get_vec_u8 (cpu, vs, i);
  5111. aarch64_set_vec_u8 (cpu, vd, i, val << shift);
  5112. }
  5113. }
  5114. static void
  5115. do_vec_SSHR_USHR (sim_cpu *cpu)
  5116. {
  5117. /* instr [31] = 0
  5118. instr [30] = half(0)/full(1)
  5119. instr [29] = signed(0)/unsigned(1)
  5120. instr [28,23] = 0 1111 0
  5121. instr [22,16] = size and shift amount
  5122. instr [15,10] = 0000 01
  5123. instr [9, 5] = Vs
  5124. instr [4, 0] = Vd. */
  5125. int full = INSTR (30, 30);
  5126. int sign = ! INSTR (29, 29);
  5127. unsigned shift = INSTR (22, 16);
  5128. unsigned vs = INSTR (9, 5);
  5129. unsigned vd = INSTR (4, 0);
  5130. unsigned i;
  5131. NYI_assert (28, 23, 0x1E);
  5132. NYI_assert (15, 10, 0x01);
  5133. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5134. if (INSTR (22, 22))
  5135. {
  5136. shift = 128 - shift;
  5137. if (full == 0)
  5138. HALT_UNALLOC;
  5139. if (sign)
  5140. for (i = 0; i < 2; i++)
  5141. {
  5142. int64_t val = aarch64_get_vec_s64 (cpu, vs, i);
  5143. aarch64_set_vec_s64 (cpu, vd, i, val >> shift);
  5144. }
  5145. else
  5146. for (i = 0; i < 2; i++)
  5147. {
  5148. uint64_t val = aarch64_get_vec_u64 (cpu, vs, i);
  5149. aarch64_set_vec_u64 (cpu, vd, i, val >> shift);
  5150. }
  5151. return;
  5152. }
  5153. if (INSTR (21, 21))
  5154. {
  5155. shift = 64 - shift;
  5156. if (sign)
  5157. for (i = 0; i < (full ? 4 : 2); i++)
  5158. {
  5159. int32_t val = aarch64_get_vec_s32 (cpu, vs, i);
  5160. aarch64_set_vec_s32 (cpu, vd, i, val >> shift);
  5161. }
  5162. else
  5163. for (i = 0; i < (full ? 4 : 2); i++)
  5164. {
  5165. uint32_t val = aarch64_get_vec_u32 (cpu, vs, i);
  5166. aarch64_set_vec_u32 (cpu, vd, i, val >> shift);
  5167. }
  5168. return;
  5169. }
  5170. if (INSTR (20, 20))
  5171. {
  5172. shift = 32 - shift;
  5173. if (sign)
  5174. for (i = 0; i < (full ? 8 : 4); i++)
  5175. {
  5176. int16_t val = aarch64_get_vec_s16 (cpu, vs, i);
  5177. aarch64_set_vec_s16 (cpu, vd, i, val >> shift);
  5178. }
  5179. else
  5180. for (i = 0; i < (full ? 8 : 4); i++)
  5181. {
  5182. uint16_t val = aarch64_get_vec_u16 (cpu, vs, i);
  5183. aarch64_set_vec_u16 (cpu, vd, i, val >> shift);
  5184. }
  5185. return;
  5186. }
  5187. if (INSTR (19, 19) == 0)
  5188. HALT_UNALLOC;
  5189. shift = 16 - shift;
  5190. if (sign)
  5191. for (i = 0; i < (full ? 16 : 8); i++)
  5192. {
  5193. int8_t val = aarch64_get_vec_s8 (cpu, vs, i);
  5194. aarch64_set_vec_s8 (cpu, vd, i, val >> shift);
  5195. }
  5196. else
  5197. for (i = 0; i < (full ? 16 : 8); i++)
  5198. {
  5199. uint8_t val = aarch64_get_vec_u8 (cpu, vs, i);
  5200. aarch64_set_vec_u8 (cpu, vd, i, val >> shift);
  5201. }
  5202. }
  5203. static void
  5204. do_vec_MUL_by_element (sim_cpu *cpu)
  5205. {
  5206. /* instr[31] = 0
  5207. instr[30] = half/full
  5208. instr[29,24] = 00 1111
  5209. instr[23,22] = size
  5210. instr[21] = L
  5211. instr[20] = M
  5212. instr[19,16] = m
  5213. instr[15,12] = 1000
  5214. instr[11] = H
  5215. instr[10] = 0
  5216. instr[9,5] = Vn
  5217. instr[4,0] = Vd */
  5218. unsigned full = INSTR (30, 30);
  5219. unsigned L = INSTR (21, 21);
  5220. unsigned H = INSTR (11, 11);
  5221. unsigned vn = INSTR (9, 5);
  5222. unsigned vd = INSTR (4, 0);
  5223. unsigned size = INSTR (23, 22);
  5224. unsigned index;
  5225. unsigned vm;
  5226. unsigned e;
  5227. NYI_assert (29, 24, 0x0F);
  5228. NYI_assert (15, 12, 0x8);
  5229. NYI_assert (10, 10, 0);
  5230. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5231. switch (size)
  5232. {
  5233. case 1:
  5234. {
  5235. /* 16 bit products. */
  5236. uint16_t product;
  5237. uint16_t element1;
  5238. uint16_t element2;
  5239. index = (H << 2) | (L << 1) | INSTR (20, 20);
  5240. vm = INSTR (19, 16);
  5241. element2 = aarch64_get_vec_u16 (cpu, vm, index);
  5242. for (e = 0; e < (full ? 8 : 4); e ++)
  5243. {
  5244. element1 = aarch64_get_vec_u16 (cpu, vn, e);
  5245. product = element1 * element2;
  5246. aarch64_set_vec_u16 (cpu, vd, e, product);
  5247. }
  5248. }
  5249. break;
  5250. case 2:
  5251. {
  5252. /* 32 bit products. */
  5253. uint32_t product;
  5254. uint32_t element1;
  5255. uint32_t element2;
  5256. index = (H << 1) | L;
  5257. vm = INSTR (20, 16);
  5258. element2 = aarch64_get_vec_u32 (cpu, vm, index);
  5259. for (e = 0; e < (full ? 4 : 2); e ++)
  5260. {
  5261. element1 = aarch64_get_vec_u32 (cpu, vn, e);
  5262. product = element1 * element2;
  5263. aarch64_set_vec_u32 (cpu, vd, e, product);
  5264. }
  5265. }
  5266. break;
  5267. default:
  5268. HALT_UNALLOC;
  5269. }
  5270. }
  5271. static void
  5272. do_FMLA_by_element (sim_cpu *cpu)
  5273. {
  5274. /* instr[31] = 0
  5275. instr[30] = half/full
  5276. instr[29,23] = 00 1111 1
  5277. instr[22] = size
  5278. instr[21] = L
  5279. instr[20,16] = m
  5280. instr[15,12] = 0001
  5281. instr[11] = H
  5282. instr[10] = 0
  5283. instr[9,5] = Vn
  5284. instr[4,0] = Vd */
  5285. unsigned full = INSTR (30, 30);
  5286. unsigned size = INSTR (22, 22);
  5287. unsigned L = INSTR (21, 21);
  5288. unsigned vm = INSTR (20, 16);
  5289. unsigned H = INSTR (11, 11);
  5290. unsigned vn = INSTR (9, 5);
  5291. unsigned vd = INSTR (4, 0);
  5292. unsigned e;
  5293. NYI_assert (29, 23, 0x1F);
  5294. NYI_assert (15, 12, 0x1);
  5295. NYI_assert (10, 10, 0);
  5296. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5297. if (size)
  5298. {
  5299. double element1, element2;
  5300. if (! full || L)
  5301. HALT_UNALLOC;
  5302. element2 = aarch64_get_vec_double (cpu, vm, H);
  5303. for (e = 0; e < 2; e++)
  5304. {
  5305. element1 = aarch64_get_vec_double (cpu, vn, e);
  5306. element1 *= element2;
  5307. element1 += aarch64_get_vec_double (cpu, vd, e);
  5308. aarch64_set_vec_double (cpu, vd, e, element1);
  5309. }
  5310. }
  5311. else
  5312. {
  5313. float element1;
  5314. float element2 = aarch64_get_vec_float (cpu, vm, (H << 1) | L);
  5315. for (e = 0; e < (full ? 4 : 2); e++)
  5316. {
  5317. element1 = aarch64_get_vec_float (cpu, vn, e);
  5318. element1 *= element2;
  5319. element1 += aarch64_get_vec_float (cpu, vd, e);
  5320. aarch64_set_vec_float (cpu, vd, e, element1);
  5321. }
  5322. }
  5323. }
  5324. static void
  5325. do_vec_op2 (sim_cpu *cpu)
  5326. {
  5327. /* instr[31] = 0
  5328. instr[30] = half/full
  5329. instr[29,24] = 00 1111
  5330. instr[23] = ?
  5331. instr[22,16] = element size & index
  5332. instr[15,10] = sub-opcode
  5333. instr[9,5] = Vm
  5334. instr[4,0] = Vd */
  5335. NYI_assert (29, 24, 0x0F);
  5336. if (INSTR (23, 23) != 0)
  5337. {
  5338. switch (INSTR (15, 10))
  5339. {
  5340. case 0x04:
  5341. case 0x06:
  5342. do_FMLA_by_element (cpu);
  5343. return;
  5344. case 0x20:
  5345. case 0x22:
  5346. do_vec_MUL_by_element (cpu);
  5347. return;
  5348. default:
  5349. HALT_NYI;
  5350. }
  5351. }
  5352. else
  5353. {
  5354. switch (INSTR (15, 10))
  5355. {
  5356. case 0x01: do_vec_SSHR_USHR (cpu); return;
  5357. case 0x15: do_vec_SHL (cpu); return;
  5358. case 0x20:
  5359. case 0x22: do_vec_MUL_by_element (cpu); return;
  5360. case 0x29: do_vec_xtl (cpu); return;
  5361. default: HALT_NYI;
  5362. }
  5363. }
  5364. }
  5365. static void
  5366. do_vec_neg (sim_cpu *cpu)
  5367. {
  5368. /* instr[31] = 0
  5369. instr[30] = full(1)/half(0)
  5370. instr[29,24] = 10 1110
  5371. instr[23,22] = size: byte(00), half (01), word (10), long (11)
  5372. instr[21,10] = 1000 0010 1110
  5373. instr[9,5] = Vs
  5374. instr[4,0] = Vd */
  5375. int full = INSTR (30, 30);
  5376. unsigned vs = INSTR (9, 5);
  5377. unsigned vd = INSTR (4, 0);
  5378. unsigned i;
  5379. NYI_assert (29, 24, 0x2E);
  5380. NYI_assert (21, 10, 0x82E);
  5381. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5382. switch (INSTR (23, 22))
  5383. {
  5384. case 0:
  5385. for (i = 0; i < (full ? 16 : 8); i++)
  5386. aarch64_set_vec_s8 (cpu, vd, i, - aarch64_get_vec_s8 (cpu, vs, i));
  5387. return;
  5388. case 1:
  5389. for (i = 0; i < (full ? 8 : 4); i++)
  5390. aarch64_set_vec_s16 (cpu, vd, i, - aarch64_get_vec_s16 (cpu, vs, i));
  5391. return;
  5392. case 2:
  5393. for (i = 0; i < (full ? 4 : 2); i++)
  5394. aarch64_set_vec_s32 (cpu, vd, i, - aarch64_get_vec_s32 (cpu, vs, i));
  5395. return;
  5396. case 3:
  5397. if (! full)
  5398. HALT_NYI;
  5399. for (i = 0; i < 2; i++)
  5400. aarch64_set_vec_s64 (cpu, vd, i, - aarch64_get_vec_s64 (cpu, vs, i));
  5401. return;
  5402. }
  5403. }
  5404. static void
  5405. do_vec_sqrt (sim_cpu *cpu)
  5406. {
  5407. /* instr[31] = 0
  5408. instr[30] = full(1)/half(0)
  5409. instr[29,23] = 101 1101
  5410. instr[22] = single(0)/double(1)
  5411. instr[21,10] = 1000 0111 1110
  5412. instr[9,5] = Vs
  5413. instr[4,0] = Vd. */
  5414. int full = INSTR (30, 30);
  5415. unsigned vs = INSTR (9, 5);
  5416. unsigned vd = INSTR (4, 0);
  5417. unsigned i;
  5418. NYI_assert (29, 23, 0x5B);
  5419. NYI_assert (21, 10, 0x87E);
  5420. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5421. if (INSTR (22, 22) == 0)
  5422. for (i = 0; i < (full ? 4 : 2); i++)
  5423. aarch64_set_vec_float (cpu, vd, i,
  5424. sqrtf (aarch64_get_vec_float (cpu, vs, i)));
  5425. else
  5426. for (i = 0; i < 2; i++)
  5427. aarch64_set_vec_double (cpu, vd, i,
  5428. sqrt (aarch64_get_vec_double (cpu, vs, i)));
  5429. }
  5430. static void
  5431. do_vec_mls_indexed (sim_cpu *cpu)
  5432. {
  5433. /* instr[31] = 0
  5434. instr[30] = half(0)/full(1)
  5435. instr[29,24] = 10 1111
  5436. instr[23,22] = 16-bit(01)/32-bit(10)
  5437. instr[21,20+11] = index (if 16-bit)
  5438. instr[21+11] = index (if 32-bit)
  5439. instr[20,16] = Vm
  5440. instr[15,12] = 0100
  5441. instr[11] = part of index
  5442. instr[10] = 0
  5443. instr[9,5] = Vs
  5444. instr[4,0] = Vd. */
  5445. int full = INSTR (30, 30);
  5446. unsigned vs = INSTR (9, 5);
  5447. unsigned vd = INSTR (4, 0);
  5448. unsigned vm = INSTR (20, 16);
  5449. unsigned i;
  5450. NYI_assert (15, 12, 4);
  5451. NYI_assert (10, 10, 0);
  5452. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5453. switch (INSTR (23, 22))
  5454. {
  5455. case 1:
  5456. {
  5457. unsigned elem;
  5458. uint32_t val;
  5459. if (vm > 15)
  5460. HALT_NYI;
  5461. elem = (INSTR (21, 20) << 1) | INSTR (11, 11);
  5462. val = aarch64_get_vec_u16 (cpu, vm, elem);
  5463. for (i = 0; i < (full ? 8 : 4); i++)
  5464. aarch64_set_vec_u32 (cpu, vd, i,
  5465. aarch64_get_vec_u32 (cpu, vd, i) -
  5466. (aarch64_get_vec_u32 (cpu, vs, i) * val));
  5467. return;
  5468. }
  5469. case 2:
  5470. {
  5471. unsigned elem = (INSTR (21, 21) << 1) | INSTR (11, 11);
  5472. uint64_t val = aarch64_get_vec_u32 (cpu, vm, elem);
  5473. for (i = 0; i < (full ? 4 : 2); i++)
  5474. aarch64_set_vec_u64 (cpu, vd, i,
  5475. aarch64_get_vec_u64 (cpu, vd, i) -
  5476. (aarch64_get_vec_u64 (cpu, vs, i) * val));
  5477. return;
  5478. }
  5479. case 0:
  5480. case 3:
  5481. default:
  5482. HALT_NYI;
  5483. }
  5484. }
  5485. static void
  5486. do_vec_SUB (sim_cpu *cpu)
  5487. {
  5488. /* instr [31] = 0
  5489. instr [30] = half(0)/full(1)
  5490. instr [29,24] = 10 1110
  5491. instr [23,22] = size: byte(00, half(01), word (10), long (11)
  5492. instr [21] = 1
  5493. instr [20,16] = Vm
  5494. instr [15,10] = 10 0001
  5495. instr [9, 5] = Vn
  5496. instr [4, 0] = Vd. */
  5497. unsigned full = INSTR (30, 30);
  5498. unsigned vm = INSTR (20, 16);
  5499. unsigned vn = INSTR (9, 5);
  5500. unsigned vd = INSTR (4, 0);
  5501. unsigned i;
  5502. NYI_assert (29, 24, 0x2E);
  5503. NYI_assert (21, 21, 1);
  5504. NYI_assert (15, 10, 0x21);
  5505. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5506. switch (INSTR (23, 22))
  5507. {
  5508. case 0:
  5509. for (i = 0; i < (full ? 16 : 8); i++)
  5510. aarch64_set_vec_s8 (cpu, vd, i,
  5511. aarch64_get_vec_s8 (cpu, vn, i)
  5512. - aarch64_get_vec_s8 (cpu, vm, i));
  5513. return;
  5514. case 1:
  5515. for (i = 0; i < (full ? 8 : 4); i++)
  5516. aarch64_set_vec_s16 (cpu, vd, i,
  5517. aarch64_get_vec_s16 (cpu, vn, i)
  5518. - aarch64_get_vec_s16 (cpu, vm, i));
  5519. return;
  5520. case 2:
  5521. for (i = 0; i < (full ? 4 : 2); i++)
  5522. aarch64_set_vec_s32 (cpu, vd, i,
  5523. aarch64_get_vec_s32 (cpu, vn, i)
  5524. - aarch64_get_vec_s32 (cpu, vm, i));
  5525. return;
  5526. case 3:
  5527. if (full == 0)
  5528. HALT_UNALLOC;
  5529. for (i = 0; i < 2; i++)
  5530. aarch64_set_vec_s64 (cpu, vd, i,
  5531. aarch64_get_vec_s64 (cpu, vn, i)
  5532. - aarch64_get_vec_s64 (cpu, vm, i));
  5533. return;
  5534. }
  5535. }
  5536. static void
  5537. do_vec_MLS (sim_cpu *cpu)
  5538. {
  5539. /* instr [31] = 0
  5540. instr [30] = half(0)/full(1)
  5541. instr [29,24] = 10 1110
  5542. instr [23,22] = size: byte(00, half(01), word (10)
  5543. instr [21] = 1
  5544. instr [20,16] = Vm
  5545. instr [15,10] = 10 0101
  5546. instr [9, 5] = Vn
  5547. instr [4, 0] = Vd. */
  5548. unsigned full = INSTR (30, 30);
  5549. unsigned vm = INSTR (20, 16);
  5550. unsigned vn = INSTR (9, 5);
  5551. unsigned vd = INSTR (4, 0);
  5552. unsigned i;
  5553. NYI_assert (29, 24, 0x2E);
  5554. NYI_assert (21, 21, 1);
  5555. NYI_assert (15, 10, 0x25);
  5556. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5557. switch (INSTR (23, 22))
  5558. {
  5559. case 0:
  5560. for (i = 0; i < (full ? 16 : 8); i++)
  5561. aarch64_set_vec_u8 (cpu, vd, i,
  5562. aarch64_get_vec_u8 (cpu, vd, i)
  5563. - (aarch64_get_vec_u8 (cpu, vn, i)
  5564. * aarch64_get_vec_u8 (cpu, vm, i)));
  5565. return;
  5566. case 1:
  5567. for (i = 0; i < (full ? 8 : 4); i++)
  5568. aarch64_set_vec_u16 (cpu, vd, i,
  5569. aarch64_get_vec_u16 (cpu, vd, i)
  5570. - (aarch64_get_vec_u16 (cpu, vn, i)
  5571. * aarch64_get_vec_u16 (cpu, vm, i)));
  5572. return;
  5573. case 2:
  5574. for (i = 0; i < (full ? 4 : 2); i++)
  5575. aarch64_set_vec_u32 (cpu, vd, i,
  5576. aarch64_get_vec_u32 (cpu, vd, i)
  5577. - (aarch64_get_vec_u32 (cpu, vn, i)
  5578. * aarch64_get_vec_u32 (cpu, vm, i)));
  5579. return;
  5580. default:
  5581. HALT_UNALLOC;
  5582. }
  5583. }
  5584. static void
  5585. do_vec_FDIV (sim_cpu *cpu)
  5586. {
  5587. /* instr [31] = 0
  5588. instr [30] = half(0)/full(1)
  5589. instr [29,23] = 10 1110 0
  5590. instr [22] = float()/double(1)
  5591. instr [21] = 1
  5592. instr [20,16] = Vm
  5593. instr [15,10] = 1111 11
  5594. instr [9, 5] = Vn
  5595. instr [4, 0] = Vd. */
  5596. unsigned full = INSTR (30, 30);
  5597. unsigned vm = INSTR (20, 16);
  5598. unsigned vn = INSTR (9, 5);
  5599. unsigned vd = INSTR (4, 0);
  5600. unsigned i;
  5601. NYI_assert (29, 23, 0x5C);
  5602. NYI_assert (21, 21, 1);
  5603. NYI_assert (15, 10, 0x3F);
  5604. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5605. if (INSTR (22, 22))
  5606. {
  5607. if (! full)
  5608. HALT_UNALLOC;
  5609. for (i = 0; i < 2; i++)
  5610. aarch64_set_vec_double (cpu, vd, i,
  5611. aarch64_get_vec_double (cpu, vn, i)
  5612. / aarch64_get_vec_double (cpu, vm, i));
  5613. }
  5614. else
  5615. for (i = 0; i < (full ? 4 : 2); i++)
  5616. aarch64_set_vec_float (cpu, vd, i,
  5617. aarch64_get_vec_float (cpu, vn, i)
  5618. / aarch64_get_vec_float (cpu, vm, i));
  5619. }
  5620. static void
  5621. do_vec_FMUL (sim_cpu *cpu)
  5622. {
  5623. /* instr [31] = 0
  5624. instr [30] = half(0)/full(1)
  5625. instr [29,23] = 10 1110 0
  5626. instr [22] = float(0)/double(1)
  5627. instr [21] = 1
  5628. instr [20,16] = Vm
  5629. instr [15,10] = 1101 11
  5630. instr [9, 5] = Vn
  5631. instr [4, 0] = Vd. */
  5632. unsigned full = INSTR (30, 30);
  5633. unsigned vm = INSTR (20, 16);
  5634. unsigned vn = INSTR (9, 5);
  5635. unsigned vd = INSTR (4, 0);
  5636. unsigned i;
  5637. NYI_assert (29, 23, 0x5C);
  5638. NYI_assert (21, 21, 1);
  5639. NYI_assert (15, 10, 0x37);
  5640. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5641. if (INSTR (22, 22))
  5642. {
  5643. if (! full)
  5644. HALT_UNALLOC;
  5645. for (i = 0; i < 2; i++)
  5646. aarch64_set_vec_double (cpu, vd, i,
  5647. aarch64_get_vec_double (cpu, vn, i)
  5648. * aarch64_get_vec_double (cpu, vm, i));
  5649. }
  5650. else
  5651. for (i = 0; i < (full ? 4 : 2); i++)
  5652. aarch64_set_vec_float (cpu, vd, i,
  5653. aarch64_get_vec_float (cpu, vn, i)
  5654. * aarch64_get_vec_float (cpu, vm, i));
  5655. }
  5656. static void
  5657. do_vec_FADDP (sim_cpu *cpu)
  5658. {
  5659. /* instr [31] = 0
  5660. instr [30] = half(0)/full(1)
  5661. instr [29,23] = 10 1110 0
  5662. instr [22] = float(0)/double(1)
  5663. instr [21] = 1
  5664. instr [20,16] = Vm
  5665. instr [15,10] = 1101 01
  5666. instr [9, 5] = Vn
  5667. instr [4, 0] = Vd. */
  5668. unsigned full = INSTR (30, 30);
  5669. unsigned vm = INSTR (20, 16);
  5670. unsigned vn = INSTR (9, 5);
  5671. unsigned vd = INSTR (4, 0);
  5672. NYI_assert (29, 23, 0x5C);
  5673. NYI_assert (21, 21, 1);
  5674. NYI_assert (15, 10, 0x35);
  5675. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5676. if (INSTR (22, 22))
  5677. {
  5678. /* Extract values before adding them incase vd == vn/vm. */
  5679. double tmp1 = aarch64_get_vec_double (cpu, vn, 0);
  5680. double tmp2 = aarch64_get_vec_double (cpu, vn, 1);
  5681. double tmp3 = aarch64_get_vec_double (cpu, vm, 0);
  5682. double tmp4 = aarch64_get_vec_double (cpu, vm, 1);
  5683. if (! full)
  5684. HALT_UNALLOC;
  5685. aarch64_set_vec_double (cpu, vd, 0, tmp1 + tmp2);
  5686. aarch64_set_vec_double (cpu, vd, 1, tmp3 + tmp4);
  5687. }
  5688. else
  5689. {
  5690. /* Extract values before adding them incase vd == vn/vm. */
  5691. float tmp1 = aarch64_get_vec_float (cpu, vn, 0);
  5692. float tmp2 = aarch64_get_vec_float (cpu, vn, 1);
  5693. float tmp5 = aarch64_get_vec_float (cpu, vm, 0);
  5694. float tmp6 = aarch64_get_vec_float (cpu, vm, 1);
  5695. if (full)
  5696. {
  5697. float tmp3 = aarch64_get_vec_float (cpu, vn, 2);
  5698. float tmp4 = aarch64_get_vec_float (cpu, vn, 3);
  5699. float tmp7 = aarch64_get_vec_float (cpu, vm, 2);
  5700. float tmp8 = aarch64_get_vec_float (cpu, vm, 3);
  5701. aarch64_set_vec_float (cpu, vd, 0, tmp1 + tmp2);
  5702. aarch64_set_vec_float (cpu, vd, 1, tmp3 + tmp4);
  5703. aarch64_set_vec_float (cpu, vd, 2, tmp5 + tmp6);
  5704. aarch64_set_vec_float (cpu, vd, 3, tmp7 + tmp8);
  5705. }
  5706. else
  5707. {
  5708. aarch64_set_vec_float (cpu, vd, 0, tmp1 + tmp2);
  5709. aarch64_set_vec_float (cpu, vd, 1, tmp5 + tmp6);
  5710. }
  5711. }
  5712. }
  5713. static void
  5714. do_vec_FSQRT (sim_cpu *cpu)
  5715. {
  5716. /* instr[31] = 0
  5717. instr[30] = half(0)/full(1)
  5718. instr[29,23] = 10 1110 1
  5719. instr[22] = single(0)/double(1)
  5720. instr[21,10] = 10 0001 1111 10
  5721. instr[9,5] = Vsrc
  5722. instr[4,0] = Vdest. */
  5723. unsigned vn = INSTR (9, 5);
  5724. unsigned vd = INSTR (4, 0);
  5725. unsigned full = INSTR (30, 30);
  5726. int i;
  5727. NYI_assert (29, 23, 0x5D);
  5728. NYI_assert (21, 10, 0x87E);
  5729. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5730. if (INSTR (22, 22))
  5731. {
  5732. if (! full)
  5733. HALT_UNALLOC;
  5734. for (i = 0; i < 2; i++)
  5735. aarch64_set_vec_double (cpu, vd, i,
  5736. sqrt (aarch64_get_vec_double (cpu, vn, i)));
  5737. }
  5738. else
  5739. {
  5740. for (i = 0; i < (full ? 4 : 2); i++)
  5741. aarch64_set_vec_float (cpu, vd, i,
  5742. sqrtf (aarch64_get_vec_float (cpu, vn, i)));
  5743. }
  5744. }
  5745. static void
  5746. do_vec_FNEG (sim_cpu *cpu)
  5747. {
  5748. /* instr[31] = 0
  5749. instr[30] = half (0)/full (1)
  5750. instr[29,23] = 10 1110 1
  5751. instr[22] = single (0)/double (1)
  5752. instr[21,10] = 10 0000 1111 10
  5753. instr[9,5] = Vsrc
  5754. instr[4,0] = Vdest. */
  5755. unsigned vn = INSTR (9, 5);
  5756. unsigned vd = INSTR (4, 0);
  5757. unsigned full = INSTR (30, 30);
  5758. int i;
  5759. NYI_assert (29, 23, 0x5D);
  5760. NYI_assert (21, 10, 0x83E);
  5761. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5762. if (INSTR (22, 22))
  5763. {
  5764. if (! full)
  5765. HALT_UNALLOC;
  5766. for (i = 0; i < 2; i++)
  5767. aarch64_set_vec_double (cpu, vd, i,
  5768. - aarch64_get_vec_double (cpu, vn, i));
  5769. }
  5770. else
  5771. {
  5772. for (i = 0; i < (full ? 4 : 2); i++)
  5773. aarch64_set_vec_float (cpu, vd, i,
  5774. - aarch64_get_vec_float (cpu, vn, i));
  5775. }
  5776. }
  5777. static void
  5778. do_vec_NOT (sim_cpu *cpu)
  5779. {
  5780. /* instr[31] = 0
  5781. instr[30] = half (0)/full (1)
  5782. instr[29,10] = 10 1110 0010 0000 0101 10
  5783. instr[9,5] = Vn
  5784. instr[4.0] = Vd. */
  5785. unsigned vn = INSTR (9, 5);
  5786. unsigned vd = INSTR (4, 0);
  5787. unsigned i;
  5788. int full = INSTR (30, 30);
  5789. NYI_assert (29, 10, 0xB8816);
  5790. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5791. for (i = 0; i < (full ? 16 : 8); i++)
  5792. aarch64_set_vec_u8 (cpu, vd, i, ~ aarch64_get_vec_u8 (cpu, vn, i));
  5793. }
  5794. static unsigned int
  5795. clz (uint64_t val, unsigned size)
  5796. {
  5797. uint64_t mask = 1;
  5798. int count;
  5799. mask <<= (size - 1);
  5800. count = 0;
  5801. do
  5802. {
  5803. if (val & mask)
  5804. break;
  5805. mask >>= 1;
  5806. count ++;
  5807. }
  5808. while (mask);
  5809. return count;
  5810. }
  5811. static void
  5812. do_vec_CLZ (sim_cpu *cpu)
  5813. {
  5814. /* instr[31] = 0
  5815. instr[30] = half (0)/full (1)
  5816. instr[29,24] = 10 1110
  5817. instr[23,22] = size
  5818. instr[21,10] = 10 0000 0100 10
  5819. instr[9,5] = Vn
  5820. instr[4.0] = Vd. */
  5821. unsigned vn = INSTR (9, 5);
  5822. unsigned vd = INSTR (4, 0);
  5823. unsigned i;
  5824. int full = INSTR (30,30);
  5825. NYI_assert (29, 24, 0x2E);
  5826. NYI_assert (21, 10, 0x812);
  5827. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5828. switch (INSTR (23, 22))
  5829. {
  5830. case 0:
  5831. for (i = 0; i < (full ? 16 : 8); i++)
  5832. aarch64_set_vec_u8 (cpu, vd, i, clz (aarch64_get_vec_u8 (cpu, vn, i), 8));
  5833. break;
  5834. case 1:
  5835. for (i = 0; i < (full ? 8 : 4); i++)
  5836. aarch64_set_vec_u16 (cpu, vd, i, clz (aarch64_get_vec_u16 (cpu, vn, i), 16));
  5837. break;
  5838. case 2:
  5839. for (i = 0; i < (full ? 4 : 2); i++)
  5840. aarch64_set_vec_u32 (cpu, vd, i, clz (aarch64_get_vec_u32 (cpu, vn, i), 32));
  5841. break;
  5842. case 3:
  5843. if (! full)
  5844. HALT_UNALLOC;
  5845. aarch64_set_vec_u64 (cpu, vd, 0, clz (aarch64_get_vec_u64 (cpu, vn, 0), 64));
  5846. aarch64_set_vec_u64 (cpu, vd, 1, clz (aarch64_get_vec_u64 (cpu, vn, 1), 64));
  5847. break;
  5848. }
  5849. }
  5850. static void
  5851. do_vec_MOV_element (sim_cpu *cpu)
  5852. {
  5853. /* instr[31,21] = 0110 1110 000
  5854. instr[20,16] = size & dest index
  5855. instr[15] = 0
  5856. instr[14,11] = source index
  5857. instr[10] = 1
  5858. instr[9,5] = Vs
  5859. instr[4.0] = Vd. */
  5860. unsigned vs = INSTR (9, 5);
  5861. unsigned vd = INSTR (4, 0);
  5862. unsigned src_index;
  5863. unsigned dst_index;
  5864. NYI_assert (31, 21, 0x370);
  5865. NYI_assert (15, 15, 0);
  5866. NYI_assert (10, 10, 1);
  5867. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5868. if (INSTR (16, 16))
  5869. {
  5870. /* Move a byte. */
  5871. src_index = INSTR (14, 11);
  5872. dst_index = INSTR (20, 17);
  5873. aarch64_set_vec_u8 (cpu, vd, dst_index,
  5874. aarch64_get_vec_u8 (cpu, vs, src_index));
  5875. }
  5876. else if (INSTR (17, 17))
  5877. {
  5878. /* Move 16-bits. */
  5879. NYI_assert (11, 11, 0);
  5880. src_index = INSTR (14, 12);
  5881. dst_index = INSTR (20, 18);
  5882. aarch64_set_vec_u16 (cpu, vd, dst_index,
  5883. aarch64_get_vec_u16 (cpu, vs, src_index));
  5884. }
  5885. else if (INSTR (18, 18))
  5886. {
  5887. /* Move 32-bits. */
  5888. NYI_assert (12, 11, 0);
  5889. src_index = INSTR (14, 13);
  5890. dst_index = INSTR (20, 19);
  5891. aarch64_set_vec_u32 (cpu, vd, dst_index,
  5892. aarch64_get_vec_u32 (cpu, vs, src_index));
  5893. }
  5894. else
  5895. {
  5896. NYI_assert (19, 19, 1);
  5897. NYI_assert (13, 11, 0);
  5898. src_index = INSTR (14, 14);
  5899. dst_index = INSTR (20, 20);
  5900. aarch64_set_vec_u64 (cpu, vd, dst_index,
  5901. aarch64_get_vec_u64 (cpu, vs, src_index));
  5902. }
  5903. }
  5904. static void
  5905. do_vec_REV32 (sim_cpu *cpu)
  5906. {
  5907. /* instr[31] = 0
  5908. instr[30] = full/half
  5909. instr[29,24] = 10 1110
  5910. instr[23,22] = size
  5911. instr[21,10] = 10 0000 0000 10
  5912. instr[9,5] = Rn
  5913. instr[4,0] = Rd. */
  5914. unsigned rn = INSTR (9, 5);
  5915. unsigned rd = INSTR (4, 0);
  5916. unsigned size = INSTR (23, 22);
  5917. unsigned full = INSTR (30, 30);
  5918. unsigned i;
  5919. FRegister val;
  5920. NYI_assert (29, 24, 0x2E);
  5921. NYI_assert (21, 10, 0x802);
  5922. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5923. switch (size)
  5924. {
  5925. case 0:
  5926. for (i = 0; i < (full ? 16 : 8); i++)
  5927. val.b[i ^ 0x3] = aarch64_get_vec_u8 (cpu, rn, i);
  5928. break;
  5929. case 1:
  5930. for (i = 0; i < (full ? 8 : 4); i++)
  5931. val.h[i ^ 0x1] = aarch64_get_vec_u16 (cpu, rn, i);
  5932. break;
  5933. default:
  5934. HALT_UNALLOC;
  5935. }
  5936. aarch64_set_vec_u64 (cpu, rd, 0, val.v[0]);
  5937. if (full)
  5938. aarch64_set_vec_u64 (cpu, rd, 1, val.v[1]);
  5939. }
  5940. static void
  5941. do_vec_EXT (sim_cpu *cpu)
  5942. {
  5943. /* instr[31] = 0
  5944. instr[30] = full/half
  5945. instr[29,21] = 10 1110 000
  5946. instr[20,16] = Vm
  5947. instr[15] = 0
  5948. instr[14,11] = source index
  5949. instr[10] = 0
  5950. instr[9,5] = Vn
  5951. instr[4.0] = Vd. */
  5952. unsigned vm = INSTR (20, 16);
  5953. unsigned vn = INSTR (9, 5);
  5954. unsigned vd = INSTR (4, 0);
  5955. unsigned src_index = INSTR (14, 11);
  5956. unsigned full = INSTR (30, 30);
  5957. unsigned i;
  5958. unsigned j;
  5959. FRegister val;
  5960. NYI_assert (31, 21, 0x370);
  5961. NYI_assert (15, 15, 0);
  5962. NYI_assert (10, 10, 0);
  5963. if (!full && (src_index & 0x8))
  5964. HALT_UNALLOC;
  5965. j = 0;
  5966. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  5967. for (i = src_index; i < (full ? 16 : 8); i++)
  5968. val.b[j ++] = aarch64_get_vec_u8 (cpu, vn, i);
  5969. for (i = 0; i < src_index; i++)
  5970. val.b[j ++] = aarch64_get_vec_u8 (cpu, vm, i);
  5971. aarch64_set_vec_u64 (cpu, vd, 0, val.v[0]);
  5972. if (full)
  5973. aarch64_set_vec_u64 (cpu, vd, 1, val.v[1]);
  5974. }
  5975. static void
  5976. dexAdvSIMD0 (sim_cpu *cpu)
  5977. {
  5978. /* instr [28,25] = 0 111. */
  5979. if ( INSTR (15, 10) == 0x07
  5980. && (INSTR (9, 5) ==
  5981. INSTR (20, 16)))
  5982. {
  5983. if (INSTR (31, 21) == 0x075
  5984. || INSTR (31, 21) == 0x275)
  5985. {
  5986. do_vec_MOV_whole_vector (cpu);
  5987. return;
  5988. }
  5989. }
  5990. if (INSTR (29, 19) == 0x1E0)
  5991. {
  5992. do_vec_MOV_immediate (cpu);
  5993. return;
  5994. }
  5995. if (INSTR (29, 19) == 0x5E0)
  5996. {
  5997. do_vec_MVNI (cpu);
  5998. return;
  5999. }
  6000. if (INSTR (29, 19) == 0x1C0
  6001. || INSTR (29, 19) == 0x1C1)
  6002. {
  6003. if (INSTR (15, 10) == 0x03)
  6004. {
  6005. do_vec_DUP_scalar_into_vector (cpu);
  6006. return;
  6007. }
  6008. }
  6009. switch (INSTR (29, 24))
  6010. {
  6011. case 0x0E: do_vec_op1 (cpu); return;
  6012. case 0x0F: do_vec_op2 (cpu); return;
  6013. case 0x2E:
  6014. if (INSTR (21, 21) == 1)
  6015. {
  6016. switch (INSTR (15, 10))
  6017. {
  6018. case 0x02:
  6019. do_vec_REV32 (cpu);
  6020. return;
  6021. case 0x07:
  6022. switch (INSTR (23, 22))
  6023. {
  6024. case 0: do_vec_EOR (cpu); return;
  6025. case 1: do_vec_BSL (cpu); return;
  6026. case 2:
  6027. case 3: do_vec_bit (cpu); return;
  6028. }
  6029. break;
  6030. case 0x08: do_vec_sub_long (cpu); return;
  6031. case 0x11: do_vec_USHL (cpu); return;
  6032. case 0x12: do_vec_CLZ (cpu); return;
  6033. case 0x16: do_vec_NOT (cpu); return;
  6034. case 0x19: do_vec_max (cpu); return;
  6035. case 0x1B: do_vec_min (cpu); return;
  6036. case 0x21: do_vec_SUB (cpu); return;
  6037. case 0x25: do_vec_MLS (cpu); return;
  6038. case 0x31: do_vec_FminmaxNMP (cpu); return;
  6039. case 0x35: do_vec_FADDP (cpu); return;
  6040. case 0x37: do_vec_FMUL (cpu); return;
  6041. case 0x3F: do_vec_FDIV (cpu); return;
  6042. case 0x3E:
  6043. switch (INSTR (20, 16))
  6044. {
  6045. case 0x00: do_vec_FNEG (cpu); return;
  6046. case 0x01: do_vec_FSQRT (cpu); return;
  6047. default: HALT_NYI;
  6048. }
  6049. case 0x0D:
  6050. case 0x0F:
  6051. case 0x22:
  6052. case 0x23:
  6053. case 0x26:
  6054. case 0x2A:
  6055. case 0x32:
  6056. case 0x36:
  6057. case 0x39:
  6058. case 0x3A:
  6059. do_vec_compare (cpu); return;
  6060. default:
  6061. break;
  6062. }
  6063. }
  6064. if (INSTR (31, 21) == 0x370)
  6065. {
  6066. if (INSTR (10, 10))
  6067. do_vec_MOV_element (cpu);
  6068. else
  6069. do_vec_EXT (cpu);
  6070. return;
  6071. }
  6072. switch (INSTR (21, 10))
  6073. {
  6074. case 0x82E: do_vec_neg (cpu); return;
  6075. case 0x87E: do_vec_sqrt (cpu); return;
  6076. default:
  6077. if (INSTR (15, 10) == 0x30)
  6078. {
  6079. do_vec_mull (cpu);
  6080. return;
  6081. }
  6082. break;
  6083. }
  6084. break;
  6085. case 0x2f:
  6086. switch (INSTR (15, 10))
  6087. {
  6088. case 0x01: do_vec_SSHR_USHR (cpu); return;
  6089. case 0x10:
  6090. case 0x12: do_vec_mls_indexed (cpu); return;
  6091. case 0x29: do_vec_xtl (cpu); return;
  6092. default:
  6093. HALT_NYI;
  6094. }
  6095. default:
  6096. break;
  6097. }
  6098. HALT_NYI;
  6099. }
  6100. /* 3 sources. */
  6101. /* Float multiply add. */
  6102. static void
  6103. fmadds (sim_cpu *cpu)
  6104. {
  6105. unsigned sa = INSTR (14, 10);
  6106. unsigned sm = INSTR (20, 16);
  6107. unsigned sn = INSTR ( 9, 5);
  6108. unsigned sd = INSTR ( 4, 0);
  6109. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6110. aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sa)
  6111. + aarch64_get_FP_float (cpu, sn)
  6112. * aarch64_get_FP_float (cpu, sm));
  6113. }
  6114. /* Double multiply add. */
  6115. static void
  6116. fmaddd (sim_cpu *cpu)
  6117. {
  6118. unsigned sa = INSTR (14, 10);
  6119. unsigned sm = INSTR (20, 16);
  6120. unsigned sn = INSTR ( 9, 5);
  6121. unsigned sd = INSTR ( 4, 0);
  6122. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6123. aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sa)
  6124. + aarch64_get_FP_double (cpu, sn)
  6125. * aarch64_get_FP_double (cpu, sm));
  6126. }
  6127. /* Float multiply subtract. */
  6128. static void
  6129. fmsubs (sim_cpu *cpu)
  6130. {
  6131. unsigned sa = INSTR (14, 10);
  6132. unsigned sm = INSTR (20, 16);
  6133. unsigned sn = INSTR ( 9, 5);
  6134. unsigned sd = INSTR ( 4, 0);
  6135. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6136. aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sa)
  6137. - aarch64_get_FP_float (cpu, sn)
  6138. * aarch64_get_FP_float (cpu, sm));
  6139. }
  6140. /* Double multiply subtract. */
  6141. static void
  6142. fmsubd (sim_cpu *cpu)
  6143. {
  6144. unsigned sa = INSTR (14, 10);
  6145. unsigned sm = INSTR (20, 16);
  6146. unsigned sn = INSTR ( 9, 5);
  6147. unsigned sd = INSTR ( 4, 0);
  6148. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6149. aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sa)
  6150. - aarch64_get_FP_double (cpu, sn)
  6151. * aarch64_get_FP_double (cpu, sm));
  6152. }
  6153. /* Float negative multiply add. */
  6154. static void
  6155. fnmadds (sim_cpu *cpu)
  6156. {
  6157. unsigned sa = INSTR (14, 10);
  6158. unsigned sm = INSTR (20, 16);
  6159. unsigned sn = INSTR ( 9, 5);
  6160. unsigned sd = INSTR ( 4, 0);
  6161. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6162. aarch64_set_FP_float (cpu, sd, - aarch64_get_FP_float (cpu, sa)
  6163. + (- aarch64_get_FP_float (cpu, sn))
  6164. * aarch64_get_FP_float (cpu, sm));
  6165. }
  6166. /* Double negative multiply add. */
  6167. static void
  6168. fnmaddd (sim_cpu *cpu)
  6169. {
  6170. unsigned sa = INSTR (14, 10);
  6171. unsigned sm = INSTR (20, 16);
  6172. unsigned sn = INSTR ( 9, 5);
  6173. unsigned sd = INSTR ( 4, 0);
  6174. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6175. aarch64_set_FP_double (cpu, sd, - aarch64_get_FP_double (cpu, sa)
  6176. + (- aarch64_get_FP_double (cpu, sn))
  6177. * aarch64_get_FP_double (cpu, sm));
  6178. }
  6179. /* Float negative multiply subtract. */
  6180. static void
  6181. fnmsubs (sim_cpu *cpu)
  6182. {
  6183. unsigned sa = INSTR (14, 10);
  6184. unsigned sm = INSTR (20, 16);
  6185. unsigned sn = INSTR ( 9, 5);
  6186. unsigned sd = INSTR ( 4, 0);
  6187. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6188. aarch64_set_FP_float (cpu, sd, - aarch64_get_FP_float (cpu, sa)
  6189. + aarch64_get_FP_float (cpu, sn)
  6190. * aarch64_get_FP_float (cpu, sm));
  6191. }
  6192. /* Double negative multiply subtract. */
  6193. static void
  6194. fnmsubd (sim_cpu *cpu)
  6195. {
  6196. unsigned sa = INSTR (14, 10);
  6197. unsigned sm = INSTR (20, 16);
  6198. unsigned sn = INSTR ( 9, 5);
  6199. unsigned sd = INSTR ( 4, 0);
  6200. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6201. aarch64_set_FP_double (cpu, sd, - aarch64_get_FP_double (cpu, sa)
  6202. + aarch64_get_FP_double (cpu, sn)
  6203. * aarch64_get_FP_double (cpu, sm));
  6204. }
  6205. static void
  6206. dexSimpleFPDataProc3Source (sim_cpu *cpu)
  6207. {
  6208. /* instr[31] ==> M : 0 ==> OK, 1 ==> UNALLOC
  6209. instr[30] = 0
  6210. instr[29] ==> S : 0 ==> OK, 1 ==> UNALLOC
  6211. instr[28,25] = 1111
  6212. instr[24] = 1
  6213. instr[23,22] ==> type : 0 ==> single, 01 ==> double, 1x ==> UNALLOC
  6214. instr[21] ==> o1 : 0 ==> unnegated, 1 ==> negated
  6215. instr[15] ==> o2 : 0 ==> ADD, 1 ==> SUB */
  6216. uint32_t M_S = (INSTR (31, 31) << 1) | INSTR (29, 29);
  6217. /* dispatch on combined type:o1:o2. */
  6218. uint32_t dispatch = (INSTR (23, 21) << 1) | INSTR (15, 15);
  6219. if (M_S != 0)
  6220. HALT_UNALLOC;
  6221. switch (dispatch)
  6222. {
  6223. case 0: fmadds (cpu); return;
  6224. case 1: fmsubs (cpu); return;
  6225. case 2: fnmadds (cpu); return;
  6226. case 3: fnmsubs (cpu); return;
  6227. case 4: fmaddd (cpu); return;
  6228. case 5: fmsubd (cpu); return;
  6229. case 6: fnmaddd (cpu); return;
  6230. case 7: fnmsubd (cpu); return;
  6231. default:
  6232. /* type > 1 is currently unallocated. */
  6233. HALT_UNALLOC;
  6234. }
  6235. }
  6236. static void
  6237. dexSimpleFPFixedConvert (sim_cpu *cpu)
  6238. {
  6239. HALT_NYI;
  6240. }
  6241. static void
  6242. dexSimpleFPCondCompare (sim_cpu *cpu)
  6243. {
  6244. /* instr [31,23] = 0001 1110 0
  6245. instr [22] = type
  6246. instr [21] = 1
  6247. instr [20,16] = Rm
  6248. instr [15,12] = condition
  6249. instr [11,10] = 01
  6250. instr [9,5] = Rn
  6251. instr [4] = 0
  6252. instr [3,0] = nzcv */
  6253. unsigned rm = INSTR (20, 16);
  6254. unsigned rn = INSTR (9, 5);
  6255. NYI_assert (31, 23, 0x3C);
  6256. NYI_assert (11, 10, 0x1);
  6257. NYI_assert (4, 4, 0);
  6258. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6259. if (! testConditionCode (cpu, INSTR (15, 12)))
  6260. {
  6261. aarch64_set_CPSR (cpu, INSTR (3, 0));
  6262. return;
  6263. }
  6264. if (INSTR (22, 22))
  6265. {
  6266. /* Double precision. */
  6267. double val1 = aarch64_get_vec_double (cpu, rn, 0);
  6268. double val2 = aarch64_get_vec_double (cpu, rm, 0);
  6269. /* FIXME: Check for NaNs. */
  6270. if (val1 == val2)
  6271. aarch64_set_CPSR (cpu, (Z | C));
  6272. else if (val1 < val2)
  6273. aarch64_set_CPSR (cpu, N);
  6274. else /* val1 > val2 */
  6275. aarch64_set_CPSR (cpu, C);
  6276. }
  6277. else
  6278. {
  6279. /* Single precision. */
  6280. float val1 = aarch64_get_vec_float (cpu, rn, 0);
  6281. float val2 = aarch64_get_vec_float (cpu, rm, 0);
  6282. /* FIXME: Check for NaNs. */
  6283. if (val1 == val2)
  6284. aarch64_set_CPSR (cpu, (Z | C));
  6285. else if (val1 < val2)
  6286. aarch64_set_CPSR (cpu, N);
  6287. else /* val1 > val2 */
  6288. aarch64_set_CPSR (cpu, C);
  6289. }
  6290. }
  6291. /* 2 sources. */
  6292. /* Float add. */
  6293. static void
  6294. fadds (sim_cpu *cpu)
  6295. {
  6296. unsigned sm = INSTR (20, 16);
  6297. unsigned sn = INSTR ( 9, 5);
  6298. unsigned sd = INSTR ( 4, 0);
  6299. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6300. aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn)
  6301. + aarch64_get_FP_float (cpu, sm));
  6302. }
  6303. /* Double add. */
  6304. static void
  6305. faddd (sim_cpu *cpu)
  6306. {
  6307. unsigned sm = INSTR (20, 16);
  6308. unsigned sn = INSTR ( 9, 5);
  6309. unsigned sd = INSTR ( 4, 0);
  6310. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6311. aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn)
  6312. + aarch64_get_FP_double (cpu, sm));
  6313. }
  6314. /* Float divide. */
  6315. static void
  6316. fdivs (sim_cpu *cpu)
  6317. {
  6318. unsigned sm = INSTR (20, 16);
  6319. unsigned sn = INSTR ( 9, 5);
  6320. unsigned sd = INSTR ( 4, 0);
  6321. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6322. aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn)
  6323. / aarch64_get_FP_float (cpu, sm));
  6324. }
  6325. /* Double divide. */
  6326. static void
  6327. fdivd (sim_cpu *cpu)
  6328. {
  6329. unsigned sm = INSTR (20, 16);
  6330. unsigned sn = INSTR ( 9, 5);
  6331. unsigned sd = INSTR ( 4, 0);
  6332. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6333. aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn)
  6334. / aarch64_get_FP_double (cpu, sm));
  6335. }
  6336. /* Float multiply. */
  6337. static void
  6338. fmuls (sim_cpu *cpu)
  6339. {
  6340. unsigned sm = INSTR (20, 16);
  6341. unsigned sn = INSTR ( 9, 5);
  6342. unsigned sd = INSTR ( 4, 0);
  6343. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6344. aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn)
  6345. * aarch64_get_FP_float (cpu, sm));
  6346. }
  6347. /* Double multiply. */
  6348. static void
  6349. fmuld (sim_cpu *cpu)
  6350. {
  6351. unsigned sm = INSTR (20, 16);
  6352. unsigned sn = INSTR ( 9, 5);
  6353. unsigned sd = INSTR ( 4, 0);
  6354. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6355. aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn)
  6356. * aarch64_get_FP_double (cpu, sm));
  6357. }
  6358. /* Float negate and multiply. */
  6359. static void
  6360. fnmuls (sim_cpu *cpu)
  6361. {
  6362. unsigned sm = INSTR (20, 16);
  6363. unsigned sn = INSTR ( 9, 5);
  6364. unsigned sd = INSTR ( 4, 0);
  6365. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6366. aarch64_set_FP_float (cpu, sd, - (aarch64_get_FP_float (cpu, sn)
  6367. * aarch64_get_FP_float (cpu, sm)));
  6368. }
  6369. /* Double negate and multiply. */
  6370. static void
  6371. fnmuld (sim_cpu *cpu)
  6372. {
  6373. unsigned sm = INSTR (20, 16);
  6374. unsigned sn = INSTR ( 9, 5);
  6375. unsigned sd = INSTR ( 4, 0);
  6376. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6377. aarch64_set_FP_double (cpu, sd, - (aarch64_get_FP_double (cpu, sn)
  6378. * aarch64_get_FP_double (cpu, sm)));
  6379. }
  6380. /* Float subtract. */
  6381. static void
  6382. fsubs (sim_cpu *cpu)
  6383. {
  6384. unsigned sm = INSTR (20, 16);
  6385. unsigned sn = INSTR ( 9, 5);
  6386. unsigned sd = INSTR ( 4, 0);
  6387. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6388. aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn)
  6389. - aarch64_get_FP_float (cpu, sm));
  6390. }
  6391. /* Double subtract. */
  6392. static void
  6393. fsubd (sim_cpu *cpu)
  6394. {
  6395. unsigned sm = INSTR (20, 16);
  6396. unsigned sn = INSTR ( 9, 5);
  6397. unsigned sd = INSTR ( 4, 0);
  6398. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6399. aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn)
  6400. - aarch64_get_FP_double (cpu, sm));
  6401. }
  6402. static void
  6403. do_FMINNM (sim_cpu *cpu)
  6404. {
  6405. /* instr[31,23] = 0 0011 1100
  6406. instr[22] = float(0)/double(1)
  6407. instr[21] = 1
  6408. instr[20,16] = Sm
  6409. instr[15,10] = 01 1110
  6410. instr[9,5] = Sn
  6411. instr[4,0] = Cpu */
  6412. unsigned sm = INSTR (20, 16);
  6413. unsigned sn = INSTR ( 9, 5);
  6414. unsigned sd = INSTR ( 4, 0);
  6415. NYI_assert (31, 23, 0x03C);
  6416. NYI_assert (15, 10, 0x1E);
  6417. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6418. if (INSTR (22, 22))
  6419. aarch64_set_FP_double (cpu, sd,
  6420. dminnm (aarch64_get_FP_double (cpu, sn),
  6421. aarch64_get_FP_double (cpu, sm)));
  6422. else
  6423. aarch64_set_FP_float (cpu, sd,
  6424. fminnm (aarch64_get_FP_float (cpu, sn),
  6425. aarch64_get_FP_float (cpu, sm)));
  6426. }
  6427. static void
  6428. do_FMAXNM (sim_cpu *cpu)
  6429. {
  6430. /* instr[31,23] = 0 0011 1100
  6431. instr[22] = float(0)/double(1)
  6432. instr[21] = 1
  6433. instr[20,16] = Sm
  6434. instr[15,10] = 01 1010
  6435. instr[9,5] = Sn
  6436. instr[4,0] = Cpu */
  6437. unsigned sm = INSTR (20, 16);
  6438. unsigned sn = INSTR ( 9, 5);
  6439. unsigned sd = INSTR ( 4, 0);
  6440. NYI_assert (31, 23, 0x03C);
  6441. NYI_assert (15, 10, 0x1A);
  6442. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6443. if (INSTR (22, 22))
  6444. aarch64_set_FP_double (cpu, sd,
  6445. dmaxnm (aarch64_get_FP_double (cpu, sn),
  6446. aarch64_get_FP_double (cpu, sm)));
  6447. else
  6448. aarch64_set_FP_float (cpu, sd,
  6449. fmaxnm (aarch64_get_FP_float (cpu, sn),
  6450. aarch64_get_FP_float (cpu, sm)));
  6451. }
  6452. static void
  6453. dexSimpleFPDataProc2Source (sim_cpu *cpu)
  6454. {
  6455. /* instr[31] ==> M : 0 ==> OK, 1 ==> UNALLOC
  6456. instr[30] = 0
  6457. instr[29] ==> S : 0 ==> OK, 1 ==> UNALLOC
  6458. instr[28,25] = 1111
  6459. instr[24] = 0
  6460. instr[23,22] ==> type : 0 ==> single, 01 ==> double, 1x ==> UNALLOC
  6461. instr[21] = 1
  6462. instr[20,16] = Vm
  6463. instr[15,12] ==> opcode : 0000 ==> FMUL, 0001 ==> FDIV
  6464. 0010 ==> FADD, 0011 ==> FSUB,
  6465. 0100 ==> FMAX, 0101 ==> FMIN
  6466. 0110 ==> FMAXNM, 0111 ==> FMINNM
  6467. 1000 ==> FNMUL, ow ==> UNALLOC
  6468. instr[11,10] = 10
  6469. instr[9,5] = Vn
  6470. instr[4,0] = Vd */
  6471. uint32_t M_S = (INSTR (31, 31) << 1) | INSTR (29, 29);
  6472. uint32_t type = INSTR (23, 22);
  6473. /* Dispatch on opcode. */
  6474. uint32_t dispatch = INSTR (15, 12);
  6475. if (type > 1)
  6476. HALT_UNALLOC;
  6477. if (M_S != 0)
  6478. HALT_UNALLOC;
  6479. if (type)
  6480. switch (dispatch)
  6481. {
  6482. case 0: fmuld (cpu); return;
  6483. case 1: fdivd (cpu); return;
  6484. case 2: faddd (cpu); return;
  6485. case 3: fsubd (cpu); return;
  6486. case 6: do_FMAXNM (cpu); return;
  6487. case 7: do_FMINNM (cpu); return;
  6488. case 8: fnmuld (cpu); return;
  6489. /* Have not yet implemented fmax and fmin. */
  6490. case 4:
  6491. case 5:
  6492. HALT_NYI;
  6493. default:
  6494. HALT_UNALLOC;
  6495. }
  6496. else /* type == 0 => floats. */
  6497. switch (dispatch)
  6498. {
  6499. case 0: fmuls (cpu); return;
  6500. case 1: fdivs (cpu); return;
  6501. case 2: fadds (cpu); return;
  6502. case 3: fsubs (cpu); return;
  6503. case 6: do_FMAXNM (cpu); return;
  6504. case 7: do_FMINNM (cpu); return;
  6505. case 8: fnmuls (cpu); return;
  6506. case 4:
  6507. case 5:
  6508. HALT_NYI;
  6509. default:
  6510. HALT_UNALLOC;
  6511. }
  6512. }
  6513. static void
  6514. dexSimpleFPCondSelect (sim_cpu *cpu)
  6515. {
  6516. /* FCSEL
  6517. instr[31,23] = 0 0011 1100
  6518. instr[22] = 0=>single 1=>double
  6519. instr[21] = 1
  6520. instr[20,16] = Sm
  6521. instr[15,12] = cond
  6522. instr[11,10] = 11
  6523. instr[9,5] = Sn
  6524. instr[4,0] = Cpu */
  6525. unsigned sm = INSTR (20, 16);
  6526. unsigned sn = INSTR ( 9, 5);
  6527. unsigned sd = INSTR ( 4, 0);
  6528. uint32_t set = testConditionCode (cpu, INSTR (15, 12));
  6529. NYI_assert (31, 23, 0x03C);
  6530. NYI_assert (11, 10, 0x3);
  6531. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6532. if (INSTR (22, 22))
  6533. aarch64_set_FP_double (cpu, sd, (set ? aarch64_get_FP_double (cpu, sn)
  6534. : aarch64_get_FP_double (cpu, sm)));
  6535. else
  6536. aarch64_set_FP_float (cpu, sd, (set ? aarch64_get_FP_float (cpu, sn)
  6537. : aarch64_get_FP_float (cpu, sm)));
  6538. }
  6539. /* Store 32 bit unscaled signed 9 bit. */
  6540. static void
  6541. fsturs (sim_cpu *cpu, int32_t offset)
  6542. {
  6543. unsigned int rn = INSTR (9, 5);
  6544. unsigned int st = INSTR (4, 0);
  6545. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6546. aarch64_set_mem_u32 (cpu, aarch64_get_reg_u64 (cpu, rn, 1) + offset,
  6547. aarch64_get_vec_u32 (cpu, st, 0));
  6548. }
  6549. /* Store 64 bit unscaled signed 9 bit. */
  6550. static void
  6551. fsturd (sim_cpu *cpu, int32_t offset)
  6552. {
  6553. unsigned int rn = INSTR (9, 5);
  6554. unsigned int st = INSTR (4, 0);
  6555. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6556. aarch64_set_mem_u64 (cpu, aarch64_get_reg_u64 (cpu, rn, 1) + offset,
  6557. aarch64_get_vec_u64 (cpu, st, 0));
  6558. }
  6559. /* Store 128 bit unscaled signed 9 bit. */
  6560. static void
  6561. fsturq (sim_cpu *cpu, int32_t offset)
  6562. {
  6563. unsigned int rn = INSTR (9, 5);
  6564. unsigned int st = INSTR (4, 0);
  6565. FRegister a;
  6566. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6567. aarch64_get_FP_long_double (cpu, st, & a);
  6568. aarch64_set_mem_long_double (cpu,
  6569. aarch64_get_reg_u64 (cpu, rn, 1)
  6570. + offset, a);
  6571. }
  6572. /* TODO FP move register. */
  6573. /* 32 bit fp to fp move register. */
  6574. static void
  6575. ffmovs (sim_cpu *cpu)
  6576. {
  6577. unsigned int rn = INSTR (9, 5);
  6578. unsigned int st = INSTR (4, 0);
  6579. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6580. aarch64_set_FP_float (cpu, st, aarch64_get_FP_float (cpu, rn));
  6581. }
  6582. /* 64 bit fp to fp move register. */
  6583. static void
  6584. ffmovd (sim_cpu *cpu)
  6585. {
  6586. unsigned int rn = INSTR (9, 5);
  6587. unsigned int st = INSTR (4, 0);
  6588. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6589. aarch64_set_FP_double (cpu, st, aarch64_get_FP_double (cpu, rn));
  6590. }
  6591. /* 32 bit GReg to Vec move register. */
  6592. static void
  6593. fgmovs (sim_cpu *cpu)
  6594. {
  6595. unsigned int rn = INSTR (9, 5);
  6596. unsigned int st = INSTR (4, 0);
  6597. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6598. aarch64_set_vec_u32 (cpu, st, 0, aarch64_get_reg_u32 (cpu, rn, NO_SP));
  6599. }
  6600. /* 64 bit g to fp move register. */
  6601. static void
  6602. fgmovd (sim_cpu *cpu)
  6603. {
  6604. unsigned int rn = INSTR (9, 5);
  6605. unsigned int st = INSTR (4, 0);
  6606. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6607. aarch64_set_vec_u64 (cpu, st, 0, aarch64_get_reg_u64 (cpu, rn, NO_SP));
  6608. }
  6609. /* 32 bit fp to g move register. */
  6610. static void
  6611. gfmovs (sim_cpu *cpu)
  6612. {
  6613. unsigned int rn = INSTR (9, 5);
  6614. unsigned int st = INSTR (4, 0);
  6615. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6616. aarch64_set_reg_u64 (cpu, st, NO_SP, aarch64_get_vec_u32 (cpu, rn, 0));
  6617. }
  6618. /* 64 bit fp to g move register. */
  6619. static void
  6620. gfmovd (sim_cpu *cpu)
  6621. {
  6622. unsigned int rn = INSTR (9, 5);
  6623. unsigned int st = INSTR (4, 0);
  6624. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6625. aarch64_set_reg_u64 (cpu, st, NO_SP, aarch64_get_vec_u64 (cpu, rn, 0));
  6626. }
  6627. /* FP move immediate
  6628. These install an immediate 8 bit value in the target register
  6629. where the 8 bits comprise 1 sign bit, 4 bits of fraction and a 3
  6630. bit exponent. */
  6631. static void
  6632. fmovs (sim_cpu *cpu)
  6633. {
  6634. unsigned int sd = INSTR (4, 0);
  6635. uint32_t imm = INSTR (20, 13);
  6636. float f = fp_immediate_for_encoding_32 (imm);
  6637. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6638. aarch64_set_FP_float (cpu, sd, f);
  6639. }
  6640. static void
  6641. fmovd (sim_cpu *cpu)
  6642. {
  6643. unsigned int sd = INSTR (4, 0);
  6644. uint32_t imm = INSTR (20, 13);
  6645. double d = fp_immediate_for_encoding_64 (imm);
  6646. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6647. aarch64_set_FP_double (cpu, sd, d);
  6648. }
  6649. static void
  6650. dexSimpleFPImmediate (sim_cpu *cpu)
  6651. {
  6652. /* instr[31,23] == 00111100
  6653. instr[22] == type : single(0)/double(1)
  6654. instr[21] == 1
  6655. instr[20,13] == imm8
  6656. instr[12,10] == 100
  6657. instr[9,5] == imm5 : 00000 ==> PK, ow ==> UNALLOC
  6658. instr[4,0] == Rd */
  6659. uint32_t imm5 = INSTR (9, 5);
  6660. NYI_assert (31, 23, 0x3C);
  6661. if (imm5 != 0)
  6662. HALT_UNALLOC;
  6663. if (INSTR (22, 22))
  6664. fmovd (cpu);
  6665. else
  6666. fmovs (cpu);
  6667. }
  6668. /* TODO specific decode and execute for group Load Store. */
  6669. /* TODO FP load/store single register (unscaled offset). */
  6670. /* TODO load 8 bit unscaled signed 9 bit. */
  6671. /* TODO load 16 bit unscaled signed 9 bit. */
  6672. /* Load 32 bit unscaled signed 9 bit. */
  6673. static void
  6674. fldurs (sim_cpu *cpu, int32_t offset)
  6675. {
  6676. unsigned int rn = INSTR (9, 5);
  6677. unsigned int st = INSTR (4, 0);
  6678. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6679. aarch64_set_vec_u32 (cpu, st, 0, aarch64_get_mem_u32
  6680. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset));
  6681. }
  6682. /* Load 64 bit unscaled signed 9 bit. */
  6683. static void
  6684. fldurd (sim_cpu *cpu, int32_t offset)
  6685. {
  6686. unsigned int rn = INSTR (9, 5);
  6687. unsigned int st = INSTR (4, 0);
  6688. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6689. aarch64_set_vec_u64 (cpu, st, 0, aarch64_get_mem_u64
  6690. (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset));
  6691. }
  6692. /* Load 128 bit unscaled signed 9 bit. */
  6693. static void
  6694. fldurq (sim_cpu *cpu, int32_t offset)
  6695. {
  6696. unsigned int rn = INSTR (9, 5);
  6697. unsigned int st = INSTR (4, 0);
  6698. FRegister a;
  6699. uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset;
  6700. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6701. aarch64_get_mem_long_double (cpu, addr, & a);
  6702. aarch64_set_FP_long_double (cpu, st, a);
  6703. }
  6704. /* TODO store 8 bit unscaled signed 9 bit. */
  6705. /* TODO store 16 bit unscaled signed 9 bit. */
  6706. /* 1 source. */
  6707. /* Float absolute value. */
  6708. static void
  6709. fabss (sim_cpu *cpu)
  6710. {
  6711. unsigned sn = INSTR (9, 5);
  6712. unsigned sd = INSTR (4, 0);
  6713. float value = aarch64_get_FP_float (cpu, sn);
  6714. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6715. aarch64_set_FP_float (cpu, sd, fabsf (value));
  6716. }
  6717. /* Double absolute value. */
  6718. static void
  6719. fabcpu (sim_cpu *cpu)
  6720. {
  6721. unsigned sn = INSTR (9, 5);
  6722. unsigned sd = INSTR (4, 0);
  6723. double value = aarch64_get_FP_double (cpu, sn);
  6724. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6725. aarch64_set_FP_double (cpu, sd, fabs (value));
  6726. }
  6727. /* Float negative value. */
  6728. static void
  6729. fnegs (sim_cpu *cpu)
  6730. {
  6731. unsigned sn = INSTR (9, 5);
  6732. unsigned sd = INSTR (4, 0);
  6733. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6734. aarch64_set_FP_float (cpu, sd, - aarch64_get_FP_float (cpu, sn));
  6735. }
  6736. /* Double negative value. */
  6737. static void
  6738. fnegd (sim_cpu *cpu)
  6739. {
  6740. unsigned sn = INSTR (9, 5);
  6741. unsigned sd = INSTR (4, 0);
  6742. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6743. aarch64_set_FP_double (cpu, sd, - aarch64_get_FP_double (cpu, sn));
  6744. }
  6745. /* Float square root. */
  6746. static void
  6747. fsqrts (sim_cpu *cpu)
  6748. {
  6749. unsigned sn = INSTR (9, 5);
  6750. unsigned sd = INSTR (4, 0);
  6751. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6752. aarch64_set_FP_float (cpu, sd, sqrtf (aarch64_get_FP_float (cpu, sn)));
  6753. }
  6754. /* Double square root. */
  6755. static void
  6756. fsqrtd (sim_cpu *cpu)
  6757. {
  6758. unsigned sn = INSTR (9, 5);
  6759. unsigned sd = INSTR (4, 0);
  6760. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6761. aarch64_set_FP_double (cpu, sd,
  6762. sqrt (aarch64_get_FP_double (cpu, sn)));
  6763. }
  6764. /* Convert double to float. */
  6765. static void
  6766. fcvtds (sim_cpu *cpu)
  6767. {
  6768. unsigned sn = INSTR (9, 5);
  6769. unsigned sd = INSTR (4, 0);
  6770. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6771. aarch64_set_FP_float (cpu, sd, (float) aarch64_get_FP_double (cpu, sn));
  6772. }
  6773. /* Convert float to double. */
  6774. static void
  6775. fcvtcpu (sim_cpu *cpu)
  6776. {
  6777. unsigned sn = INSTR (9, 5);
  6778. unsigned sd = INSTR (4, 0);
  6779. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6780. aarch64_set_FP_double (cpu, sd, (double) aarch64_get_FP_float (cpu, sn));
  6781. }
  6782. static void
  6783. do_FRINT (sim_cpu *cpu)
  6784. {
  6785. /* instr[31,23] = 0001 1110 0
  6786. instr[22] = single(0)/double(1)
  6787. instr[21,18] = 1001
  6788. instr[17,15] = rounding mode
  6789. instr[14,10] = 10000
  6790. instr[9,5] = source
  6791. instr[4,0] = dest */
  6792. float val;
  6793. unsigned rs = INSTR (9, 5);
  6794. unsigned rd = INSTR (4, 0);
  6795. unsigned int rmode = INSTR (17, 15);
  6796. NYI_assert (31, 23, 0x03C);
  6797. NYI_assert (21, 18, 0x9);
  6798. NYI_assert (14, 10, 0x10);
  6799. if (rmode == 6 || rmode == 7)
  6800. /* FIXME: Add support for rmode == 6 exactness check. */
  6801. rmode = uimm (aarch64_get_FPSR (cpu), 23, 22);
  6802. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6803. if (INSTR (22, 22))
  6804. {
  6805. double val = aarch64_get_FP_double (cpu, rs);
  6806. switch (rmode)
  6807. {
  6808. case 0: /* mode N: nearest or even. */
  6809. {
  6810. double rval = round (val);
  6811. if (val - rval == 0.5)
  6812. {
  6813. if (((rval / 2.0) * 2.0) != rval)
  6814. rval += 1.0;
  6815. }
  6816. aarch64_set_FP_double (cpu, rd, round (val));
  6817. return;
  6818. }
  6819. case 1: /* mode P: towards +inf. */
  6820. if (val < 0.0)
  6821. aarch64_set_FP_double (cpu, rd, trunc (val));
  6822. else
  6823. aarch64_set_FP_double (cpu, rd, round (val));
  6824. return;
  6825. case 2: /* mode M: towards -inf. */
  6826. if (val < 0.0)
  6827. aarch64_set_FP_double (cpu, rd, round (val));
  6828. else
  6829. aarch64_set_FP_double (cpu, rd, trunc (val));
  6830. return;
  6831. case 3: /* mode Z: towards 0. */
  6832. aarch64_set_FP_double (cpu, rd, trunc (val));
  6833. return;
  6834. case 4: /* mode A: away from 0. */
  6835. aarch64_set_FP_double (cpu, rd, round (val));
  6836. return;
  6837. case 6: /* mode X: use FPCR with exactness check. */
  6838. case 7: /* mode I: use FPCR mode. */
  6839. HALT_NYI;
  6840. default:
  6841. HALT_UNALLOC;
  6842. }
  6843. }
  6844. val = aarch64_get_FP_float (cpu, rs);
  6845. switch (rmode)
  6846. {
  6847. case 0: /* mode N: nearest or even. */
  6848. {
  6849. float rval = roundf (val);
  6850. if (val - rval == 0.5)
  6851. {
  6852. if (((rval / 2.0) * 2.0) != rval)
  6853. rval += 1.0;
  6854. }
  6855. aarch64_set_FP_float (cpu, rd, rval);
  6856. return;
  6857. }
  6858. case 1: /* mode P: towards +inf. */
  6859. if (val < 0.0)
  6860. aarch64_set_FP_float (cpu, rd, truncf (val));
  6861. else
  6862. aarch64_set_FP_float (cpu, rd, roundf (val));
  6863. return;
  6864. case 2: /* mode M: towards -inf. */
  6865. if (val < 0.0)
  6866. aarch64_set_FP_float (cpu, rd, truncf (val));
  6867. else
  6868. aarch64_set_FP_float (cpu, rd, roundf (val));
  6869. return;
  6870. case 3: /* mode Z: towards 0. */
  6871. aarch64_set_FP_float (cpu, rd, truncf (val));
  6872. return;
  6873. case 4: /* mode A: away from 0. */
  6874. aarch64_set_FP_float (cpu, rd, roundf (val));
  6875. return;
  6876. case 6: /* mode X: use FPCR with exactness check. */
  6877. case 7: /* mode I: use FPCR mode. */
  6878. HALT_NYI;
  6879. default:
  6880. HALT_UNALLOC;
  6881. }
  6882. }
  6883. /* Convert half to float. */
  6884. static void
  6885. do_FCVT_half_to_single (sim_cpu *cpu)
  6886. {
  6887. unsigned rn = INSTR (9, 5);
  6888. unsigned rd = INSTR (4, 0);
  6889. NYI_assert (31, 10, 0x7B890);
  6890. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6891. aarch64_set_FP_float (cpu, rd, (float) aarch64_get_FP_half (cpu, rn));
  6892. }
  6893. /* Convert half to double. */
  6894. static void
  6895. do_FCVT_half_to_double (sim_cpu *cpu)
  6896. {
  6897. unsigned rn = INSTR (9, 5);
  6898. unsigned rd = INSTR (4, 0);
  6899. NYI_assert (31, 10, 0x7B8B0);
  6900. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6901. aarch64_set_FP_double (cpu, rd, (double) aarch64_get_FP_half (cpu, rn));
  6902. }
  6903. static void
  6904. do_FCVT_single_to_half (sim_cpu *cpu)
  6905. {
  6906. unsigned rn = INSTR (9, 5);
  6907. unsigned rd = INSTR (4, 0);
  6908. NYI_assert (31, 10, 0x788F0);
  6909. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6910. aarch64_set_FP_half (cpu, rd, aarch64_get_FP_float (cpu, rn));
  6911. }
  6912. /* Convert double to half. */
  6913. static void
  6914. do_FCVT_double_to_half (sim_cpu *cpu)
  6915. {
  6916. unsigned rn = INSTR (9, 5);
  6917. unsigned rd = INSTR (4, 0);
  6918. NYI_assert (31, 10, 0x798F0);
  6919. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  6920. aarch64_set_FP_half (cpu, rd, (float) aarch64_get_FP_double (cpu, rn));
  6921. }
  6922. static void
  6923. dexSimpleFPDataProc1Source (sim_cpu *cpu)
  6924. {
  6925. /* instr[31] ==> M : 0 ==> OK, 1 ==> UNALLOC
  6926. instr[30] = 0
  6927. instr[29] ==> S : 0 ==> OK, 1 ==> UNALLOC
  6928. instr[28,25] = 1111
  6929. instr[24] = 0
  6930. instr[23,22] ==> type : 00 ==> source is single,
  6931. 01 ==> source is double
  6932. 10 ==> UNALLOC
  6933. 11 ==> UNALLOC or source is half
  6934. instr[21] = 1
  6935. instr[20,15] ==> opcode : with type 00 or 01
  6936. 000000 ==> FMOV, 000001 ==> FABS,
  6937. 000010 ==> FNEG, 000011 ==> FSQRT,
  6938. 000100 ==> UNALLOC, 000101 ==> FCVT,(to single/double)
  6939. 000110 ==> UNALLOC, 000111 ==> FCVT (to half)
  6940. 001000 ==> FRINTN, 001001 ==> FRINTP,
  6941. 001010 ==> FRINTM, 001011 ==> FRINTZ,
  6942. 001100 ==> FRINTA, 001101 ==> UNALLOC
  6943. 001110 ==> FRINTX, 001111 ==> FRINTI
  6944. with type 11
  6945. 000100 ==> FCVT (half-to-single)
  6946. 000101 ==> FCVT (half-to-double)
  6947. instr[14,10] = 10000. */
  6948. uint32_t M_S = (INSTR (31, 31) << 1) | INSTR (29, 29);
  6949. uint32_t type = INSTR (23, 22);
  6950. uint32_t opcode = INSTR (20, 15);
  6951. if (M_S != 0)
  6952. HALT_UNALLOC;
  6953. if (type == 3)
  6954. {
  6955. if (opcode == 4)
  6956. do_FCVT_half_to_single (cpu);
  6957. else if (opcode == 5)
  6958. do_FCVT_half_to_double (cpu);
  6959. else
  6960. HALT_UNALLOC;
  6961. return;
  6962. }
  6963. if (type == 2)
  6964. HALT_UNALLOC;
  6965. switch (opcode)
  6966. {
  6967. case 0:
  6968. if (type)
  6969. ffmovd (cpu);
  6970. else
  6971. ffmovs (cpu);
  6972. return;
  6973. case 1:
  6974. if (type)
  6975. fabcpu (cpu);
  6976. else
  6977. fabss (cpu);
  6978. return;
  6979. case 2:
  6980. if (type)
  6981. fnegd (cpu);
  6982. else
  6983. fnegs (cpu);
  6984. return;
  6985. case 3:
  6986. if (type)
  6987. fsqrtd (cpu);
  6988. else
  6989. fsqrts (cpu);
  6990. return;
  6991. case 4:
  6992. if (type)
  6993. fcvtds (cpu);
  6994. else
  6995. HALT_UNALLOC;
  6996. return;
  6997. case 5:
  6998. if (type)
  6999. HALT_UNALLOC;
  7000. fcvtcpu (cpu);
  7001. return;
  7002. case 8: /* FRINTN etc. */
  7003. case 9:
  7004. case 10:
  7005. case 11:
  7006. case 12:
  7007. case 14:
  7008. case 15:
  7009. do_FRINT (cpu);
  7010. return;
  7011. case 7:
  7012. if (INSTR (22, 22))
  7013. do_FCVT_double_to_half (cpu);
  7014. else
  7015. do_FCVT_single_to_half (cpu);
  7016. return;
  7017. case 13:
  7018. HALT_NYI;
  7019. default:
  7020. HALT_UNALLOC;
  7021. }
  7022. }
  7023. /* 32 bit signed int to float. */
  7024. static void
  7025. scvtf32 (sim_cpu *cpu)
  7026. {
  7027. unsigned rn = INSTR (9, 5);
  7028. unsigned sd = INSTR (4, 0);
  7029. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7030. aarch64_set_FP_float
  7031. (cpu, sd, (float) aarch64_get_reg_s32 (cpu, rn, NO_SP));
  7032. }
  7033. /* signed int to float. */
  7034. static void
  7035. scvtf (sim_cpu *cpu)
  7036. {
  7037. unsigned rn = INSTR (9, 5);
  7038. unsigned sd = INSTR (4, 0);
  7039. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7040. aarch64_set_FP_float
  7041. (cpu, sd, (float) aarch64_get_reg_s64 (cpu, rn, NO_SP));
  7042. }
  7043. /* 32 bit signed int to double. */
  7044. static void
  7045. scvtd32 (sim_cpu *cpu)
  7046. {
  7047. unsigned rn = INSTR (9, 5);
  7048. unsigned sd = INSTR (4, 0);
  7049. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7050. aarch64_set_FP_double
  7051. (cpu, sd, (double) aarch64_get_reg_s32 (cpu, rn, NO_SP));
  7052. }
  7053. /* signed int to double. */
  7054. static void
  7055. scvtd (sim_cpu *cpu)
  7056. {
  7057. unsigned rn = INSTR (9, 5);
  7058. unsigned sd = INSTR (4, 0);
  7059. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7060. aarch64_set_FP_double
  7061. (cpu, sd, (double) aarch64_get_reg_s64 (cpu, rn, NO_SP));
  7062. }
  7063. static const float FLOAT_INT_MAX = (float) INT_MAX;
  7064. static const float FLOAT_INT_MIN = (float) INT_MIN;
  7065. static const double DOUBLE_INT_MAX = (double) INT_MAX;
  7066. static const double DOUBLE_INT_MIN = (double) INT_MIN;
  7067. static const float FLOAT_LONG_MAX = (float) LONG_MAX;
  7068. static const float FLOAT_LONG_MIN = (float) LONG_MIN;
  7069. static const double DOUBLE_LONG_MAX = (double) LONG_MAX;
  7070. static const double DOUBLE_LONG_MIN = (double) LONG_MIN;
  7071. #define UINT_MIN 0
  7072. #define ULONG_MIN 0
  7073. static const float FLOAT_UINT_MAX = (float) UINT_MAX;
  7074. static const float FLOAT_UINT_MIN = (float) UINT_MIN;
  7075. static const double DOUBLE_UINT_MAX = (double) UINT_MAX;
  7076. static const double DOUBLE_UINT_MIN = (double) UINT_MIN;
  7077. static const float FLOAT_ULONG_MAX = (float) ULONG_MAX;
  7078. static const float FLOAT_ULONG_MIN = (float) ULONG_MIN;
  7079. static const double DOUBLE_ULONG_MAX = (double) ULONG_MAX;
  7080. static const double DOUBLE_ULONG_MIN = (double) ULONG_MIN;
  7081. /* Check for FP exception conditions:
  7082. NaN raises IO
  7083. Infinity raises IO
  7084. Out of Range raises IO and IX and saturates value
  7085. Denormal raises ID and IX and sets to zero. */
  7086. #define RAISE_EXCEPTIONS(F, VALUE, FTYPE, ITYPE) \
  7087. do \
  7088. { \
  7089. switch (fpclassify (F)) \
  7090. { \
  7091. case FP_INFINITE: \
  7092. case FP_NAN: \
  7093. aarch64_set_FPSR (cpu, IO); \
  7094. if (signbit (F)) \
  7095. VALUE = ITYPE##_MAX; \
  7096. else \
  7097. VALUE = ITYPE##_MIN; \
  7098. break; \
  7099. \
  7100. case FP_NORMAL: \
  7101. if (F >= FTYPE##_##ITYPE##_MAX) \
  7102. { \
  7103. aarch64_set_FPSR_bits (cpu, IO | IX, IO | IX); \
  7104. VALUE = ITYPE##_MAX; \
  7105. } \
  7106. else if (F <= FTYPE##_##ITYPE##_MIN) \
  7107. { \
  7108. aarch64_set_FPSR_bits (cpu, IO | IX, IO | IX); \
  7109. VALUE = ITYPE##_MIN; \
  7110. } \
  7111. break; \
  7112. \
  7113. case FP_SUBNORMAL: \
  7114. aarch64_set_FPSR_bits (cpu, IO | IX | ID, IX | ID); \
  7115. VALUE = 0; \
  7116. break; \
  7117. \
  7118. default: \
  7119. case FP_ZERO: \
  7120. VALUE = 0; \
  7121. break; \
  7122. } \
  7123. } \
  7124. while (0)
  7125. /* 32 bit convert float to signed int truncate towards zero. */
  7126. static void
  7127. fcvtszs32 (sim_cpu *cpu)
  7128. {
  7129. unsigned sn = INSTR (9, 5);
  7130. unsigned rd = INSTR (4, 0);
  7131. /* TODO : check that this rounds toward zero. */
  7132. float f = aarch64_get_FP_float (cpu, sn);
  7133. int32_t value = (int32_t) f;
  7134. RAISE_EXCEPTIONS (f, value, FLOAT, INT);
  7135. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7136. /* Avoid sign extension to 64 bit. */
  7137. aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) value);
  7138. }
  7139. /* 64 bit convert float to signed int truncate towards zero. */
  7140. static void
  7141. fcvtszs (sim_cpu *cpu)
  7142. {
  7143. unsigned sn = INSTR (9, 5);
  7144. unsigned rd = INSTR (4, 0);
  7145. float f = aarch64_get_FP_float (cpu, sn);
  7146. int64_t value = (int64_t) f;
  7147. RAISE_EXCEPTIONS (f, value, FLOAT, LONG);
  7148. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7149. aarch64_set_reg_s64 (cpu, rd, NO_SP, value);
  7150. }
  7151. /* 32 bit convert double to signed int truncate towards zero. */
  7152. static void
  7153. fcvtszd32 (sim_cpu *cpu)
  7154. {
  7155. unsigned sn = INSTR (9, 5);
  7156. unsigned rd = INSTR (4, 0);
  7157. /* TODO : check that this rounds toward zero. */
  7158. double d = aarch64_get_FP_double (cpu, sn);
  7159. int32_t value = (int32_t) d;
  7160. RAISE_EXCEPTIONS (d, value, DOUBLE, INT);
  7161. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7162. /* Avoid sign extension to 64 bit. */
  7163. aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) value);
  7164. }
  7165. /* 64 bit convert double to signed int truncate towards zero. */
  7166. static void
  7167. fcvtszd (sim_cpu *cpu)
  7168. {
  7169. unsigned sn = INSTR (9, 5);
  7170. unsigned rd = INSTR (4, 0);
  7171. /* TODO : check that this rounds toward zero. */
  7172. double d = aarch64_get_FP_double (cpu, sn);
  7173. int64_t value;
  7174. value = (int64_t) d;
  7175. RAISE_EXCEPTIONS (d, value, DOUBLE, LONG);
  7176. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7177. aarch64_set_reg_s64 (cpu, rd, NO_SP, value);
  7178. }
  7179. static void
  7180. do_fcvtzu (sim_cpu *cpu)
  7181. {
  7182. /* instr[31] = size: 32-bit (0), 64-bit (1)
  7183. instr[30,23] = 00111100
  7184. instr[22] = type: single (0)/ double (1)
  7185. instr[21] = enable (0)/disable(1) precision
  7186. instr[20,16] = 11001
  7187. instr[15,10] = precision
  7188. instr[9,5] = Rs
  7189. instr[4,0] = Rd. */
  7190. unsigned rs = INSTR (9, 5);
  7191. unsigned rd = INSTR (4, 0);
  7192. NYI_assert (30, 23, 0x3C);
  7193. NYI_assert (20, 16, 0x19);
  7194. if (INSTR (21, 21) != 1)
  7195. /* Convert to fixed point. */
  7196. HALT_NYI;
  7197. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7198. if (INSTR (31, 31))
  7199. {
  7200. /* Convert to unsigned 64-bit integer. */
  7201. if (INSTR (22, 22))
  7202. {
  7203. double d = aarch64_get_FP_double (cpu, rs);
  7204. uint64_t value = (uint64_t) d;
  7205. /* Do not raise an exception if we have reached ULONG_MAX. */
  7206. if (value != (1ULL << 63))
  7207. RAISE_EXCEPTIONS (d, value, DOUBLE, ULONG);
  7208. aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
  7209. }
  7210. else
  7211. {
  7212. float f = aarch64_get_FP_float (cpu, rs);
  7213. uint64_t value = (uint64_t) f;
  7214. /* Do not raise an exception if we have reached ULONG_MAX. */
  7215. if (value != (1ULL << 63))
  7216. RAISE_EXCEPTIONS (f, value, FLOAT, ULONG);
  7217. aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
  7218. }
  7219. }
  7220. else
  7221. {
  7222. uint32_t value;
  7223. /* Convert to unsigned 32-bit integer. */
  7224. if (INSTR (22, 22))
  7225. {
  7226. double d = aarch64_get_FP_double (cpu, rs);
  7227. value = (uint32_t) d;
  7228. /* Do not raise an exception if we have reached UINT_MAX. */
  7229. if (value != (1UL << 31))
  7230. RAISE_EXCEPTIONS (d, value, DOUBLE, UINT);
  7231. }
  7232. else
  7233. {
  7234. float f = aarch64_get_FP_float (cpu, rs);
  7235. value = (uint32_t) f;
  7236. /* Do not raise an exception if we have reached UINT_MAX. */
  7237. if (value != (1UL << 31))
  7238. RAISE_EXCEPTIONS (f, value, FLOAT, UINT);
  7239. }
  7240. aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
  7241. }
  7242. }
  7243. static void
  7244. do_UCVTF (sim_cpu *cpu)
  7245. {
  7246. /* instr[31] = size: 32-bit (0), 64-bit (1)
  7247. instr[30,23] = 001 1110 0
  7248. instr[22] = type: single (0)/ double (1)
  7249. instr[21] = enable (0)/disable(1) precision
  7250. instr[20,16] = 0 0011
  7251. instr[15,10] = precision
  7252. instr[9,5] = Rs
  7253. instr[4,0] = Rd. */
  7254. unsigned rs = INSTR (9, 5);
  7255. unsigned rd = INSTR (4, 0);
  7256. NYI_assert (30, 23, 0x3C);
  7257. NYI_assert (20, 16, 0x03);
  7258. if (INSTR (21, 21) != 1)
  7259. HALT_NYI;
  7260. /* FIXME: Add exception raising. */
  7261. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7262. if (INSTR (31, 31))
  7263. {
  7264. uint64_t value = aarch64_get_reg_u64 (cpu, rs, NO_SP);
  7265. if (INSTR (22, 22))
  7266. aarch64_set_FP_double (cpu, rd, (double) value);
  7267. else
  7268. aarch64_set_FP_float (cpu, rd, (float) value);
  7269. }
  7270. else
  7271. {
  7272. uint32_t value = aarch64_get_reg_u32 (cpu, rs, NO_SP);
  7273. if (INSTR (22, 22))
  7274. aarch64_set_FP_double (cpu, rd, (double) value);
  7275. else
  7276. aarch64_set_FP_float (cpu, rd, (float) value);
  7277. }
  7278. }
  7279. static void
  7280. float_vector_move (sim_cpu *cpu)
  7281. {
  7282. /* instr[31,17] == 100 1111 0101 0111
  7283. instr[16] ==> direction 0=> to GR, 1=> from GR
  7284. instr[15,10] => ???
  7285. instr[9,5] ==> source
  7286. instr[4,0] ==> dest. */
  7287. unsigned rn = INSTR (9, 5);
  7288. unsigned rd = INSTR (4, 0);
  7289. NYI_assert (31, 17, 0x4F57);
  7290. if (INSTR (15, 10) != 0)
  7291. HALT_UNALLOC;
  7292. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7293. if (INSTR (16, 16))
  7294. aarch64_set_vec_u64 (cpu, rd, 1, aarch64_get_reg_u64 (cpu, rn, NO_SP));
  7295. else
  7296. aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u64 (cpu, rn, 1));
  7297. }
  7298. static void
  7299. dexSimpleFPIntegerConvert (sim_cpu *cpu)
  7300. {
  7301. /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  7302. instr[30 = 0
  7303. instr[29] = S : 0 ==> OK, 1 ==> UNALLOC
  7304. instr[28,25] = 1111
  7305. instr[24] = 0
  7306. instr[23,22] = type : 00 ==> single, 01 ==> double, 1x ==> UNALLOC
  7307. instr[21] = 1
  7308. instr[20,19] = rmode
  7309. instr[18,16] = opcode
  7310. instr[15,10] = 10 0000 */
  7311. uint32_t rmode_opcode;
  7312. uint32_t size_type;
  7313. uint32_t type;
  7314. uint32_t size;
  7315. uint32_t S;
  7316. if (INSTR (31, 17) == 0x4F57)
  7317. {
  7318. float_vector_move (cpu);
  7319. return;
  7320. }
  7321. size = INSTR (31, 31);
  7322. S = INSTR (29, 29);
  7323. if (S != 0)
  7324. HALT_UNALLOC;
  7325. type = INSTR (23, 22);
  7326. if (type > 1)
  7327. HALT_UNALLOC;
  7328. rmode_opcode = INSTR (20, 16);
  7329. size_type = (size << 1) | type; /* 0==32f, 1==32d, 2==64f, 3==64d. */
  7330. switch (rmode_opcode)
  7331. {
  7332. case 2: /* SCVTF. */
  7333. switch (size_type)
  7334. {
  7335. case 0: scvtf32 (cpu); return;
  7336. case 1: scvtd32 (cpu); return;
  7337. case 2: scvtf (cpu); return;
  7338. case 3: scvtd (cpu); return;
  7339. }
  7340. case 6: /* FMOV GR, Vec. */
  7341. switch (size_type)
  7342. {
  7343. case 0: gfmovs (cpu); return;
  7344. case 3: gfmovd (cpu); return;
  7345. default: HALT_UNALLOC;
  7346. }
  7347. case 7: /* FMOV vec, GR. */
  7348. switch (size_type)
  7349. {
  7350. case 0: fgmovs (cpu); return;
  7351. case 3: fgmovd (cpu); return;
  7352. default: HALT_UNALLOC;
  7353. }
  7354. case 24: /* FCVTZS. */
  7355. switch (size_type)
  7356. {
  7357. case 0: fcvtszs32 (cpu); return;
  7358. case 1: fcvtszd32 (cpu); return;
  7359. case 2: fcvtszs (cpu); return;
  7360. case 3: fcvtszd (cpu); return;
  7361. }
  7362. case 25: do_fcvtzu (cpu); return;
  7363. case 3: do_UCVTF (cpu); return;
  7364. case 0: /* FCVTNS. */
  7365. case 1: /* FCVTNU. */
  7366. case 4: /* FCVTAS. */
  7367. case 5: /* FCVTAU. */
  7368. case 8: /* FCVPTS. */
  7369. case 9: /* FCVTPU. */
  7370. case 16: /* FCVTMS. */
  7371. case 17: /* FCVTMU. */
  7372. default:
  7373. HALT_NYI;
  7374. }
  7375. }
  7376. static void
  7377. set_flags_for_float_compare (sim_cpu *cpu, float fvalue1, float fvalue2)
  7378. {
  7379. uint32_t flags;
  7380. /* FIXME: Add exception raising. */
  7381. if (isnan (fvalue1) || isnan (fvalue2))
  7382. flags = C|V;
  7383. else if (isinf (fvalue1) && isinf (fvalue2))
  7384. {
  7385. /* Subtracting two infinities may give a NaN. We only need to compare
  7386. the signs, which we can get from isinf. */
  7387. int result = isinf (fvalue1) - isinf (fvalue2);
  7388. if (result == 0)
  7389. flags = Z|C;
  7390. else if (result < 0)
  7391. flags = N;
  7392. else /* (result > 0). */
  7393. flags = C;
  7394. }
  7395. else
  7396. {
  7397. float result = fvalue1 - fvalue2;
  7398. if (result == 0.0)
  7399. flags = Z|C;
  7400. else if (result < 0)
  7401. flags = N;
  7402. else /* (result > 0). */
  7403. flags = C;
  7404. }
  7405. aarch64_set_CPSR (cpu, flags);
  7406. }
  7407. static void
  7408. fcmps (sim_cpu *cpu)
  7409. {
  7410. unsigned sm = INSTR (20, 16);
  7411. unsigned sn = INSTR ( 9, 5);
  7412. float fvalue1 = aarch64_get_FP_float (cpu, sn);
  7413. float fvalue2 = aarch64_get_FP_float (cpu, sm);
  7414. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7415. set_flags_for_float_compare (cpu, fvalue1, fvalue2);
  7416. }
  7417. /* Float compare to zero -- Invalid Operation exception
  7418. only on signaling NaNs. */
  7419. static void
  7420. fcmpzs (sim_cpu *cpu)
  7421. {
  7422. unsigned sn = INSTR ( 9, 5);
  7423. float fvalue1 = aarch64_get_FP_float (cpu, sn);
  7424. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7425. set_flags_for_float_compare (cpu, fvalue1, 0.0f);
  7426. }
  7427. /* Float compare -- Invalid Operation exception on all NaNs. */
  7428. static void
  7429. fcmpes (sim_cpu *cpu)
  7430. {
  7431. unsigned sm = INSTR (20, 16);
  7432. unsigned sn = INSTR ( 9, 5);
  7433. float fvalue1 = aarch64_get_FP_float (cpu, sn);
  7434. float fvalue2 = aarch64_get_FP_float (cpu, sm);
  7435. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7436. set_flags_for_float_compare (cpu, fvalue1, fvalue2);
  7437. }
  7438. /* Float compare to zero -- Invalid Operation exception on all NaNs. */
  7439. static void
  7440. fcmpzes (sim_cpu *cpu)
  7441. {
  7442. unsigned sn = INSTR ( 9, 5);
  7443. float fvalue1 = aarch64_get_FP_float (cpu, sn);
  7444. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7445. set_flags_for_float_compare (cpu, fvalue1, 0.0f);
  7446. }
  7447. static void
  7448. set_flags_for_double_compare (sim_cpu *cpu, double dval1, double dval2)
  7449. {
  7450. uint32_t flags;
  7451. /* FIXME: Add exception raising. */
  7452. if (isnan (dval1) || isnan (dval2))
  7453. flags = C|V;
  7454. else if (isinf (dval1) && isinf (dval2))
  7455. {
  7456. /* Subtracting two infinities may give a NaN. We only need to compare
  7457. the signs, which we can get from isinf. */
  7458. int result = isinf (dval1) - isinf (dval2);
  7459. if (result == 0)
  7460. flags = Z|C;
  7461. else if (result < 0)
  7462. flags = N;
  7463. else /* (result > 0). */
  7464. flags = C;
  7465. }
  7466. else
  7467. {
  7468. double result = dval1 - dval2;
  7469. if (result == 0.0)
  7470. flags = Z|C;
  7471. else if (result < 0)
  7472. flags = N;
  7473. else /* (result > 0). */
  7474. flags = C;
  7475. }
  7476. aarch64_set_CPSR (cpu, flags);
  7477. }
  7478. /* Double compare -- Invalid Operation exception only on signaling NaNs. */
  7479. static void
  7480. fcmpd (sim_cpu *cpu)
  7481. {
  7482. unsigned sm = INSTR (20, 16);
  7483. unsigned sn = INSTR ( 9, 5);
  7484. double dvalue1 = aarch64_get_FP_double (cpu, sn);
  7485. double dvalue2 = aarch64_get_FP_double (cpu, sm);
  7486. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7487. set_flags_for_double_compare (cpu, dvalue1, dvalue2);
  7488. }
  7489. /* Double compare to zero -- Invalid Operation exception
  7490. only on signaling NaNs. */
  7491. static void
  7492. fcmpzd (sim_cpu *cpu)
  7493. {
  7494. unsigned sn = INSTR ( 9, 5);
  7495. double dvalue1 = aarch64_get_FP_double (cpu, sn);
  7496. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7497. set_flags_for_double_compare (cpu, dvalue1, 0.0);
  7498. }
  7499. /* Double compare -- Invalid Operation exception on all NaNs. */
  7500. static void
  7501. fcmped (sim_cpu *cpu)
  7502. {
  7503. unsigned sm = INSTR (20, 16);
  7504. unsigned sn = INSTR ( 9, 5);
  7505. double dvalue1 = aarch64_get_FP_double (cpu, sn);
  7506. double dvalue2 = aarch64_get_FP_double (cpu, sm);
  7507. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7508. set_flags_for_double_compare (cpu, dvalue1, dvalue2);
  7509. }
  7510. /* Double compare to zero -- Invalid Operation exception on all NaNs. */
  7511. static void
  7512. fcmpzed (sim_cpu *cpu)
  7513. {
  7514. unsigned sn = INSTR ( 9, 5);
  7515. double dvalue1 = aarch64_get_FP_double (cpu, sn);
  7516. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7517. set_flags_for_double_compare (cpu, dvalue1, 0.0);
  7518. }
  7519. static void
  7520. dexSimpleFPCompare (sim_cpu *cpu)
  7521. {
  7522. /* assert instr[28,25] == 1111
  7523. instr[30:24:21:13,10] = 0011000
  7524. instr[31] = M : 0 ==> OK, 1 ==> UNALLOC
  7525. instr[29] ==> S : 0 ==> OK, 1 ==> UNALLOC
  7526. instr[23,22] ==> type : 0 ==> single, 01 ==> double, 1x ==> UNALLOC
  7527. instr[15,14] ==> op : 00 ==> OK, ow ==> UNALLOC
  7528. instr[4,0] ==> opcode2 : 00000 ==> FCMP, 10000 ==> FCMPE,
  7529. 01000 ==> FCMPZ, 11000 ==> FCMPEZ,
  7530. ow ==> UNALLOC */
  7531. uint32_t dispatch;
  7532. uint32_t M_S = (INSTR (31, 31) << 1) | INSTR (29, 29);
  7533. uint32_t type = INSTR (23, 22);
  7534. uint32_t op = INSTR (15, 14);
  7535. uint32_t op2_2_0 = INSTR (2, 0);
  7536. if (op2_2_0 != 0)
  7537. HALT_UNALLOC;
  7538. if (M_S != 0)
  7539. HALT_UNALLOC;
  7540. if (type > 1)
  7541. HALT_UNALLOC;
  7542. if (op != 0)
  7543. HALT_UNALLOC;
  7544. /* dispatch on type and top 2 bits of opcode. */
  7545. dispatch = (type << 2) | INSTR (4, 3);
  7546. switch (dispatch)
  7547. {
  7548. case 0: fcmps (cpu); return;
  7549. case 1: fcmpzs (cpu); return;
  7550. case 2: fcmpes (cpu); return;
  7551. case 3: fcmpzes (cpu); return;
  7552. case 4: fcmpd (cpu); return;
  7553. case 5: fcmpzd (cpu); return;
  7554. case 6: fcmped (cpu); return;
  7555. case 7: fcmpzed (cpu); return;
  7556. }
  7557. }
  7558. static void
  7559. do_scalar_FADDP (sim_cpu *cpu)
  7560. {
  7561. /* instr [31,23] = 0111 1110 0
  7562. instr [22] = single(0)/double(1)
  7563. instr [21,10] = 11 0000 1101 10
  7564. instr [9,5] = Fn
  7565. instr [4,0] = Fd. */
  7566. unsigned Fn = INSTR (9, 5);
  7567. unsigned Fd = INSTR (4, 0);
  7568. NYI_assert (31, 23, 0x0FC);
  7569. NYI_assert (21, 10, 0xC36);
  7570. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7571. if (INSTR (22, 22))
  7572. {
  7573. double val1 = aarch64_get_vec_double (cpu, Fn, 0);
  7574. double val2 = aarch64_get_vec_double (cpu, Fn, 1);
  7575. aarch64_set_FP_double (cpu, Fd, val1 + val2);
  7576. }
  7577. else
  7578. {
  7579. float val1 = aarch64_get_vec_float (cpu, Fn, 0);
  7580. float val2 = aarch64_get_vec_float (cpu, Fn, 1);
  7581. aarch64_set_FP_float (cpu, Fd, val1 + val2);
  7582. }
  7583. }
  7584. /* Floating point absolute difference. */
  7585. static void
  7586. do_scalar_FABD (sim_cpu *cpu)
  7587. {
  7588. /* instr [31,23] = 0111 1110 1
  7589. instr [22] = float(0)/double(1)
  7590. instr [21] = 1
  7591. instr [20,16] = Rm
  7592. instr [15,10] = 1101 01
  7593. instr [9, 5] = Rn
  7594. instr [4, 0] = Rd. */
  7595. unsigned rm = INSTR (20, 16);
  7596. unsigned rn = INSTR (9, 5);
  7597. unsigned rd = INSTR (4, 0);
  7598. NYI_assert (31, 23, 0x0FD);
  7599. NYI_assert (21, 21, 1);
  7600. NYI_assert (15, 10, 0x35);
  7601. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7602. if (INSTR (22, 22))
  7603. aarch64_set_FP_double (cpu, rd,
  7604. fabs (aarch64_get_FP_double (cpu, rn)
  7605. - aarch64_get_FP_double (cpu, rm)));
  7606. else
  7607. aarch64_set_FP_float (cpu, rd,
  7608. fabsf (aarch64_get_FP_float (cpu, rn)
  7609. - aarch64_get_FP_float (cpu, rm)));
  7610. }
  7611. static void
  7612. do_scalar_CMGT (sim_cpu *cpu)
  7613. {
  7614. /* instr [31,21] = 0101 1110 111
  7615. instr [20,16] = Rm
  7616. instr [15,10] = 00 1101
  7617. instr [9, 5] = Rn
  7618. instr [4, 0] = Rd. */
  7619. unsigned rm = INSTR (20, 16);
  7620. unsigned rn = INSTR (9, 5);
  7621. unsigned rd = INSTR (4, 0);
  7622. NYI_assert (31, 21, 0x2F7);
  7623. NYI_assert (15, 10, 0x0D);
  7624. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7625. aarch64_set_vec_u64 (cpu, rd, 0,
  7626. aarch64_get_vec_u64 (cpu, rn, 0) >
  7627. aarch64_get_vec_u64 (cpu, rm, 0) ? -1L : 0L);
  7628. }
  7629. static void
  7630. do_scalar_USHR (sim_cpu *cpu)
  7631. {
  7632. /* instr [31,23] = 0111 1111 0
  7633. instr [22,16] = shift amount
  7634. instr [15,10] = 0000 01
  7635. instr [9, 5] = Rn
  7636. instr [4, 0] = Rd. */
  7637. unsigned amount = 128 - INSTR (22, 16);
  7638. unsigned rn = INSTR (9, 5);
  7639. unsigned rd = INSTR (4, 0);
  7640. NYI_assert (31, 23, 0x0FE);
  7641. NYI_assert (15, 10, 0x01);
  7642. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7643. aarch64_set_vec_u64 (cpu, rd, 0,
  7644. aarch64_get_vec_u64 (cpu, rn, 0) >> amount);
  7645. }
  7646. static void
  7647. do_scalar_SSHL (sim_cpu *cpu)
  7648. {
  7649. /* instr [31,21] = 0101 1110 111
  7650. instr [20,16] = Rm
  7651. instr [15,10] = 0100 01
  7652. instr [9, 5] = Rn
  7653. instr [4, 0] = Rd. */
  7654. unsigned rm = INSTR (20, 16);
  7655. unsigned rn = INSTR (9, 5);
  7656. unsigned rd = INSTR (4, 0);
  7657. signed int shift = aarch64_get_vec_s8 (cpu, rm, 0);
  7658. NYI_assert (31, 21, 0x2F7);
  7659. NYI_assert (15, 10, 0x11);
  7660. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7661. if (shift >= 0)
  7662. aarch64_set_vec_s64 (cpu, rd, 0,
  7663. aarch64_get_vec_s64 (cpu, rn, 0) << shift);
  7664. else
  7665. aarch64_set_vec_s64 (cpu, rd, 0,
  7666. aarch64_get_vec_s64 (cpu, rn, 0) >> - shift);
  7667. }
  7668. /* Floating point scalar compare greater than or equal to 0. */
  7669. static void
  7670. do_scalar_FCMGE_zero (sim_cpu *cpu)
  7671. {
  7672. /* instr [31,23] = 0111 1110 1
  7673. instr [22,22] = size
  7674. instr [21,16] = 1000 00
  7675. instr [15,10] = 1100 10
  7676. instr [9, 5] = Rn
  7677. instr [4, 0] = Rd. */
  7678. unsigned size = INSTR (22, 22);
  7679. unsigned rn = INSTR (9, 5);
  7680. unsigned rd = INSTR (4, 0);
  7681. NYI_assert (31, 23, 0x0FD);
  7682. NYI_assert (21, 16, 0x20);
  7683. NYI_assert (15, 10, 0x32);
  7684. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7685. if (size)
  7686. aarch64_set_vec_u64 (cpu, rd, 0,
  7687. aarch64_get_vec_double (cpu, rn, 0) >= 0.0 ? -1 : 0);
  7688. else
  7689. aarch64_set_vec_u32 (cpu, rd, 0,
  7690. aarch64_get_vec_float (cpu, rn, 0) >= 0.0 ? -1 : 0);
  7691. }
  7692. /* Floating point scalar compare less than or equal to 0. */
  7693. static void
  7694. do_scalar_FCMLE_zero (sim_cpu *cpu)
  7695. {
  7696. /* instr [31,23] = 0111 1110 1
  7697. instr [22,22] = size
  7698. instr [21,16] = 1000 00
  7699. instr [15,10] = 1101 10
  7700. instr [9, 5] = Rn
  7701. instr [4, 0] = Rd. */
  7702. unsigned size = INSTR (22, 22);
  7703. unsigned rn = INSTR (9, 5);
  7704. unsigned rd = INSTR (4, 0);
  7705. NYI_assert (31, 23, 0x0FD);
  7706. NYI_assert (21, 16, 0x20);
  7707. NYI_assert (15, 10, 0x36);
  7708. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7709. if (size)
  7710. aarch64_set_vec_u64 (cpu, rd, 0,
  7711. aarch64_get_vec_double (cpu, rn, 0) <= 0.0 ? -1 : 0);
  7712. else
  7713. aarch64_set_vec_u32 (cpu, rd, 0,
  7714. aarch64_get_vec_float (cpu, rn, 0) <= 0.0 ? -1 : 0);
  7715. }
  7716. /* Floating point scalar compare greater than 0. */
  7717. static void
  7718. do_scalar_FCMGT_zero (sim_cpu *cpu)
  7719. {
  7720. /* instr [31,23] = 0101 1110 1
  7721. instr [22,22] = size
  7722. instr [21,16] = 1000 00
  7723. instr [15,10] = 1100 10
  7724. instr [9, 5] = Rn
  7725. instr [4, 0] = Rd. */
  7726. unsigned size = INSTR (22, 22);
  7727. unsigned rn = INSTR (9, 5);
  7728. unsigned rd = INSTR (4, 0);
  7729. NYI_assert (31, 23, 0x0BD);
  7730. NYI_assert (21, 16, 0x20);
  7731. NYI_assert (15, 10, 0x32);
  7732. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7733. if (size)
  7734. aarch64_set_vec_u64 (cpu, rd, 0,
  7735. aarch64_get_vec_double (cpu, rn, 0) > 0.0 ? -1 : 0);
  7736. else
  7737. aarch64_set_vec_u32 (cpu, rd, 0,
  7738. aarch64_get_vec_float (cpu, rn, 0) > 0.0 ? -1 : 0);
  7739. }
  7740. /* Floating point scalar compare equal to 0. */
  7741. static void
  7742. do_scalar_FCMEQ_zero (sim_cpu *cpu)
  7743. {
  7744. /* instr [31,23] = 0101 1110 1
  7745. instr [22,22] = size
  7746. instr [21,16] = 1000 00
  7747. instr [15,10] = 1101 10
  7748. instr [9, 5] = Rn
  7749. instr [4, 0] = Rd. */
  7750. unsigned size = INSTR (22, 22);
  7751. unsigned rn = INSTR (9, 5);
  7752. unsigned rd = INSTR (4, 0);
  7753. NYI_assert (31, 23, 0x0BD);
  7754. NYI_assert (21, 16, 0x20);
  7755. NYI_assert (15, 10, 0x36);
  7756. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7757. if (size)
  7758. aarch64_set_vec_u64 (cpu, rd, 0,
  7759. aarch64_get_vec_double (cpu, rn, 0) == 0.0 ? -1 : 0);
  7760. else
  7761. aarch64_set_vec_u32 (cpu, rd, 0,
  7762. aarch64_get_vec_float (cpu, rn, 0) == 0.0 ? -1 : 0);
  7763. }
  7764. /* Floating point scalar compare less than 0. */
  7765. static void
  7766. do_scalar_FCMLT_zero (sim_cpu *cpu)
  7767. {
  7768. /* instr [31,23] = 0101 1110 1
  7769. instr [22,22] = size
  7770. instr [21,16] = 1000 00
  7771. instr [15,10] = 1110 10
  7772. instr [9, 5] = Rn
  7773. instr [4, 0] = Rd. */
  7774. unsigned size = INSTR (22, 22);
  7775. unsigned rn = INSTR (9, 5);
  7776. unsigned rd = INSTR (4, 0);
  7777. NYI_assert (31, 23, 0x0BD);
  7778. NYI_assert (21, 16, 0x20);
  7779. NYI_assert (15, 10, 0x3A);
  7780. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7781. if (size)
  7782. aarch64_set_vec_u64 (cpu, rd, 0,
  7783. aarch64_get_vec_double (cpu, rn, 0) < 0.0 ? -1 : 0);
  7784. else
  7785. aarch64_set_vec_u32 (cpu, rd, 0,
  7786. aarch64_get_vec_float (cpu, rn, 0) < 0.0 ? -1 : 0);
  7787. }
  7788. static void
  7789. do_scalar_shift (sim_cpu *cpu)
  7790. {
  7791. /* instr [31,23] = 0101 1111 0
  7792. instr [22,16] = shift amount
  7793. instr [15,10] = 0101 01 [SHL]
  7794. instr [15,10] = 0000 01 [SSHR]
  7795. instr [9, 5] = Rn
  7796. instr [4, 0] = Rd. */
  7797. unsigned rn = INSTR (9, 5);
  7798. unsigned rd = INSTR (4, 0);
  7799. unsigned amount;
  7800. NYI_assert (31, 23, 0x0BE);
  7801. if (INSTR (22, 22) == 0)
  7802. HALT_UNALLOC;
  7803. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7804. switch (INSTR (15, 10))
  7805. {
  7806. case 0x01: /* SSHR */
  7807. amount = 128 - INSTR (22, 16);
  7808. aarch64_set_vec_s64 (cpu, rd, 0,
  7809. aarch64_get_vec_s64 (cpu, rn, 0) >> amount);
  7810. return;
  7811. case 0x15: /* SHL */
  7812. amount = INSTR (22, 16) - 64;
  7813. aarch64_set_vec_u64 (cpu, rd, 0,
  7814. aarch64_get_vec_u64 (cpu, rn, 0) << amount);
  7815. return;
  7816. default:
  7817. HALT_NYI;
  7818. }
  7819. }
  7820. /* FCMEQ FCMGT FCMGE. */
  7821. static void
  7822. do_scalar_FCM (sim_cpu *cpu)
  7823. {
  7824. /* instr [31,30] = 01
  7825. instr [29] = U
  7826. instr [28,24] = 1 1110
  7827. instr [23] = E
  7828. instr [22] = size
  7829. instr [21] = 1
  7830. instr [20,16] = Rm
  7831. instr [15,12] = 1110
  7832. instr [11] = AC
  7833. instr [10] = 1
  7834. instr [9, 5] = Rn
  7835. instr [4, 0] = Rd. */
  7836. unsigned rm = INSTR (20, 16);
  7837. unsigned rn = INSTR (9, 5);
  7838. unsigned rd = INSTR (4, 0);
  7839. unsigned EUac = (INSTR (23, 23) << 2) | (INSTR (29, 29) << 1) | INSTR (11, 11);
  7840. unsigned result;
  7841. float val1;
  7842. float val2;
  7843. NYI_assert (31, 30, 1);
  7844. NYI_assert (28, 24, 0x1E);
  7845. NYI_assert (21, 21, 1);
  7846. NYI_assert (15, 12, 0xE);
  7847. NYI_assert (10, 10, 1);
  7848. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7849. if (INSTR (22, 22))
  7850. {
  7851. double val1 = aarch64_get_FP_double (cpu, rn);
  7852. double val2 = aarch64_get_FP_double (cpu, rm);
  7853. switch (EUac)
  7854. {
  7855. case 0: /* 000 */
  7856. result = val1 == val2;
  7857. break;
  7858. case 3: /* 011 */
  7859. val1 = fabs (val1);
  7860. val2 = fabs (val2);
  7861. /* Fall through. */
  7862. case 2: /* 010 */
  7863. result = val1 >= val2;
  7864. break;
  7865. case 7: /* 111 */
  7866. val1 = fabs (val1);
  7867. val2 = fabs (val2);
  7868. /* Fall through. */
  7869. case 6: /* 110 */
  7870. result = val1 > val2;
  7871. break;
  7872. default:
  7873. HALT_UNALLOC;
  7874. }
  7875. aarch64_set_vec_u32 (cpu, rd, 0, result ? -1 : 0);
  7876. return;
  7877. }
  7878. val1 = aarch64_get_FP_float (cpu, rn);
  7879. val2 = aarch64_get_FP_float (cpu, rm);
  7880. switch (EUac)
  7881. {
  7882. case 0: /* 000 */
  7883. result = val1 == val2;
  7884. break;
  7885. case 3: /* 011 */
  7886. val1 = fabsf (val1);
  7887. val2 = fabsf (val2);
  7888. /* Fall through. */
  7889. case 2: /* 010 */
  7890. result = val1 >= val2;
  7891. break;
  7892. case 7: /* 111 */
  7893. val1 = fabsf (val1);
  7894. val2 = fabsf (val2);
  7895. /* Fall through. */
  7896. case 6: /* 110 */
  7897. result = val1 > val2;
  7898. break;
  7899. default:
  7900. HALT_UNALLOC;
  7901. }
  7902. aarch64_set_vec_u32 (cpu, rd, 0, result ? -1 : 0);
  7903. }
  7904. /* An alias of DUP. */
  7905. static void
  7906. do_scalar_MOV (sim_cpu *cpu)
  7907. {
  7908. /* instr [31,21] = 0101 1110 000
  7909. instr [20,16] = imm5
  7910. instr [15,10] = 0000 01
  7911. instr [9, 5] = Rn
  7912. instr [4, 0] = Rd. */
  7913. unsigned rn = INSTR (9, 5);
  7914. unsigned rd = INSTR (4, 0);
  7915. unsigned index;
  7916. NYI_assert (31, 21, 0x2F0);
  7917. NYI_assert (15, 10, 0x01);
  7918. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7919. if (INSTR (16, 16))
  7920. {
  7921. /* 8-bit. */
  7922. index = INSTR (20, 17);
  7923. aarch64_set_vec_u8
  7924. (cpu, rd, 0, aarch64_get_vec_u8 (cpu, rn, index));
  7925. }
  7926. else if (INSTR (17, 17))
  7927. {
  7928. /* 16-bit. */
  7929. index = INSTR (20, 18);
  7930. aarch64_set_vec_u16
  7931. (cpu, rd, 0, aarch64_get_vec_u16 (cpu, rn, index));
  7932. }
  7933. else if (INSTR (18, 18))
  7934. {
  7935. /* 32-bit. */
  7936. index = INSTR (20, 19);
  7937. aarch64_set_vec_u32
  7938. (cpu, rd, 0, aarch64_get_vec_u32 (cpu, rn, index));
  7939. }
  7940. else if (INSTR (19, 19))
  7941. {
  7942. /* 64-bit. */
  7943. index = INSTR (20, 20);
  7944. aarch64_set_vec_u64
  7945. (cpu, rd, 0, aarch64_get_vec_u64 (cpu, rn, index));
  7946. }
  7947. else
  7948. HALT_UNALLOC;
  7949. }
  7950. static void
  7951. do_scalar_NEG (sim_cpu *cpu)
  7952. {
  7953. /* instr [31,10] = 0111 1110 1110 0000 1011 10
  7954. instr [9, 5] = Rn
  7955. instr [4, 0] = Rd. */
  7956. unsigned rn = INSTR (9, 5);
  7957. unsigned rd = INSTR (4, 0);
  7958. NYI_assert (31, 10, 0x1FB82E);
  7959. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7960. aarch64_set_vec_u64 (cpu, rd, 0, - aarch64_get_vec_u64 (cpu, rn, 0));
  7961. }
  7962. static void
  7963. do_scalar_USHL (sim_cpu *cpu)
  7964. {
  7965. /* instr [31,21] = 0111 1110 111
  7966. instr [20,16] = Rm
  7967. instr [15,10] = 0100 01
  7968. instr [9, 5] = Rn
  7969. instr [4, 0] = Rd. */
  7970. unsigned rm = INSTR (20, 16);
  7971. unsigned rn = INSTR (9, 5);
  7972. unsigned rd = INSTR (4, 0);
  7973. signed int shift = aarch64_get_vec_s8 (cpu, rm, 0);
  7974. NYI_assert (31, 21, 0x3F7);
  7975. NYI_assert (15, 10, 0x11);
  7976. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  7977. if (shift >= 0)
  7978. aarch64_set_vec_u64 (cpu, rd, 0, aarch64_get_vec_u64 (cpu, rn, 0) << shift);
  7979. else
  7980. aarch64_set_vec_u64 (cpu, rd, 0, aarch64_get_vec_u64 (cpu, rn, 0) >> - shift);
  7981. }
  7982. static void
  7983. do_double_add (sim_cpu *cpu)
  7984. {
  7985. /* instr [31,21] = 0101 1110 111
  7986. instr [20,16] = Fn
  7987. instr [15,10] = 1000 01
  7988. instr [9,5] = Fm
  7989. instr [4,0] = Fd. */
  7990. unsigned Fd;
  7991. unsigned Fm;
  7992. unsigned Fn;
  7993. double val1;
  7994. double val2;
  7995. NYI_assert (31, 21, 0x2F7);
  7996. NYI_assert (15, 10, 0x21);
  7997. Fd = INSTR (4, 0);
  7998. Fm = INSTR (9, 5);
  7999. Fn = INSTR (20, 16);
  8000. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8001. val1 = aarch64_get_FP_double (cpu, Fm);
  8002. val2 = aarch64_get_FP_double (cpu, Fn);
  8003. aarch64_set_FP_double (cpu, Fd, val1 + val2);
  8004. }
  8005. static void
  8006. do_scalar_UCVTF (sim_cpu *cpu)
  8007. {
  8008. /* instr [31,23] = 0111 1110 0
  8009. instr [22] = single(0)/double(1)
  8010. instr [21,10] = 10 0001 1101 10
  8011. instr [9,5] = rn
  8012. instr [4,0] = rd. */
  8013. unsigned rn = INSTR (9, 5);
  8014. unsigned rd = INSTR (4, 0);
  8015. NYI_assert (31, 23, 0x0FC);
  8016. NYI_assert (21, 10, 0x876);
  8017. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8018. if (INSTR (22, 22))
  8019. {
  8020. uint64_t val = aarch64_get_vec_u64 (cpu, rn, 0);
  8021. aarch64_set_vec_double (cpu, rd, 0, (double) val);
  8022. }
  8023. else
  8024. {
  8025. uint32_t val = aarch64_get_vec_u32 (cpu, rn, 0);
  8026. aarch64_set_vec_float (cpu, rd, 0, (float) val);
  8027. }
  8028. }
  8029. static void
  8030. do_scalar_vec (sim_cpu *cpu)
  8031. {
  8032. /* instr [30] = 1. */
  8033. /* instr [28,25] = 1111. */
  8034. switch (INSTR (31, 23))
  8035. {
  8036. case 0xBC:
  8037. switch (INSTR (15, 10))
  8038. {
  8039. case 0x01: do_scalar_MOV (cpu); return;
  8040. case 0x39: do_scalar_FCM (cpu); return;
  8041. case 0x3B: do_scalar_FCM (cpu); return;
  8042. }
  8043. break;
  8044. case 0xBE: do_scalar_shift (cpu); return;
  8045. case 0xFC:
  8046. switch (INSTR (15, 10))
  8047. {
  8048. case 0x36:
  8049. switch (INSTR (21, 16))
  8050. {
  8051. case 0x30: do_scalar_FADDP (cpu); return;
  8052. case 0x21: do_scalar_UCVTF (cpu); return;
  8053. }
  8054. HALT_NYI;
  8055. case 0x39: do_scalar_FCM (cpu); return;
  8056. case 0x3B: do_scalar_FCM (cpu); return;
  8057. }
  8058. break;
  8059. case 0xFD:
  8060. switch (INSTR (15, 10))
  8061. {
  8062. case 0x0D: do_scalar_CMGT (cpu); return;
  8063. case 0x11: do_scalar_USHL (cpu); return;
  8064. case 0x2E: do_scalar_NEG (cpu); return;
  8065. case 0x32: do_scalar_FCMGE_zero (cpu); return;
  8066. case 0x35: do_scalar_FABD (cpu); return;
  8067. case 0x36: do_scalar_FCMLE_zero (cpu); return;
  8068. case 0x39: do_scalar_FCM (cpu); return;
  8069. case 0x3B: do_scalar_FCM (cpu); return;
  8070. default:
  8071. HALT_NYI;
  8072. }
  8073. case 0xFE: do_scalar_USHR (cpu); return;
  8074. case 0xBD:
  8075. switch (INSTR (15, 10))
  8076. {
  8077. case 0x21: do_double_add (cpu); return;
  8078. case 0x11: do_scalar_SSHL (cpu); return;
  8079. case 0x32: do_scalar_FCMGT_zero (cpu); return;
  8080. case 0x36: do_scalar_FCMEQ_zero (cpu); return;
  8081. case 0x3A: do_scalar_FCMLT_zero (cpu); return;
  8082. default:
  8083. HALT_NYI;
  8084. }
  8085. default:
  8086. HALT_NYI;
  8087. }
  8088. }
  8089. static void
  8090. dexAdvSIMD1 (sim_cpu *cpu)
  8091. {
  8092. /* instr [28,25] = 1 111. */
  8093. /* We are currently only interested in the basic
  8094. scalar fp routines which all have bit 30 = 0. */
  8095. if (INSTR (30, 30))
  8096. do_scalar_vec (cpu);
  8097. /* instr[24] is set for FP data processing 3-source and clear for
  8098. all other basic scalar fp instruction groups. */
  8099. else if (INSTR (24, 24))
  8100. dexSimpleFPDataProc3Source (cpu);
  8101. /* instr[21] is clear for floating <-> fixed conversions and set for
  8102. all other basic scalar fp instruction groups. */
  8103. else if (!INSTR (21, 21))
  8104. dexSimpleFPFixedConvert (cpu);
  8105. /* instr[11,10] : 01 ==> cond compare, 10 ==> Data Proc 2 Source
  8106. 11 ==> cond select, 00 ==> other. */
  8107. else
  8108. switch (INSTR (11, 10))
  8109. {
  8110. case 1: dexSimpleFPCondCompare (cpu); return;
  8111. case 2: dexSimpleFPDataProc2Source (cpu); return;
  8112. case 3: dexSimpleFPCondSelect (cpu); return;
  8113. default:
  8114. /* Now an ordered cascade of tests.
  8115. FP immediate has instr [12] == 1.
  8116. FP compare has instr [13] == 1.
  8117. FP Data Proc 1 Source has instr [14] == 1.
  8118. FP floating <--> integer conversions has instr [15] == 0. */
  8119. if (INSTR (12, 12))
  8120. dexSimpleFPImmediate (cpu);
  8121. else if (INSTR (13, 13))
  8122. dexSimpleFPCompare (cpu);
  8123. else if (INSTR (14, 14))
  8124. dexSimpleFPDataProc1Source (cpu);
  8125. else if (!INSTR (15, 15))
  8126. dexSimpleFPIntegerConvert (cpu);
  8127. else
  8128. /* If we get here then instr[15] == 1 which means UNALLOC. */
  8129. HALT_UNALLOC;
  8130. }
  8131. }
  8132. /* PC relative addressing. */
  8133. static void
  8134. pcadr (sim_cpu *cpu)
  8135. {
  8136. /* instr[31] = op : 0 ==> ADR, 1 ==> ADRP
  8137. instr[30,29] = immlo
  8138. instr[23,5] = immhi. */
  8139. uint64_t address;
  8140. unsigned rd = INSTR (4, 0);
  8141. uint32_t isPage = INSTR (31, 31);
  8142. union { int64_t u64; uint64_t s64; } imm;
  8143. uint64_t offset;
  8144. imm.s64 = simm64 (aarch64_get_instr (cpu), 23, 5);
  8145. offset = imm.u64;
  8146. offset = (offset << 2) | INSTR (30, 29);
  8147. address = aarch64_get_PC (cpu);
  8148. if (isPage)
  8149. {
  8150. offset <<= 12;
  8151. address &= ~0xfff;
  8152. }
  8153. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8154. aarch64_set_reg_u64 (cpu, rd, NO_SP, address + offset);
  8155. }
  8156. /* Specific decode and execute for group Data Processing Immediate. */
  8157. static void
  8158. dexPCRelAddressing (sim_cpu *cpu)
  8159. {
  8160. /* assert instr[28,24] = 10000. */
  8161. pcadr (cpu);
  8162. }
  8163. /* Immediate logical.
  8164. The bimm32/64 argument is constructed by replicating a 2, 4, 8,
  8165. 16, 32 or 64 bit sequence pulled out at decode and possibly
  8166. inverting it..
  8167. N.B. the output register (dest) can normally be Xn or SP
  8168. the exception occurs for flag setting instructions which may
  8169. only use Xn for the output (dest). The input register can
  8170. never be SP. */
  8171. /* 32 bit and immediate. */
  8172. static void
  8173. and32 (sim_cpu *cpu, uint32_t bimm)
  8174. {
  8175. unsigned rn = INSTR (9, 5);
  8176. unsigned rd = INSTR (4, 0);
  8177. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8178. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  8179. aarch64_get_reg_u32 (cpu, rn, NO_SP) & bimm);
  8180. }
  8181. /* 64 bit and immediate. */
  8182. static void
  8183. and64 (sim_cpu *cpu, uint64_t bimm)
  8184. {
  8185. unsigned rn = INSTR (9, 5);
  8186. unsigned rd = INSTR (4, 0);
  8187. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8188. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  8189. aarch64_get_reg_u64 (cpu, rn, NO_SP) & bimm);
  8190. }
  8191. /* 32 bit and immediate set flags. */
  8192. static void
  8193. ands32 (sim_cpu *cpu, uint32_t bimm)
  8194. {
  8195. unsigned rn = INSTR (9, 5);
  8196. unsigned rd = INSTR (4, 0);
  8197. uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  8198. uint32_t value2 = bimm;
  8199. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8200. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
  8201. set_flags_for_binop32 (cpu, value1 & value2);
  8202. }
  8203. /* 64 bit and immediate set flags. */
  8204. static void
  8205. ands64 (sim_cpu *cpu, uint64_t bimm)
  8206. {
  8207. unsigned rn = INSTR (9, 5);
  8208. unsigned rd = INSTR (4, 0);
  8209. uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  8210. uint64_t value2 = bimm;
  8211. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8212. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
  8213. set_flags_for_binop64 (cpu, value1 & value2);
  8214. }
  8215. /* 32 bit exclusive or immediate. */
  8216. static void
  8217. eor32 (sim_cpu *cpu, uint32_t bimm)
  8218. {
  8219. unsigned rn = INSTR (9, 5);
  8220. unsigned rd = INSTR (4, 0);
  8221. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8222. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  8223. aarch64_get_reg_u32 (cpu, rn, NO_SP) ^ bimm);
  8224. }
  8225. /* 64 bit exclusive or immediate. */
  8226. static void
  8227. eor64 (sim_cpu *cpu, uint64_t bimm)
  8228. {
  8229. unsigned rn = INSTR (9, 5);
  8230. unsigned rd = INSTR (4, 0);
  8231. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8232. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  8233. aarch64_get_reg_u64 (cpu, rn, NO_SP) ^ bimm);
  8234. }
  8235. /* 32 bit or immediate. */
  8236. static void
  8237. orr32 (sim_cpu *cpu, uint32_t bimm)
  8238. {
  8239. unsigned rn = INSTR (9, 5);
  8240. unsigned rd = INSTR (4, 0);
  8241. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8242. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  8243. aarch64_get_reg_u32 (cpu, rn, NO_SP) | bimm);
  8244. }
  8245. /* 64 bit or immediate. */
  8246. static void
  8247. orr64 (sim_cpu *cpu, uint64_t bimm)
  8248. {
  8249. unsigned rn = INSTR (9, 5);
  8250. unsigned rd = INSTR (4, 0);
  8251. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8252. aarch64_set_reg_u64 (cpu, rd, SP_OK,
  8253. aarch64_get_reg_u64 (cpu, rn, NO_SP) | bimm);
  8254. }
  8255. /* Logical shifted register.
  8256. These allow an optional LSL, ASR, LSR or ROR to the second source
  8257. register with a count up to the register bit count.
  8258. N.B register args may not be SP. */
  8259. /* 32 bit AND shifted register. */
  8260. static void
  8261. and32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8262. {
  8263. unsigned rm = INSTR (20, 16);
  8264. unsigned rn = INSTR (9, 5);
  8265. unsigned rd = INSTR (4, 0);
  8266. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8267. aarch64_set_reg_u64
  8268. (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
  8269. & shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
  8270. }
  8271. /* 64 bit AND shifted register. */
  8272. static void
  8273. and64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8274. {
  8275. unsigned rm = INSTR (20, 16);
  8276. unsigned rn = INSTR (9, 5);
  8277. unsigned rd = INSTR (4, 0);
  8278. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8279. aarch64_set_reg_u64
  8280. (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
  8281. & shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
  8282. }
  8283. /* 32 bit AND shifted register setting flags. */
  8284. static void
  8285. ands32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8286. {
  8287. unsigned rm = INSTR (20, 16);
  8288. unsigned rn = INSTR (9, 5);
  8289. unsigned rd = INSTR (4, 0);
  8290. uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  8291. uint32_t value2 = shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  8292. shift, count);
  8293. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8294. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
  8295. set_flags_for_binop32 (cpu, value1 & value2);
  8296. }
  8297. /* 64 bit AND shifted register setting flags. */
  8298. static void
  8299. ands64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8300. {
  8301. unsigned rm = INSTR (20, 16);
  8302. unsigned rn = INSTR (9, 5);
  8303. unsigned rd = INSTR (4, 0);
  8304. uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  8305. uint64_t value2 = shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
  8306. shift, count);
  8307. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8308. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
  8309. set_flags_for_binop64 (cpu, value1 & value2);
  8310. }
  8311. /* 32 bit BIC shifted register. */
  8312. static void
  8313. bic32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8314. {
  8315. unsigned rm = INSTR (20, 16);
  8316. unsigned rn = INSTR (9, 5);
  8317. unsigned rd = INSTR (4, 0);
  8318. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8319. aarch64_set_reg_u64
  8320. (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
  8321. & ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
  8322. }
  8323. /* 64 bit BIC shifted register. */
  8324. static void
  8325. bic64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8326. {
  8327. unsigned rm = INSTR (20, 16);
  8328. unsigned rn = INSTR (9, 5);
  8329. unsigned rd = INSTR (4, 0);
  8330. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8331. aarch64_set_reg_u64
  8332. (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
  8333. & ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
  8334. }
  8335. /* 32 bit BIC shifted register setting flags. */
  8336. static void
  8337. bics32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8338. {
  8339. unsigned rm = INSTR (20, 16);
  8340. unsigned rn = INSTR (9, 5);
  8341. unsigned rd = INSTR (4, 0);
  8342. uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  8343. uint32_t value2 = ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  8344. shift, count);
  8345. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8346. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
  8347. set_flags_for_binop32 (cpu, value1 & value2);
  8348. }
  8349. /* 64 bit BIC shifted register setting flags. */
  8350. static void
  8351. bics64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8352. {
  8353. unsigned rm = INSTR (20, 16);
  8354. unsigned rn = INSTR (9, 5);
  8355. unsigned rd = INSTR (4, 0);
  8356. uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  8357. uint64_t value2 = ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
  8358. shift, count);
  8359. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8360. aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
  8361. set_flags_for_binop64 (cpu, value1 & value2);
  8362. }
  8363. /* 32 bit EON shifted register. */
  8364. static void
  8365. eon32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8366. {
  8367. unsigned rm = INSTR (20, 16);
  8368. unsigned rn = INSTR (9, 5);
  8369. unsigned rd = INSTR (4, 0);
  8370. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8371. aarch64_set_reg_u64
  8372. (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
  8373. ^ ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
  8374. }
  8375. /* 64 bit EON shifted register. */
  8376. static void
  8377. eon64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8378. {
  8379. unsigned rm = INSTR (20, 16);
  8380. unsigned rn = INSTR (9, 5);
  8381. unsigned rd = INSTR (4, 0);
  8382. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8383. aarch64_set_reg_u64
  8384. (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
  8385. ^ ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
  8386. }
  8387. /* 32 bit EOR shifted register. */
  8388. static void
  8389. eor32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8390. {
  8391. unsigned rm = INSTR (20, 16);
  8392. unsigned rn = INSTR (9, 5);
  8393. unsigned rd = INSTR (4, 0);
  8394. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8395. aarch64_set_reg_u64
  8396. (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
  8397. ^ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
  8398. }
  8399. /* 64 bit EOR shifted register. */
  8400. static void
  8401. eor64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8402. {
  8403. unsigned rm = INSTR (20, 16);
  8404. unsigned rn = INSTR (9, 5);
  8405. unsigned rd = INSTR (4, 0);
  8406. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8407. aarch64_set_reg_u64
  8408. (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
  8409. ^ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
  8410. }
  8411. /* 32 bit ORR shifted register. */
  8412. static void
  8413. orr32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8414. {
  8415. unsigned rm = INSTR (20, 16);
  8416. unsigned rn = INSTR (9, 5);
  8417. unsigned rd = INSTR (4, 0);
  8418. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8419. aarch64_set_reg_u64
  8420. (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
  8421. | shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
  8422. }
  8423. /* 64 bit ORR shifted register. */
  8424. static void
  8425. orr64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8426. {
  8427. unsigned rm = INSTR (20, 16);
  8428. unsigned rn = INSTR (9, 5);
  8429. unsigned rd = INSTR (4, 0);
  8430. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8431. aarch64_set_reg_u64
  8432. (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
  8433. | shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
  8434. }
  8435. /* 32 bit ORN shifted register. */
  8436. static void
  8437. orn32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8438. {
  8439. unsigned rm = INSTR (20, 16);
  8440. unsigned rn = INSTR (9, 5);
  8441. unsigned rd = INSTR (4, 0);
  8442. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8443. aarch64_set_reg_u64
  8444. (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
  8445. | ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
  8446. }
  8447. /* 64 bit ORN shifted register. */
  8448. static void
  8449. orn64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
  8450. {
  8451. unsigned rm = INSTR (20, 16);
  8452. unsigned rn = INSTR (9, 5);
  8453. unsigned rd = INSTR (4, 0);
  8454. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8455. aarch64_set_reg_u64
  8456. (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
  8457. | ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
  8458. }
  8459. static void
  8460. dexLogicalImmediate (sim_cpu *cpu)
  8461. {
  8462. /* assert instr[28,23] = 1001000
  8463. instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  8464. instr[30,29] = op : 0 ==> AND, 1 ==> ORR, 2 ==> EOR, 3 ==> ANDS
  8465. instr[22] = N : used to construct immediate mask
  8466. instr[21,16] = immr
  8467. instr[15,10] = imms
  8468. instr[9,5] = Rn
  8469. instr[4,0] = Rd */
  8470. /* 32 bit operations must have N = 0 or else we have an UNALLOC. */
  8471. uint32_t size = INSTR (31, 31);
  8472. uint32_t N = INSTR (22, 22);
  8473. /* uint32_t immr = INSTR (21, 16);. */
  8474. /* uint32_t imms = INSTR (15, 10);. */
  8475. uint32_t index = INSTR (22, 10);
  8476. uint64_t bimm64 = LITable [index];
  8477. uint32_t dispatch = INSTR (30, 29);
  8478. if (~size & N)
  8479. HALT_UNALLOC;
  8480. if (!bimm64)
  8481. HALT_UNALLOC;
  8482. if (size == 0)
  8483. {
  8484. uint32_t bimm = (uint32_t) bimm64;
  8485. switch (dispatch)
  8486. {
  8487. case 0: and32 (cpu, bimm); return;
  8488. case 1: orr32 (cpu, bimm); return;
  8489. case 2: eor32 (cpu, bimm); return;
  8490. case 3: ands32 (cpu, bimm); return;
  8491. }
  8492. }
  8493. else
  8494. {
  8495. switch (dispatch)
  8496. {
  8497. case 0: and64 (cpu, bimm64); return;
  8498. case 1: orr64 (cpu, bimm64); return;
  8499. case 2: eor64 (cpu, bimm64); return;
  8500. case 3: ands64 (cpu, bimm64); return;
  8501. }
  8502. }
  8503. HALT_UNALLOC;
  8504. }
  8505. /* Immediate move.
  8506. The uimm argument is a 16 bit value to be inserted into the
  8507. target register the pos argument locates the 16 bit word in the
  8508. dest register i.e. it is in {0, 1} for 32 bit and {0, 1, 2,
  8509. 3} for 64 bit.
  8510. N.B register arg may not be SP so it should be.
  8511. accessed using the setGZRegisterXXX accessors. */
  8512. /* 32 bit move 16 bit immediate zero remaining shorts. */
  8513. static void
  8514. movz32 (sim_cpu *cpu, uint32_t val, uint32_t pos)
  8515. {
  8516. unsigned rd = INSTR (4, 0);
  8517. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8518. aarch64_set_reg_u64 (cpu, rd, NO_SP, val << (pos * 16));
  8519. }
  8520. /* 64 bit move 16 bit immediate zero remaining shorts. */
  8521. static void
  8522. movz64 (sim_cpu *cpu, uint32_t val, uint32_t pos)
  8523. {
  8524. unsigned rd = INSTR (4, 0);
  8525. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8526. aarch64_set_reg_u64 (cpu, rd, NO_SP, ((uint64_t) val) << (pos * 16));
  8527. }
  8528. /* 32 bit move 16 bit immediate negated. */
  8529. static void
  8530. movn32 (sim_cpu *cpu, uint32_t val, uint32_t pos)
  8531. {
  8532. unsigned rd = INSTR (4, 0);
  8533. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8534. aarch64_set_reg_u64 (cpu, rd, NO_SP, ((val << (pos * 16)) ^ 0xffffffffU));
  8535. }
  8536. /* 64 bit move 16 bit immediate negated. */
  8537. static void
  8538. movn64 (sim_cpu *cpu, uint32_t val, uint32_t pos)
  8539. {
  8540. unsigned rd = INSTR (4, 0);
  8541. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8542. aarch64_set_reg_u64
  8543. (cpu, rd, NO_SP, ((((uint64_t) val) << (pos * 16))
  8544. ^ 0xffffffffffffffffULL));
  8545. }
  8546. /* 32 bit move 16 bit immediate keep remaining shorts. */
  8547. static void
  8548. movk32 (sim_cpu *cpu, uint32_t val, uint32_t pos)
  8549. {
  8550. unsigned rd = INSTR (4, 0);
  8551. uint32_t current = aarch64_get_reg_u32 (cpu, rd, NO_SP);
  8552. uint32_t value = val << (pos * 16);
  8553. uint32_t mask = ~(0xffffU << (pos * 16));
  8554. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8555. aarch64_set_reg_u64 (cpu, rd, NO_SP, (value | (current & mask)));
  8556. }
  8557. /* 64 bit move 16 it immediate keep remaining shorts. */
  8558. static void
  8559. movk64 (sim_cpu *cpu, uint32_t val, uint32_t pos)
  8560. {
  8561. unsigned rd = INSTR (4, 0);
  8562. uint64_t current = aarch64_get_reg_u64 (cpu, rd, NO_SP);
  8563. uint64_t value = (uint64_t) val << (pos * 16);
  8564. uint64_t mask = ~(0xffffULL << (pos * 16));
  8565. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8566. aarch64_set_reg_u64 (cpu, rd, NO_SP, (value | (current & mask)));
  8567. }
  8568. static void
  8569. dexMoveWideImmediate (sim_cpu *cpu)
  8570. {
  8571. /* assert instr[28:23] = 100101
  8572. instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  8573. instr[30,29] = op : 0 ==> MOVN, 1 ==> UNALLOC, 2 ==> MOVZ, 3 ==> MOVK
  8574. instr[22,21] = shift : 00 == LSL#0, 01 = LSL#16, 10 = LSL#32, 11 = LSL#48
  8575. instr[20,5] = uimm16
  8576. instr[4,0] = Rd */
  8577. /* N.B. the (multiple of 16) shift is applied by the called routine,
  8578. we just pass the multiplier. */
  8579. uint32_t imm;
  8580. uint32_t size = INSTR (31, 31);
  8581. uint32_t op = INSTR (30, 29);
  8582. uint32_t shift = INSTR (22, 21);
  8583. /* 32 bit can only shift 0 or 1 lot of 16.
  8584. anything else is an unallocated instruction. */
  8585. if (size == 0 && (shift > 1))
  8586. HALT_UNALLOC;
  8587. if (op == 1)
  8588. HALT_UNALLOC;
  8589. imm = INSTR (20, 5);
  8590. if (size == 0)
  8591. {
  8592. if (op == 0)
  8593. movn32 (cpu, imm, shift);
  8594. else if (op == 2)
  8595. movz32 (cpu, imm, shift);
  8596. else
  8597. movk32 (cpu, imm, shift);
  8598. }
  8599. else
  8600. {
  8601. if (op == 0)
  8602. movn64 (cpu, imm, shift);
  8603. else if (op == 2)
  8604. movz64 (cpu, imm, shift);
  8605. else
  8606. movk64 (cpu, imm, shift);
  8607. }
  8608. }
  8609. /* Bitfield operations.
  8610. These take a pair of bit positions r and s which are in {0..31}
  8611. or {0..63} depending on the instruction word size.
  8612. N.B register args may not be SP. */
  8613. /* OK, we start with ubfm which just needs to pick
  8614. some bits out of source zero the rest and write
  8615. the result to dest. Just need two logical shifts. */
  8616. /* 32 bit bitfield move, left and right of affected zeroed
  8617. if r <= s Wd<s-r:0> = Wn<s:r> else Wd<32+s-r,32-r> = Wn<s:0>. */
  8618. static void
  8619. ubfm32 (sim_cpu *cpu, uint32_t r, uint32_t s)
  8620. {
  8621. unsigned rd;
  8622. unsigned rn = INSTR (9, 5);
  8623. uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  8624. /* Pick either s+1-r or s+1 consecutive bits out of the original word. */
  8625. if (r <= s)
  8626. {
  8627. /* 31:...:s:xxx:r:...:0 ==> 31:...:s-r:xxx:0.
  8628. We want only bits s:xxx:r at the bottom of the word
  8629. so we LSL bit s up to bit 31 i.e. by 31 - s
  8630. and then we LSR to bring bit 31 down to bit s - r
  8631. i.e. by 31 + r - s. */
  8632. value <<= 31 - s;
  8633. value >>= 31 + r - s;
  8634. }
  8635. else
  8636. {
  8637. /* 31:...:s:xxx:0 ==> 31:...:31-(r-1)+s:xxx:31-(r-1):...:0
  8638. We want only bits s:xxx:0 starting at it 31-(r-1)
  8639. so we LSL bit s up to bit 31 i.e. by 31 - s
  8640. and then we LSL to bring bit 31 down to 31-(r-1)+s
  8641. i.e. by r - (s + 1). */
  8642. value <<= 31 - s;
  8643. value >>= r - (s + 1);
  8644. }
  8645. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8646. rd = INSTR (4, 0);
  8647. aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
  8648. }
  8649. /* 64 bit bitfield move, left and right of affected zeroed
  8650. if r <= s Wd<s-r:0> = Wn<s:r> else Wd<64+s-r,64-r> = Wn<s:0>. */
  8651. static void
  8652. ubfm (sim_cpu *cpu, uint32_t r, uint32_t s)
  8653. {
  8654. unsigned rd;
  8655. unsigned rn = INSTR (9, 5);
  8656. uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  8657. if (r <= s)
  8658. {
  8659. /* 63:...:s:xxx:r:...:0 ==> 63:...:s-r:xxx:0.
  8660. We want only bits s:xxx:r at the bottom of the word.
  8661. So we LSL bit s up to bit 63 i.e. by 63 - s
  8662. and then we LSR to bring bit 63 down to bit s - r
  8663. i.e. by 63 + r - s. */
  8664. value <<= 63 - s;
  8665. value >>= 63 + r - s;
  8666. }
  8667. else
  8668. {
  8669. /* 63:...:s:xxx:0 ==> 63:...:63-(r-1)+s:xxx:63-(r-1):...:0.
  8670. We want only bits s:xxx:0 starting at it 63-(r-1).
  8671. So we LSL bit s up to bit 63 i.e. by 63 - s
  8672. and then we LSL to bring bit 63 down to 63-(r-1)+s
  8673. i.e. by r - (s + 1). */
  8674. value <<= 63 - s;
  8675. value >>= r - (s + 1);
  8676. }
  8677. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8678. rd = INSTR (4, 0);
  8679. aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
  8680. }
  8681. /* The signed versions need to insert sign bits
  8682. on the left of the inserted bit field. so we do
  8683. much the same as the unsigned version except we
  8684. use an arithmetic shift right -- this just means
  8685. we need to operate on signed values. */
  8686. /* 32 bit bitfield move, left of affected sign-extended, right zeroed. */
  8687. /* If r <= s Wd<s-r:0> = Wn<s:r> else Wd<32+s-r,32-r> = Wn<s:0>. */
  8688. static void
  8689. sbfm32 (sim_cpu *cpu, uint32_t r, uint32_t s)
  8690. {
  8691. unsigned rd;
  8692. unsigned rn = INSTR (9, 5);
  8693. /* as per ubfm32 but use an ASR instead of an LSR. */
  8694. int32_t value = aarch64_get_reg_s32 (cpu, rn, NO_SP);
  8695. if (r <= s)
  8696. {
  8697. value <<= 31 - s;
  8698. value >>= 31 + r - s;
  8699. }
  8700. else
  8701. {
  8702. value <<= 31 - s;
  8703. value >>= r - (s + 1);
  8704. }
  8705. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8706. rd = INSTR (4, 0);
  8707. aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) value);
  8708. }
  8709. /* 64 bit bitfield move, left of affected sign-extended, right zeroed. */
  8710. /* If r <= s Wd<s-r:0> = Wn<s:r> else Wd<64+s-r,64-r> = Wn<s:0>. */
  8711. static void
  8712. sbfm (sim_cpu *cpu, uint32_t r, uint32_t s)
  8713. {
  8714. unsigned rd;
  8715. unsigned rn = INSTR (9, 5);
  8716. /* acpu per ubfm but use an ASR instead of an LSR. */
  8717. int64_t value = aarch64_get_reg_s64 (cpu, rn, NO_SP);
  8718. if (r <= s)
  8719. {
  8720. value <<= 63 - s;
  8721. value >>= 63 + r - s;
  8722. }
  8723. else
  8724. {
  8725. value <<= 63 - s;
  8726. value >>= r - (s + 1);
  8727. }
  8728. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8729. rd = INSTR (4, 0);
  8730. aarch64_set_reg_s64 (cpu, rd, NO_SP, value);
  8731. }
  8732. /* Finally, these versions leave non-affected bits
  8733. as is. so we need to generate the bits as per
  8734. ubfm and also generate a mask to pick the
  8735. bits from the original and computed values. */
  8736. /* 32 bit bitfield move, non-affected bits left as is.
  8737. If r <= s Wd<s-r:0> = Wn<s:r> else Wd<32+s-r,32-r> = Wn<s:0>. */
  8738. static void
  8739. bfm32 (sim_cpu *cpu, uint32_t r, uint32_t s)
  8740. {
  8741. unsigned rn = INSTR (9, 5);
  8742. uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  8743. uint32_t mask = -1;
  8744. unsigned rd;
  8745. uint32_t value2;
  8746. /* Pick either s+1-r or s+1 consecutive bits out of the original word. */
  8747. if (r <= s)
  8748. {
  8749. /* 31:...:s:xxx:r:...:0 ==> 31:...:s-r:xxx:0.
  8750. We want only bits s:xxx:r at the bottom of the word
  8751. so we LSL bit s up to bit 31 i.e. by 31 - s
  8752. and then we LSR to bring bit 31 down to bit s - r
  8753. i.e. by 31 + r - s. */
  8754. value <<= 31 - s;
  8755. value >>= 31 + r - s;
  8756. /* the mask must include the same bits. */
  8757. mask <<= 31 - s;
  8758. mask >>= 31 + r - s;
  8759. }
  8760. else
  8761. {
  8762. /* 31:...:s:xxx:0 ==> 31:...:31-(r-1)+s:xxx:31-(r-1):...:0.
  8763. We want only bits s:xxx:0 starting at it 31-(r-1)
  8764. so we LSL bit s up to bit 31 i.e. by 31 - s
  8765. and then we LSL to bring bit 31 down to 31-(r-1)+s
  8766. i.e. by r - (s + 1). */
  8767. value <<= 31 - s;
  8768. value >>= r - (s + 1);
  8769. /* The mask must include the same bits. */
  8770. mask <<= 31 - s;
  8771. mask >>= r - (s + 1);
  8772. }
  8773. rd = INSTR (4, 0);
  8774. value2 = aarch64_get_reg_u32 (cpu, rd, NO_SP);
  8775. value2 &= ~mask;
  8776. value2 |= value;
  8777. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8778. aarch64_set_reg_u64
  8779. (cpu, rd, NO_SP, (aarch64_get_reg_u32 (cpu, rd, NO_SP) & ~mask) | value);
  8780. }
  8781. /* 64 bit bitfield move, non-affected bits left as is.
  8782. If r <= s Wd<s-r:0> = Wn<s:r> else Wd<64+s-r,64-r> = Wn<s:0>. */
  8783. static void
  8784. bfm (sim_cpu *cpu, uint32_t r, uint32_t s)
  8785. {
  8786. unsigned rd;
  8787. unsigned rn = INSTR (9, 5);
  8788. uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  8789. uint64_t mask = 0xffffffffffffffffULL;
  8790. if (r <= s)
  8791. {
  8792. /* 63:...:s:xxx:r:...:0 ==> 63:...:s-r:xxx:0.
  8793. We want only bits s:xxx:r at the bottom of the word
  8794. so we LSL bit s up to bit 63 i.e. by 63 - s
  8795. and then we LSR to bring bit 63 down to bit s - r
  8796. i.e. by 63 + r - s. */
  8797. value <<= 63 - s;
  8798. value >>= 63 + r - s;
  8799. /* The mask must include the same bits. */
  8800. mask <<= 63 - s;
  8801. mask >>= 63 + r - s;
  8802. }
  8803. else
  8804. {
  8805. /* 63:...:s:xxx:0 ==> 63:...:63-(r-1)+s:xxx:63-(r-1):...:0
  8806. We want only bits s:xxx:0 starting at it 63-(r-1)
  8807. so we LSL bit s up to bit 63 i.e. by 63 - s
  8808. and then we LSL to bring bit 63 down to 63-(r-1)+s
  8809. i.e. by r - (s + 1). */
  8810. value <<= 63 - s;
  8811. value >>= r - (s + 1);
  8812. /* The mask must include the same bits. */
  8813. mask <<= 63 - s;
  8814. mask >>= r - (s + 1);
  8815. }
  8816. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8817. rd = INSTR (4, 0);
  8818. aarch64_set_reg_u64
  8819. (cpu, rd, NO_SP, (aarch64_get_reg_u64 (cpu, rd, NO_SP) & ~mask) | value);
  8820. }
  8821. static void
  8822. dexBitfieldImmediate (sim_cpu *cpu)
  8823. {
  8824. /* assert instr[28:23] = 100110
  8825. instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  8826. instr[30,29] = op : 0 ==> SBFM, 1 ==> BFM, 2 ==> UBFM, 3 ==> UNALLOC
  8827. instr[22] = N : must be 0 for 32 bit, 1 for 64 bit ow UNALLOC
  8828. instr[21,16] = immr : 0xxxxx for 32 bit, xxxxxx for 64 bit
  8829. instr[15,10] = imms : 0xxxxx for 32 bit, xxxxxx for 64 bit
  8830. instr[9,5] = Rn
  8831. instr[4,0] = Rd */
  8832. /* 32 bit operations must have N = 0 or else we have an UNALLOC. */
  8833. uint32_t dispatch;
  8834. uint32_t imms;
  8835. uint32_t size = INSTR (31, 31);
  8836. uint32_t N = INSTR (22, 22);
  8837. /* 32 bit operations must have immr[5] = 0 and imms[5] = 0. */
  8838. /* or else we have an UNALLOC. */
  8839. uint32_t immr = INSTR (21, 16);
  8840. if (~size & N)
  8841. HALT_UNALLOC;
  8842. if (!size && uimm (immr, 5, 5))
  8843. HALT_UNALLOC;
  8844. imms = INSTR (15, 10);
  8845. if (!size && uimm (imms, 5, 5))
  8846. HALT_UNALLOC;
  8847. /* Switch on combined size and op. */
  8848. dispatch = INSTR (31, 29);
  8849. switch (dispatch)
  8850. {
  8851. case 0: sbfm32 (cpu, immr, imms); return;
  8852. case 1: bfm32 (cpu, immr, imms); return;
  8853. case 2: ubfm32 (cpu, immr, imms); return;
  8854. case 4: sbfm (cpu, immr, imms); return;
  8855. case 5: bfm (cpu, immr, imms); return;
  8856. case 6: ubfm (cpu, immr, imms); return;
  8857. default: HALT_UNALLOC;
  8858. }
  8859. }
  8860. static void
  8861. do_EXTR_32 (sim_cpu *cpu)
  8862. {
  8863. /* instr[31:21] = 00010011100
  8864. instr[20,16] = Rm
  8865. instr[15,10] = imms : 0xxxxx for 32 bit
  8866. instr[9,5] = Rn
  8867. instr[4,0] = Rd */
  8868. unsigned rm = INSTR (20, 16);
  8869. unsigned imms = INSTR (15, 10) & 31;
  8870. unsigned rn = INSTR ( 9, 5);
  8871. unsigned rd = INSTR ( 4, 0);
  8872. uint64_t val1;
  8873. uint64_t val2;
  8874. val1 = aarch64_get_reg_u32 (cpu, rm, NO_SP);
  8875. val1 >>= imms;
  8876. val2 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  8877. val2 <<= (32 - imms);
  8878. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  8879. aarch64_set_reg_u64 (cpu, rd, NO_SP, val1 | val2);
  8880. }
  8881. static void
  8882. do_EXTR_64 (sim_cpu *cpu)
  8883. {
  8884. /* instr[31:21] = 10010011100
  8885. instr[20,16] = Rm
  8886. instr[15,10] = imms
  8887. instr[9,5] = Rn
  8888. instr[4,0] = Rd */
  8889. unsigned rm = INSTR (20, 16);
  8890. unsigned imms = INSTR (15, 10) & 63;
  8891. unsigned rn = INSTR ( 9, 5);
  8892. unsigned rd = INSTR ( 4, 0);
  8893. uint64_t val;
  8894. val = aarch64_get_reg_u64 (cpu, rm, NO_SP);
  8895. val >>= imms;
  8896. val |= (aarch64_get_reg_u64 (cpu, rn, NO_SP) << (64 - imms));
  8897. aarch64_set_reg_u64 (cpu, rd, NO_SP, val);
  8898. }
  8899. static void
  8900. dexExtractImmediate (sim_cpu *cpu)
  8901. {
  8902. /* assert instr[28:23] = 100111
  8903. instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  8904. instr[30,29] = op21 : 0 ==> EXTR, 1,2,3 ==> UNALLOC
  8905. instr[22] = N : must be 0 for 32 bit, 1 for 64 bit or UNALLOC
  8906. instr[21] = op0 : must be 0 or UNALLOC
  8907. instr[20,16] = Rm
  8908. instr[15,10] = imms : 0xxxxx for 32 bit, xxxxxx for 64 bit
  8909. instr[9,5] = Rn
  8910. instr[4,0] = Rd */
  8911. /* 32 bit operations must have N = 0 or else we have an UNALLOC. */
  8912. /* 64 bit operations must have N = 1 or else we have an UNALLOC. */
  8913. uint32_t dispatch;
  8914. uint32_t size = INSTR (31, 31);
  8915. uint32_t N = INSTR (22, 22);
  8916. /* 32 bit operations must have imms[5] = 0
  8917. or else we have an UNALLOC. */
  8918. uint32_t imms = INSTR (15, 10);
  8919. if (size ^ N)
  8920. HALT_UNALLOC;
  8921. if (!size && uimm (imms, 5, 5))
  8922. HALT_UNALLOC;
  8923. /* Switch on combined size and op. */
  8924. dispatch = INSTR (31, 29);
  8925. if (dispatch == 0)
  8926. do_EXTR_32 (cpu);
  8927. else if (dispatch == 4)
  8928. do_EXTR_64 (cpu);
  8929. else if (dispatch == 1)
  8930. HALT_NYI;
  8931. else
  8932. HALT_UNALLOC;
  8933. }
  8934. static void
  8935. dexDPImm (sim_cpu *cpu)
  8936. {
  8937. /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu));
  8938. assert group == GROUP_DPIMM_1000 || grpoup == GROUP_DPIMM_1001
  8939. bits [25,23] of a DPImm are the secondary dispatch vector. */
  8940. uint32_t group2 = dispatchDPImm (aarch64_get_instr (cpu));
  8941. switch (group2)
  8942. {
  8943. case DPIMM_PCADR_000:
  8944. case DPIMM_PCADR_001:
  8945. dexPCRelAddressing (cpu);
  8946. return;
  8947. case DPIMM_ADDSUB_010:
  8948. case DPIMM_ADDSUB_011:
  8949. dexAddSubtractImmediate (cpu);
  8950. return;
  8951. case DPIMM_LOG_100:
  8952. dexLogicalImmediate (cpu);
  8953. return;
  8954. case DPIMM_MOV_101:
  8955. dexMoveWideImmediate (cpu);
  8956. return;
  8957. case DPIMM_BITF_110:
  8958. dexBitfieldImmediate (cpu);
  8959. return;
  8960. case DPIMM_EXTR_111:
  8961. dexExtractImmediate (cpu);
  8962. return;
  8963. default:
  8964. /* Should never reach here. */
  8965. HALT_NYI;
  8966. }
  8967. }
  8968. static void
  8969. dexLoadUnscaledImmediate (sim_cpu *cpu)
  8970. {
  8971. /* instr[29,24] == 111_00
  8972. instr[21] == 0
  8973. instr[11,10] == 00
  8974. instr[31,30] = size
  8975. instr[26] = V
  8976. instr[23,22] = opc
  8977. instr[20,12] = simm9
  8978. instr[9,5] = rn may be SP. */
  8979. /* unsigned rt = INSTR (4, 0); */
  8980. uint32_t V = INSTR (26, 26);
  8981. uint32_t dispatch = ((INSTR (31, 30) << 2) | INSTR (23, 22));
  8982. int32_t imm = simm32 (aarch64_get_instr (cpu), 20, 12);
  8983. if (!V)
  8984. {
  8985. /* GReg operations. */
  8986. switch (dispatch)
  8987. {
  8988. case 0: sturb (cpu, imm); return;
  8989. case 1: ldurb32 (cpu, imm); return;
  8990. case 2: ldursb64 (cpu, imm); return;
  8991. case 3: ldursb32 (cpu, imm); return;
  8992. case 4: sturh (cpu, imm); return;
  8993. case 5: ldurh32 (cpu, imm); return;
  8994. case 6: ldursh64 (cpu, imm); return;
  8995. case 7: ldursh32 (cpu, imm); return;
  8996. case 8: stur32 (cpu, imm); return;
  8997. case 9: ldur32 (cpu, imm); return;
  8998. case 10: ldursw (cpu, imm); return;
  8999. case 12: stur64 (cpu, imm); return;
  9000. case 13: ldur64 (cpu, imm); return;
  9001. case 14:
  9002. /* PRFUM NYI. */
  9003. HALT_NYI;
  9004. default:
  9005. case 11:
  9006. case 15:
  9007. HALT_UNALLOC;
  9008. }
  9009. }
  9010. /* FReg operations. */
  9011. switch (dispatch)
  9012. {
  9013. case 2: fsturq (cpu, imm); return;
  9014. case 3: fldurq (cpu, imm); return;
  9015. case 8: fsturs (cpu, imm); return;
  9016. case 9: fldurs (cpu, imm); return;
  9017. case 12: fsturd (cpu, imm); return;
  9018. case 13: fldurd (cpu, imm); return;
  9019. case 0: /* STUR 8 bit FP. */
  9020. case 1: /* LDUR 8 bit FP. */
  9021. case 4: /* STUR 16 bit FP. */
  9022. case 5: /* LDUR 8 bit FP. */
  9023. HALT_NYI;
  9024. default:
  9025. case 6:
  9026. case 7:
  9027. case 10:
  9028. case 11:
  9029. case 14:
  9030. case 15:
  9031. HALT_UNALLOC;
  9032. }
  9033. }
  9034. /* N.B. A preliminary note regarding all the ldrs<x>32
  9035. instructions
  9036. The signed value loaded by these instructions is cast to unsigned
  9037. before being assigned to aarch64_get_reg_u64 (cpu, N) i.e. to the
  9038. 64 bit element of the GReg union. this performs a 32 bit sign extension
  9039. (as required) but avoids 64 bit sign extension, thus ensuring that the
  9040. top half of the register word is zero. this is what the spec demands
  9041. when a 32 bit load occurs. */
  9042. /* 32 bit load sign-extended byte scaled unsigned 12 bit. */
  9043. static void
  9044. ldrsb32_abs (sim_cpu *cpu, uint32_t offset)
  9045. {
  9046. unsigned int rn = INSTR (9, 5);
  9047. unsigned int rt = INSTR (4, 0);
  9048. /* The target register may not be SP but the source may be
  9049. there is no scaling required for a byte load. */
  9050. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset;
  9051. aarch64_set_reg_u64 (cpu, rt, NO_SP,
  9052. (int64_t) aarch64_get_mem_s8 (cpu, address));
  9053. }
  9054. /* 32 bit load sign-extended byte scaled or unscaled zero-
  9055. or sign-extended 32-bit register offset. */
  9056. static void
  9057. ldrsb32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  9058. {
  9059. unsigned int rm = INSTR (20, 16);
  9060. unsigned int rn = INSTR (9, 5);
  9061. unsigned int rt = INSTR (4, 0);
  9062. /* rn may reference SP, rm and rt must reference ZR. */
  9063. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  9064. int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  9065. extension);
  9066. /* There is no scaling required for a byte load. */
  9067. aarch64_set_reg_u64
  9068. (cpu, rt, NO_SP, (int64_t) aarch64_get_mem_s8 (cpu, address
  9069. + displacement));
  9070. }
  9071. /* 32 bit load sign-extended byte unscaled signed 9 bit with
  9072. pre- or post-writeback. */
  9073. static void
  9074. ldrsb32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9075. {
  9076. uint64_t address;
  9077. unsigned int rn = INSTR (9, 5);
  9078. unsigned int rt = INSTR (4, 0);
  9079. if (rn == rt && wb != NoWriteBack)
  9080. HALT_UNALLOC;
  9081. address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  9082. if (wb == Pre)
  9083. address += offset;
  9084. aarch64_set_reg_u64 (cpu, rt, NO_SP,
  9085. (int64_t) aarch64_get_mem_s8 (cpu, address));
  9086. if (wb == Post)
  9087. address += offset;
  9088. if (wb != NoWriteBack)
  9089. aarch64_set_reg_u64 (cpu, rn, NO_SP, address);
  9090. }
  9091. /* 8 bit store scaled. */
  9092. static void
  9093. fstrb_abs (sim_cpu *cpu, uint32_t offset)
  9094. {
  9095. unsigned st = INSTR (4, 0);
  9096. unsigned rn = INSTR (9, 5);
  9097. aarch64_set_mem_u8 (cpu,
  9098. aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
  9099. aarch64_get_vec_u8 (cpu, st, 0));
  9100. }
  9101. /* 8 bit store scaled or unscaled zero- or
  9102. sign-extended 8-bit register offset. */
  9103. static void
  9104. fstrb_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  9105. {
  9106. unsigned rm = INSTR (20, 16);
  9107. unsigned rn = INSTR (9, 5);
  9108. unsigned st = INSTR (4, 0);
  9109. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  9110. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  9111. extension);
  9112. uint64_t displacement = scaling == Scaled ? extended : 0;
  9113. aarch64_set_mem_u8
  9114. (cpu, address + displacement, aarch64_get_vec_u8 (cpu, st, 0));
  9115. }
  9116. /* 16 bit store scaled. */
  9117. static void
  9118. fstrh_abs (sim_cpu *cpu, uint32_t offset)
  9119. {
  9120. unsigned st = INSTR (4, 0);
  9121. unsigned rn = INSTR (9, 5);
  9122. aarch64_set_mem_u16
  9123. (cpu,
  9124. aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 16),
  9125. aarch64_get_vec_u16 (cpu, st, 0));
  9126. }
  9127. /* 16 bit store scaled or unscaled zero-
  9128. or sign-extended 16-bit register offset. */
  9129. static void
  9130. fstrh_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  9131. {
  9132. unsigned rm = INSTR (20, 16);
  9133. unsigned rn = INSTR (9, 5);
  9134. unsigned st = INSTR (4, 0);
  9135. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  9136. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  9137. extension);
  9138. uint64_t displacement = OPT_SCALE (extended, 16, scaling);
  9139. aarch64_set_mem_u16
  9140. (cpu, address + displacement, aarch64_get_vec_u16 (cpu, st, 0));
  9141. }
  9142. /* 32 bit store scaled unsigned 12 bit. */
  9143. static void
  9144. fstrs_abs (sim_cpu *cpu, uint32_t offset)
  9145. {
  9146. unsigned st = INSTR (4, 0);
  9147. unsigned rn = INSTR (9, 5);
  9148. aarch64_set_mem_u32
  9149. (cpu,
  9150. aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 32),
  9151. aarch64_get_vec_u32 (cpu, st, 0));
  9152. }
  9153. /* 32 bit store unscaled signed 9 bit with pre- or post-writeback. */
  9154. static void
  9155. fstrs_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9156. {
  9157. unsigned rn = INSTR (9, 5);
  9158. unsigned st = INSTR (4, 0);
  9159. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  9160. if (wb != Post)
  9161. address += offset;
  9162. aarch64_set_mem_u32 (cpu, address, aarch64_get_vec_u32 (cpu, st, 0));
  9163. if (wb == Post)
  9164. address += offset;
  9165. if (wb != NoWriteBack)
  9166. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  9167. }
  9168. /* 32 bit store scaled or unscaled zero-
  9169. or sign-extended 32-bit register offset. */
  9170. static void
  9171. fstrs_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  9172. {
  9173. unsigned rm = INSTR (20, 16);
  9174. unsigned rn = INSTR (9, 5);
  9175. unsigned st = INSTR (4, 0);
  9176. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  9177. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  9178. extension);
  9179. uint64_t displacement = OPT_SCALE (extended, 32, scaling);
  9180. aarch64_set_mem_u32
  9181. (cpu, address + displacement, aarch64_get_vec_u32 (cpu, st, 0));
  9182. }
  9183. /* 64 bit store scaled unsigned 12 bit. */
  9184. static void
  9185. fstrd_abs (sim_cpu *cpu, uint32_t offset)
  9186. {
  9187. unsigned st = INSTR (4, 0);
  9188. unsigned rn = INSTR (9, 5);
  9189. aarch64_set_mem_u64
  9190. (cpu,
  9191. aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 64),
  9192. aarch64_get_vec_u64 (cpu, st, 0));
  9193. }
  9194. /* 64 bit store unscaled signed 9 bit with pre- or post-writeback. */
  9195. static void
  9196. fstrd_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9197. {
  9198. unsigned rn = INSTR (9, 5);
  9199. unsigned st = INSTR (4, 0);
  9200. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  9201. if (wb != Post)
  9202. address += offset;
  9203. aarch64_set_mem_u64 (cpu, address, aarch64_get_vec_u64 (cpu, st, 0));
  9204. if (wb == Post)
  9205. address += offset;
  9206. if (wb != NoWriteBack)
  9207. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  9208. }
  9209. /* 64 bit store scaled or unscaled zero-
  9210. or sign-extended 32-bit register offset. */
  9211. static void
  9212. fstrd_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  9213. {
  9214. unsigned rm = INSTR (20, 16);
  9215. unsigned rn = INSTR (9, 5);
  9216. unsigned st = INSTR (4, 0);
  9217. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  9218. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  9219. extension);
  9220. uint64_t displacement = OPT_SCALE (extended, 64, scaling);
  9221. aarch64_set_mem_u64
  9222. (cpu, address + displacement, aarch64_get_vec_u64 (cpu, st, 0));
  9223. }
  9224. /* 128 bit store scaled unsigned 12 bit. */
  9225. static void
  9226. fstrq_abs (sim_cpu *cpu, uint32_t offset)
  9227. {
  9228. FRegister a;
  9229. unsigned st = INSTR (4, 0);
  9230. unsigned rn = INSTR (9, 5);
  9231. uint64_t addr;
  9232. aarch64_get_FP_long_double (cpu, st, & a);
  9233. addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 128);
  9234. aarch64_set_mem_long_double (cpu, addr, a);
  9235. }
  9236. /* 128 bit store unscaled signed 9 bit with pre- or post-writeback. */
  9237. static void
  9238. fstrq_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9239. {
  9240. FRegister a;
  9241. unsigned rn = INSTR (9, 5);
  9242. unsigned st = INSTR (4, 0);
  9243. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  9244. if (wb != Post)
  9245. address += offset;
  9246. aarch64_get_FP_long_double (cpu, st, & a);
  9247. aarch64_set_mem_long_double (cpu, address, a);
  9248. if (wb == Post)
  9249. address += offset;
  9250. if (wb != NoWriteBack)
  9251. aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
  9252. }
  9253. /* 128 bit store scaled or unscaled zero-
  9254. or sign-extended 32-bit register offset. */
  9255. static void
  9256. fstrq_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
  9257. {
  9258. unsigned rm = INSTR (20, 16);
  9259. unsigned rn = INSTR (9, 5);
  9260. unsigned st = INSTR (4, 0);
  9261. uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
  9262. int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
  9263. extension);
  9264. uint64_t displacement = OPT_SCALE (extended, 128, scaling);
  9265. FRegister a;
  9266. aarch64_get_FP_long_double (cpu, st, & a);
  9267. aarch64_set_mem_long_double (cpu, address + displacement, a);
  9268. }
  9269. static void
  9270. dexLoadImmediatePrePost (sim_cpu *cpu)
  9271. {
  9272. /* instr[31,30] = size
  9273. instr[29,27] = 111
  9274. instr[26] = V
  9275. instr[25,24] = 00
  9276. instr[23,22] = opc
  9277. instr[21] = 0
  9278. instr[20,12] = simm9
  9279. instr[11] = wb : 0 ==> Post, 1 ==> Pre
  9280. instr[10] = 0
  9281. instr[9,5] = Rn may be SP.
  9282. instr[4,0] = Rt */
  9283. uint32_t V = INSTR (26, 26);
  9284. uint32_t dispatch = ((INSTR (31, 30) << 2) | INSTR (23, 22));
  9285. int32_t imm = simm32 (aarch64_get_instr (cpu), 20, 12);
  9286. WriteBack wb = INSTR (11, 11);
  9287. if (!V)
  9288. {
  9289. /* GReg operations. */
  9290. switch (dispatch)
  9291. {
  9292. case 0: strb_wb (cpu, imm, wb); return;
  9293. case 1: ldrb32_wb (cpu, imm, wb); return;
  9294. case 2: ldrsb_wb (cpu, imm, wb); return;
  9295. case 3: ldrsb32_wb (cpu, imm, wb); return;
  9296. case 4: strh_wb (cpu, imm, wb); return;
  9297. case 5: ldrh32_wb (cpu, imm, wb); return;
  9298. case 6: ldrsh64_wb (cpu, imm, wb); return;
  9299. case 7: ldrsh32_wb (cpu, imm, wb); return;
  9300. case 8: str32_wb (cpu, imm, wb); return;
  9301. case 9: ldr32_wb (cpu, imm, wb); return;
  9302. case 10: ldrsw_wb (cpu, imm, wb); return;
  9303. case 12: str_wb (cpu, imm, wb); return;
  9304. case 13: ldr_wb (cpu, imm, wb); return;
  9305. default:
  9306. case 11:
  9307. case 14:
  9308. case 15:
  9309. HALT_UNALLOC;
  9310. }
  9311. }
  9312. /* FReg operations. */
  9313. switch (dispatch)
  9314. {
  9315. case 2: fstrq_wb (cpu, imm, wb); return;
  9316. case 3: fldrq_wb (cpu, imm, wb); return;
  9317. case 8: fstrs_wb (cpu, imm, wb); return;
  9318. case 9: fldrs_wb (cpu, imm, wb); return;
  9319. case 12: fstrd_wb (cpu, imm, wb); return;
  9320. case 13: fldrd_wb (cpu, imm, wb); return;
  9321. case 0: /* STUR 8 bit FP. */
  9322. case 1: /* LDUR 8 bit FP. */
  9323. case 4: /* STUR 16 bit FP. */
  9324. case 5: /* LDUR 8 bit FP. */
  9325. HALT_NYI;
  9326. default:
  9327. case 6:
  9328. case 7:
  9329. case 10:
  9330. case 11:
  9331. case 14:
  9332. case 15:
  9333. HALT_UNALLOC;
  9334. }
  9335. }
  9336. static void
  9337. dexLoadRegisterOffset (sim_cpu *cpu)
  9338. {
  9339. /* instr[31,30] = size
  9340. instr[29,27] = 111
  9341. instr[26] = V
  9342. instr[25,24] = 00
  9343. instr[23,22] = opc
  9344. instr[21] = 1
  9345. instr[20,16] = rm
  9346. instr[15,13] = option : 010 ==> UXTW, 011 ==> UXTX/LSL,
  9347. 110 ==> SXTW, 111 ==> SXTX,
  9348. ow ==> RESERVED
  9349. instr[12] = scaled
  9350. instr[11,10] = 10
  9351. instr[9,5] = rn
  9352. instr[4,0] = rt. */
  9353. uint32_t V = INSTR (26, 26);
  9354. uint32_t dispatch = ((INSTR (31, 30) << 2) | INSTR (23, 22));
  9355. Scaling scale = INSTR (12, 12);
  9356. Extension extensionType = INSTR (15, 13);
  9357. /* Check for illegal extension types. */
  9358. if (uimm (extensionType, 1, 1) == 0)
  9359. HALT_UNALLOC;
  9360. if (extensionType == UXTX || extensionType == SXTX)
  9361. extensionType = NoExtension;
  9362. if (!V)
  9363. {
  9364. /* GReg operations. */
  9365. switch (dispatch)
  9366. {
  9367. case 0: strb_scale_ext (cpu, scale, extensionType); return;
  9368. case 1: ldrb32_scale_ext (cpu, scale, extensionType); return;
  9369. case 2: ldrsb_scale_ext (cpu, scale, extensionType); return;
  9370. case 3: ldrsb32_scale_ext (cpu, scale, extensionType); return;
  9371. case 4: strh_scale_ext (cpu, scale, extensionType); return;
  9372. case 5: ldrh32_scale_ext (cpu, scale, extensionType); return;
  9373. case 6: ldrsh_scale_ext (cpu, scale, extensionType); return;
  9374. case 7: ldrsh32_scale_ext (cpu, scale, extensionType); return;
  9375. case 8: str32_scale_ext (cpu, scale, extensionType); return;
  9376. case 9: ldr32_scale_ext (cpu, scale, extensionType); return;
  9377. case 10: ldrsw_scale_ext (cpu, scale, extensionType); return;
  9378. case 12: str_scale_ext (cpu, scale, extensionType); return;
  9379. case 13: ldr_scale_ext (cpu, scale, extensionType); return;
  9380. case 14: prfm_scale_ext (cpu, scale, extensionType); return;
  9381. default:
  9382. case 11:
  9383. case 15:
  9384. HALT_UNALLOC;
  9385. }
  9386. }
  9387. /* FReg operations. */
  9388. switch (dispatch)
  9389. {
  9390. case 1: /* LDUR 8 bit FP. */
  9391. HALT_NYI;
  9392. case 3: fldrq_scale_ext (cpu, scale, extensionType); return;
  9393. case 5: /* LDUR 8 bit FP. */
  9394. HALT_NYI;
  9395. case 9: fldrs_scale_ext (cpu, scale, extensionType); return;
  9396. case 13: fldrd_scale_ext (cpu, scale, extensionType); return;
  9397. case 0: fstrb_scale_ext (cpu, scale, extensionType); return;
  9398. case 2: fstrq_scale_ext (cpu, scale, extensionType); return;
  9399. case 4: fstrh_scale_ext (cpu, scale, extensionType); return;
  9400. case 8: fstrs_scale_ext (cpu, scale, extensionType); return;
  9401. case 12: fstrd_scale_ext (cpu, scale, extensionType); return;
  9402. default:
  9403. case 6:
  9404. case 7:
  9405. case 10:
  9406. case 11:
  9407. case 14:
  9408. case 15:
  9409. HALT_UNALLOC;
  9410. }
  9411. }
  9412. static void
  9413. dexLoadUnsignedImmediate (sim_cpu *cpu)
  9414. {
  9415. /* instr[29,24] == 111_01
  9416. instr[31,30] = size
  9417. instr[26] = V
  9418. instr[23,22] = opc
  9419. instr[21,10] = uimm12 : unsigned immediate offset
  9420. instr[9,5] = rn may be SP.
  9421. instr[4,0] = rt. */
  9422. uint32_t V = INSTR (26,26);
  9423. uint32_t dispatch = ((INSTR (31, 30) << 2) | INSTR (23, 22));
  9424. uint32_t imm = INSTR (21, 10);
  9425. if (!V)
  9426. {
  9427. /* GReg operations. */
  9428. switch (dispatch)
  9429. {
  9430. case 0: strb_abs (cpu, imm); return;
  9431. case 1: ldrb32_abs (cpu, imm); return;
  9432. case 2: ldrsb_abs (cpu, imm); return;
  9433. case 3: ldrsb32_abs (cpu, imm); return;
  9434. case 4: strh_abs (cpu, imm); return;
  9435. case 5: ldrh32_abs (cpu, imm); return;
  9436. case 6: ldrsh_abs (cpu, imm); return;
  9437. case 7: ldrsh32_abs (cpu, imm); return;
  9438. case 8: str32_abs (cpu, imm); return;
  9439. case 9: ldr32_abs (cpu, imm); return;
  9440. case 10: ldrsw_abs (cpu, imm); return;
  9441. case 12: str_abs (cpu, imm); return;
  9442. case 13: ldr_abs (cpu, imm); return;
  9443. case 14: prfm_abs (cpu, imm); return;
  9444. default:
  9445. case 11:
  9446. case 15:
  9447. HALT_UNALLOC;
  9448. }
  9449. }
  9450. /* FReg operations. */
  9451. switch (dispatch)
  9452. {
  9453. case 0: fstrb_abs (cpu, imm); return;
  9454. case 4: fstrh_abs (cpu, imm); return;
  9455. case 8: fstrs_abs (cpu, imm); return;
  9456. case 12: fstrd_abs (cpu, imm); return;
  9457. case 2: fstrq_abs (cpu, imm); return;
  9458. case 1: fldrb_abs (cpu, imm); return;
  9459. case 5: fldrh_abs (cpu, imm); return;
  9460. case 9: fldrs_abs (cpu, imm); return;
  9461. case 13: fldrd_abs (cpu, imm); return;
  9462. case 3: fldrq_abs (cpu, imm); return;
  9463. default:
  9464. case 6:
  9465. case 7:
  9466. case 10:
  9467. case 11:
  9468. case 14:
  9469. case 15:
  9470. HALT_UNALLOC;
  9471. }
  9472. }
  9473. static void
  9474. dexLoadExclusive (sim_cpu *cpu)
  9475. {
  9476. /* assert instr[29:24] = 001000;
  9477. instr[31,30] = size
  9478. instr[23] = 0 if exclusive
  9479. instr[22] = L : 1 if load, 0 if store
  9480. instr[21] = 1 if pair
  9481. instr[20,16] = Rs
  9482. instr[15] = o0 : 1 if ordered
  9483. instr[14,10] = Rt2
  9484. instr[9,5] = Rn
  9485. instr[4.0] = Rt. */
  9486. switch (INSTR (22, 21))
  9487. {
  9488. case 2: ldxr (cpu); return;
  9489. case 0: stxr (cpu); return;
  9490. default: HALT_NYI;
  9491. }
  9492. }
  9493. static void
  9494. dexLoadOther (sim_cpu *cpu)
  9495. {
  9496. uint32_t dispatch;
  9497. /* instr[29,25] = 111_0
  9498. instr[24] == 0 ==> dispatch, 1 ==> ldst reg unsigned immediate
  9499. instr[21:11,10] is the secondary dispatch. */
  9500. if (INSTR (24, 24))
  9501. {
  9502. dexLoadUnsignedImmediate (cpu);
  9503. return;
  9504. }
  9505. dispatch = ((INSTR (21, 21) << 2) | INSTR (11, 10));
  9506. switch (dispatch)
  9507. {
  9508. case 0: dexLoadUnscaledImmediate (cpu); return;
  9509. case 1: dexLoadImmediatePrePost (cpu); return;
  9510. case 3: dexLoadImmediatePrePost (cpu); return;
  9511. case 6: dexLoadRegisterOffset (cpu); return;
  9512. default:
  9513. case 2:
  9514. case 4:
  9515. case 5:
  9516. case 7:
  9517. HALT_NYI;
  9518. }
  9519. }
  9520. static void
  9521. store_pair_u32 (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9522. {
  9523. unsigned rn = INSTR (14, 10);
  9524. unsigned rd = INSTR (9, 5);
  9525. unsigned rm = INSTR (4, 0);
  9526. uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
  9527. if ((rn == rd || rm == rd) && wb != NoWriteBack)
  9528. HALT_UNALLOC; /* ??? */
  9529. offset <<= 2;
  9530. if (wb != Post)
  9531. address += offset;
  9532. aarch64_set_mem_u32 (cpu, address,
  9533. aarch64_get_reg_u32 (cpu, rm, NO_SP));
  9534. aarch64_set_mem_u32 (cpu, address + 4,
  9535. aarch64_get_reg_u32 (cpu, rn, NO_SP));
  9536. if (wb == Post)
  9537. address += offset;
  9538. if (wb != NoWriteBack)
  9539. aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
  9540. }
  9541. static void
  9542. store_pair_u64 (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9543. {
  9544. unsigned rn = INSTR (14, 10);
  9545. unsigned rd = INSTR (9, 5);
  9546. unsigned rm = INSTR (4, 0);
  9547. uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
  9548. if ((rn == rd || rm == rd) && wb != NoWriteBack)
  9549. HALT_UNALLOC; /* ??? */
  9550. offset <<= 3;
  9551. if (wb != Post)
  9552. address += offset;
  9553. aarch64_set_mem_u64 (cpu, address,
  9554. aarch64_get_reg_u64 (cpu, rm, NO_SP));
  9555. aarch64_set_mem_u64 (cpu, address + 8,
  9556. aarch64_get_reg_u64 (cpu, rn, NO_SP));
  9557. if (wb == Post)
  9558. address += offset;
  9559. if (wb != NoWriteBack)
  9560. aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
  9561. }
  9562. static void
  9563. load_pair_u32 (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9564. {
  9565. unsigned rn = INSTR (14, 10);
  9566. unsigned rd = INSTR (9, 5);
  9567. unsigned rm = INSTR (4, 0);
  9568. uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
  9569. /* Treat this as unalloc to make sure we don't do it. */
  9570. if (rn == rm)
  9571. HALT_UNALLOC;
  9572. offset <<= 2;
  9573. if (wb != Post)
  9574. address += offset;
  9575. aarch64_set_reg_u64 (cpu, rm, SP_OK, aarch64_get_mem_u32 (cpu, address));
  9576. aarch64_set_reg_u64 (cpu, rn, SP_OK, aarch64_get_mem_u32 (cpu, address + 4));
  9577. if (wb == Post)
  9578. address += offset;
  9579. if (wb != NoWriteBack)
  9580. aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
  9581. }
  9582. static void
  9583. load_pair_s32 (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9584. {
  9585. unsigned rn = INSTR (14, 10);
  9586. unsigned rd = INSTR (9, 5);
  9587. unsigned rm = INSTR (4, 0);
  9588. uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
  9589. /* Treat this as unalloc to make sure we don't do it. */
  9590. if (rn == rm)
  9591. HALT_UNALLOC;
  9592. offset <<= 2;
  9593. if (wb != Post)
  9594. address += offset;
  9595. aarch64_set_reg_s64 (cpu, rm, SP_OK, aarch64_get_mem_s32 (cpu, address));
  9596. aarch64_set_reg_s64 (cpu, rn, SP_OK, aarch64_get_mem_s32 (cpu, address + 4));
  9597. if (wb == Post)
  9598. address += offset;
  9599. if (wb != NoWriteBack)
  9600. aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
  9601. }
  9602. static void
  9603. load_pair_u64 (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9604. {
  9605. unsigned rn = INSTR (14, 10);
  9606. unsigned rd = INSTR (9, 5);
  9607. unsigned rm = INSTR (4, 0);
  9608. uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
  9609. /* Treat this as unalloc to make sure we don't do it. */
  9610. if (rn == rm)
  9611. HALT_UNALLOC;
  9612. offset <<= 3;
  9613. if (wb != Post)
  9614. address += offset;
  9615. aarch64_set_reg_u64 (cpu, rm, SP_OK, aarch64_get_mem_u64 (cpu, address));
  9616. aarch64_set_reg_u64 (cpu, rn, SP_OK, aarch64_get_mem_u64 (cpu, address + 8));
  9617. if (wb == Post)
  9618. address += offset;
  9619. if (wb != NoWriteBack)
  9620. aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
  9621. }
  9622. static void
  9623. dex_load_store_pair_gr (sim_cpu *cpu)
  9624. {
  9625. /* instr[31,30] = size (10=> 64-bit, 01=> signed 32-bit, 00=> 32-bit)
  9626. instr[29,25] = instruction encoding: 101_0
  9627. instr[26] = V : 1 if fp 0 if gp
  9628. instr[24,23] = addressing mode (10=> offset, 01=> post, 11=> pre)
  9629. instr[22] = load/store (1=> load)
  9630. instr[21,15] = signed, scaled, offset
  9631. instr[14,10] = Rn
  9632. instr[ 9, 5] = Rd
  9633. instr[ 4, 0] = Rm. */
  9634. uint32_t dispatch = ((INSTR (31, 30) << 3) | INSTR (24, 22));
  9635. int32_t offset = simm32 (aarch64_get_instr (cpu), 21, 15);
  9636. switch (dispatch)
  9637. {
  9638. case 2: store_pair_u32 (cpu, offset, Post); return;
  9639. case 3: load_pair_u32 (cpu, offset, Post); return;
  9640. case 4: store_pair_u32 (cpu, offset, NoWriteBack); return;
  9641. case 5: load_pair_u32 (cpu, offset, NoWriteBack); return;
  9642. case 6: store_pair_u32 (cpu, offset, Pre); return;
  9643. case 7: load_pair_u32 (cpu, offset, Pre); return;
  9644. case 11: load_pair_s32 (cpu, offset, Post); return;
  9645. case 13: load_pair_s32 (cpu, offset, NoWriteBack); return;
  9646. case 15: load_pair_s32 (cpu, offset, Pre); return;
  9647. case 18: store_pair_u64 (cpu, offset, Post); return;
  9648. case 19: load_pair_u64 (cpu, offset, Post); return;
  9649. case 20: store_pair_u64 (cpu, offset, NoWriteBack); return;
  9650. case 21: load_pair_u64 (cpu, offset, NoWriteBack); return;
  9651. case 22: store_pair_u64 (cpu, offset, Pre); return;
  9652. case 23: load_pair_u64 (cpu, offset, Pre); return;
  9653. default:
  9654. HALT_UNALLOC;
  9655. }
  9656. }
  9657. static void
  9658. store_pair_float (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9659. {
  9660. unsigned rn = INSTR (14, 10);
  9661. unsigned rd = INSTR (9, 5);
  9662. unsigned rm = INSTR (4, 0);
  9663. uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
  9664. offset <<= 2;
  9665. if (wb != Post)
  9666. address += offset;
  9667. aarch64_set_mem_u32 (cpu, address, aarch64_get_vec_u32 (cpu, rm, 0));
  9668. aarch64_set_mem_u32 (cpu, address + 4, aarch64_get_vec_u32 (cpu, rn, 0));
  9669. if (wb == Post)
  9670. address += offset;
  9671. if (wb != NoWriteBack)
  9672. aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
  9673. }
  9674. static void
  9675. store_pair_double (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9676. {
  9677. unsigned rn = INSTR (14, 10);
  9678. unsigned rd = INSTR (9, 5);
  9679. unsigned rm = INSTR (4, 0);
  9680. uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
  9681. offset <<= 3;
  9682. if (wb != Post)
  9683. address += offset;
  9684. aarch64_set_mem_u64 (cpu, address, aarch64_get_vec_u64 (cpu, rm, 0));
  9685. aarch64_set_mem_u64 (cpu, address + 8, aarch64_get_vec_u64 (cpu, rn, 0));
  9686. if (wb == Post)
  9687. address += offset;
  9688. if (wb != NoWriteBack)
  9689. aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
  9690. }
  9691. static void
  9692. store_pair_long_double (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9693. {
  9694. FRegister a;
  9695. unsigned rn = INSTR (14, 10);
  9696. unsigned rd = INSTR (9, 5);
  9697. unsigned rm = INSTR (4, 0);
  9698. uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
  9699. offset <<= 4;
  9700. if (wb != Post)
  9701. address += offset;
  9702. aarch64_get_FP_long_double (cpu, rm, & a);
  9703. aarch64_set_mem_long_double (cpu, address, a);
  9704. aarch64_get_FP_long_double (cpu, rn, & a);
  9705. aarch64_set_mem_long_double (cpu, address + 16, a);
  9706. if (wb == Post)
  9707. address += offset;
  9708. if (wb != NoWriteBack)
  9709. aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
  9710. }
  9711. static void
  9712. load_pair_float (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9713. {
  9714. unsigned rn = INSTR (14, 10);
  9715. unsigned rd = INSTR (9, 5);
  9716. unsigned rm = INSTR (4, 0);
  9717. uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
  9718. if (rm == rn)
  9719. HALT_UNALLOC;
  9720. offset <<= 2;
  9721. if (wb != Post)
  9722. address += offset;
  9723. aarch64_set_vec_u32 (cpu, rm, 0, aarch64_get_mem_u32 (cpu, address));
  9724. aarch64_set_vec_u32 (cpu, rn, 0, aarch64_get_mem_u32 (cpu, address + 4));
  9725. if (wb == Post)
  9726. address += offset;
  9727. if (wb != NoWriteBack)
  9728. aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
  9729. }
  9730. static void
  9731. load_pair_double (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9732. {
  9733. unsigned rn = INSTR (14, 10);
  9734. unsigned rd = INSTR (9, 5);
  9735. unsigned rm = INSTR (4, 0);
  9736. uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
  9737. if (rm == rn)
  9738. HALT_UNALLOC;
  9739. offset <<= 3;
  9740. if (wb != Post)
  9741. address += offset;
  9742. aarch64_set_vec_u64 (cpu, rm, 0, aarch64_get_mem_u64 (cpu, address));
  9743. aarch64_set_vec_u64 (cpu, rn, 0, aarch64_get_mem_u64 (cpu, address + 8));
  9744. if (wb == Post)
  9745. address += offset;
  9746. if (wb != NoWriteBack)
  9747. aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
  9748. }
  9749. static void
  9750. load_pair_long_double (sim_cpu *cpu, int32_t offset, WriteBack wb)
  9751. {
  9752. FRegister a;
  9753. unsigned rn = INSTR (14, 10);
  9754. unsigned rd = INSTR (9, 5);
  9755. unsigned rm = INSTR (4, 0);
  9756. uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
  9757. if (rm == rn)
  9758. HALT_UNALLOC;
  9759. offset <<= 4;
  9760. if (wb != Post)
  9761. address += offset;
  9762. aarch64_get_mem_long_double (cpu, address, & a);
  9763. aarch64_set_FP_long_double (cpu, rm, a);
  9764. aarch64_get_mem_long_double (cpu, address + 16, & a);
  9765. aarch64_set_FP_long_double (cpu, rn, a);
  9766. if (wb == Post)
  9767. address += offset;
  9768. if (wb != NoWriteBack)
  9769. aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
  9770. }
  9771. static void
  9772. dex_load_store_pair_fp (sim_cpu *cpu)
  9773. {
  9774. /* instr[31,30] = size (10=> 128-bit, 01=> 64-bit, 00=> 32-bit)
  9775. instr[29,25] = instruction encoding
  9776. instr[24,23] = addressing mode (10=> offset, 01=> post, 11=> pre)
  9777. instr[22] = load/store (1=> load)
  9778. instr[21,15] = signed, scaled, offset
  9779. instr[14,10] = Rn
  9780. instr[ 9, 5] = Rd
  9781. instr[ 4, 0] = Rm */
  9782. uint32_t dispatch = ((INSTR (31, 30) << 3) | INSTR (24, 22));
  9783. int32_t offset = simm32 (aarch64_get_instr (cpu), 21, 15);
  9784. switch (dispatch)
  9785. {
  9786. case 2: store_pair_float (cpu, offset, Post); return;
  9787. case 3: load_pair_float (cpu, offset, Post); return;
  9788. case 4: store_pair_float (cpu, offset, NoWriteBack); return;
  9789. case 5: load_pair_float (cpu, offset, NoWriteBack); return;
  9790. case 6: store_pair_float (cpu, offset, Pre); return;
  9791. case 7: load_pair_float (cpu, offset, Pre); return;
  9792. case 10: store_pair_double (cpu, offset, Post); return;
  9793. case 11: load_pair_double (cpu, offset, Post); return;
  9794. case 12: store_pair_double (cpu, offset, NoWriteBack); return;
  9795. case 13: load_pair_double (cpu, offset, NoWriteBack); return;
  9796. case 14: store_pair_double (cpu, offset, Pre); return;
  9797. case 15: load_pair_double (cpu, offset, Pre); return;
  9798. case 18: store_pair_long_double (cpu, offset, Post); return;
  9799. case 19: load_pair_long_double (cpu, offset, Post); return;
  9800. case 20: store_pair_long_double (cpu, offset, NoWriteBack); return;
  9801. case 21: load_pair_long_double (cpu, offset, NoWriteBack); return;
  9802. case 22: store_pair_long_double (cpu, offset, Pre); return;
  9803. case 23: load_pair_long_double (cpu, offset, Pre); return;
  9804. default:
  9805. HALT_UNALLOC;
  9806. }
  9807. }
  9808. static inline unsigned
  9809. vec_reg (unsigned v, unsigned o)
  9810. {
  9811. return (v + o) & 0x3F;
  9812. }
  9813. /* Load multiple N-element structures to M consecutive registers. */
  9814. static void
  9815. vec_load (sim_cpu *cpu, uint64_t address, unsigned N, unsigned M)
  9816. {
  9817. int all = INSTR (30, 30);
  9818. unsigned size = INSTR (11, 10);
  9819. unsigned vd = INSTR (4, 0);
  9820. unsigned rpt = (N == M) ? 1 : M;
  9821. unsigned selem = N;
  9822. unsigned i, j, k;
  9823. switch (size)
  9824. {
  9825. case 0: /* 8-bit operations. */
  9826. for (i = 0; i < rpt; i++)
  9827. for (j = 0; j < (8 + (8 * all)); j++)
  9828. for (k = 0; k < selem; k++)
  9829. {
  9830. aarch64_set_vec_u8 (cpu, vec_reg (vd, i + k), j,
  9831. aarch64_get_mem_u8 (cpu, address));
  9832. address += 1;
  9833. }
  9834. return;
  9835. case 1: /* 16-bit operations. */
  9836. for (i = 0; i < rpt; i++)
  9837. for (j = 0; j < (4 + (4 * all)); j++)
  9838. for (k = 0; k < selem; k++)
  9839. {
  9840. aarch64_set_vec_u16 (cpu, vec_reg (vd, i + k), j,
  9841. aarch64_get_mem_u16 (cpu, address));
  9842. address += 2;
  9843. }
  9844. return;
  9845. case 2: /* 32-bit operations. */
  9846. for (i = 0; i < rpt; i++)
  9847. for (j = 0; j < (2 + (2 * all)); j++)
  9848. for (k = 0; k < selem; k++)
  9849. {
  9850. aarch64_set_vec_u32 (cpu, vec_reg (vd, i + k), j,
  9851. aarch64_get_mem_u32 (cpu, address));
  9852. address += 4;
  9853. }
  9854. return;
  9855. case 3: /* 64-bit operations. */
  9856. for (i = 0; i < rpt; i++)
  9857. for (j = 0; j < (1 + all); j++)
  9858. for (k = 0; k < selem; k++)
  9859. {
  9860. aarch64_set_vec_u64 (cpu, vec_reg (vd, i + k), j,
  9861. aarch64_get_mem_u64 (cpu, address));
  9862. address += 8;
  9863. }
  9864. return;
  9865. }
  9866. }
  9867. /* Load multiple 4-element structures into four consecutive registers. */
  9868. static void
  9869. LD4 (sim_cpu *cpu, uint64_t address)
  9870. {
  9871. vec_load (cpu, address, 4, 4);
  9872. }
  9873. /* Load multiple 3-element structures into three consecutive registers. */
  9874. static void
  9875. LD3 (sim_cpu *cpu, uint64_t address)
  9876. {
  9877. vec_load (cpu, address, 3, 3);
  9878. }
  9879. /* Load multiple 2-element structures into two consecutive registers. */
  9880. static void
  9881. LD2 (sim_cpu *cpu, uint64_t address)
  9882. {
  9883. vec_load (cpu, address, 2, 2);
  9884. }
  9885. /* Load multiple 1-element structures into one register. */
  9886. static void
  9887. LD1_1 (sim_cpu *cpu, uint64_t address)
  9888. {
  9889. vec_load (cpu, address, 1, 1);
  9890. }
  9891. /* Load multiple 1-element structures into two registers. */
  9892. static void
  9893. LD1_2 (sim_cpu *cpu, uint64_t address)
  9894. {
  9895. vec_load (cpu, address, 1, 2);
  9896. }
  9897. /* Load multiple 1-element structures into three registers. */
  9898. static void
  9899. LD1_3 (sim_cpu *cpu, uint64_t address)
  9900. {
  9901. vec_load (cpu, address, 1, 3);
  9902. }
  9903. /* Load multiple 1-element structures into four registers. */
  9904. static void
  9905. LD1_4 (sim_cpu *cpu, uint64_t address)
  9906. {
  9907. vec_load (cpu, address, 1, 4);
  9908. }
  9909. /* Store multiple N-element structures from M consecutive registers. */
  9910. static void
  9911. vec_store (sim_cpu *cpu, uint64_t address, unsigned N, unsigned M)
  9912. {
  9913. int all = INSTR (30, 30);
  9914. unsigned size = INSTR (11, 10);
  9915. unsigned vd = INSTR (4, 0);
  9916. unsigned rpt = (N == M) ? 1 : M;
  9917. unsigned selem = N;
  9918. unsigned i, j, k;
  9919. switch (size)
  9920. {
  9921. case 0: /* 8-bit operations. */
  9922. for (i = 0; i < rpt; i++)
  9923. for (j = 0; j < (8 + (8 * all)); j++)
  9924. for (k = 0; k < selem; k++)
  9925. {
  9926. aarch64_set_mem_u8
  9927. (cpu, address,
  9928. aarch64_get_vec_u8 (cpu, vec_reg (vd, i + k), j));
  9929. address += 1;
  9930. }
  9931. return;
  9932. case 1: /* 16-bit operations. */
  9933. for (i = 0; i < rpt; i++)
  9934. for (j = 0; j < (4 + (4 * all)); j++)
  9935. for (k = 0; k < selem; k++)
  9936. {
  9937. aarch64_set_mem_u16
  9938. (cpu, address,
  9939. aarch64_get_vec_u16 (cpu, vec_reg (vd, i + k), j));
  9940. address += 2;
  9941. }
  9942. return;
  9943. case 2: /* 32-bit operations. */
  9944. for (i = 0; i < rpt; i++)
  9945. for (j = 0; j < (2 + (2 * all)); j++)
  9946. for (k = 0; k < selem; k++)
  9947. {
  9948. aarch64_set_mem_u32
  9949. (cpu, address,
  9950. aarch64_get_vec_u32 (cpu, vec_reg (vd, i + k), j));
  9951. address += 4;
  9952. }
  9953. return;
  9954. case 3: /* 64-bit operations. */
  9955. for (i = 0; i < rpt; i++)
  9956. for (j = 0; j < (1 + all); j++)
  9957. for (k = 0; k < selem; k++)
  9958. {
  9959. aarch64_set_mem_u64
  9960. (cpu, address,
  9961. aarch64_get_vec_u64 (cpu, vec_reg (vd, i + k), j));
  9962. address += 8;
  9963. }
  9964. return;
  9965. }
  9966. }
  9967. /* Store multiple 4-element structure from four consecutive registers. */
  9968. static void
  9969. ST4 (sim_cpu *cpu, uint64_t address)
  9970. {
  9971. vec_store (cpu, address, 4, 4);
  9972. }
  9973. /* Store multiple 3-element structures from three consecutive registers. */
  9974. static void
  9975. ST3 (sim_cpu *cpu, uint64_t address)
  9976. {
  9977. vec_store (cpu, address, 3, 3);
  9978. }
  9979. /* Store multiple 2-element structures from two consecutive registers. */
  9980. static void
  9981. ST2 (sim_cpu *cpu, uint64_t address)
  9982. {
  9983. vec_store (cpu, address, 2, 2);
  9984. }
  9985. /* Store multiple 1-element structures from one register. */
  9986. static void
  9987. ST1_1 (sim_cpu *cpu, uint64_t address)
  9988. {
  9989. vec_store (cpu, address, 1, 1);
  9990. }
  9991. /* Store multiple 1-element structures from two registers. */
  9992. static void
  9993. ST1_2 (sim_cpu *cpu, uint64_t address)
  9994. {
  9995. vec_store (cpu, address, 1, 2);
  9996. }
  9997. /* Store multiple 1-element structures from three registers. */
  9998. static void
  9999. ST1_3 (sim_cpu *cpu, uint64_t address)
  10000. {
  10001. vec_store (cpu, address, 1, 3);
  10002. }
  10003. /* Store multiple 1-element structures from four registers. */
  10004. static void
  10005. ST1_4 (sim_cpu *cpu, uint64_t address)
  10006. {
  10007. vec_store (cpu, address, 1, 4);
  10008. }
  10009. #define LDn_STn_SINGLE_LANE_AND_SIZE() \
  10010. do \
  10011. { \
  10012. switch (INSTR (15, 14)) \
  10013. { \
  10014. case 0: \
  10015. lane = (full << 3) | (s << 2) | size; \
  10016. size = 0; \
  10017. break; \
  10018. \
  10019. case 1: \
  10020. if ((size & 1) == 1) \
  10021. HALT_UNALLOC; \
  10022. lane = (full << 2) | (s << 1) | (size >> 1); \
  10023. size = 1; \
  10024. break; \
  10025. \
  10026. case 2: \
  10027. if ((size & 2) == 2) \
  10028. HALT_UNALLOC; \
  10029. \
  10030. if ((size & 1) == 0) \
  10031. { \
  10032. lane = (full << 1) | s; \
  10033. size = 2; \
  10034. } \
  10035. else \
  10036. { \
  10037. if (s) \
  10038. HALT_UNALLOC; \
  10039. lane = full; \
  10040. size = 3; \
  10041. } \
  10042. break; \
  10043. \
  10044. default: \
  10045. HALT_UNALLOC; \
  10046. } \
  10047. } \
  10048. while (0)
  10049. /* Load single structure into one lane of N registers. */
  10050. static void
  10051. do_vec_LDn_single (sim_cpu *cpu, uint64_t address)
  10052. {
  10053. /* instr[31] = 0
  10054. instr[30] = element selector 0=>half, 1=>all elements
  10055. instr[29,24] = 00 1101
  10056. instr[23] = 0=>simple, 1=>post
  10057. instr[22] = 1
  10058. instr[21] = width: LD1-or-LD3 (0) / LD2-or-LD4 (1)
  10059. instr[20,16] = 0 0000 (simple), Vinc (reg-post-inc, no SP),
  10060. 11111 (immediate post inc)
  10061. instr[15,13] = opcode
  10062. instr[12] = S, used for lane number
  10063. instr[11,10] = size, also used for lane number
  10064. instr[9,5] = address
  10065. instr[4,0] = Vd */
  10066. unsigned full = INSTR (30, 30);
  10067. unsigned vd = INSTR (4, 0);
  10068. unsigned size = INSTR (11, 10);
  10069. unsigned s = INSTR (12, 12);
  10070. int nregs = ((INSTR (13, 13) << 1) | INSTR (21, 21)) + 1;
  10071. int lane = 0;
  10072. int i;
  10073. NYI_assert (29, 24, 0x0D);
  10074. NYI_assert (22, 22, 1);
  10075. /* Compute the lane number first (using size), and then compute size. */
  10076. LDn_STn_SINGLE_LANE_AND_SIZE ();
  10077. for (i = 0; i < nregs; i++)
  10078. switch (size)
  10079. {
  10080. case 0:
  10081. {
  10082. uint8_t val = aarch64_get_mem_u8 (cpu, address + i);
  10083. aarch64_set_vec_u8 (cpu, vd + i, lane, val);
  10084. break;
  10085. }
  10086. case 1:
  10087. {
  10088. uint16_t val = aarch64_get_mem_u16 (cpu, address + (i * 2));
  10089. aarch64_set_vec_u16 (cpu, vd + i, lane, val);
  10090. break;
  10091. }
  10092. case 2:
  10093. {
  10094. uint32_t val = aarch64_get_mem_u32 (cpu, address + (i * 4));
  10095. aarch64_set_vec_u32 (cpu, vd + i, lane, val);
  10096. break;
  10097. }
  10098. case 3:
  10099. {
  10100. uint64_t val = aarch64_get_mem_u64 (cpu, address + (i * 8));
  10101. aarch64_set_vec_u64 (cpu, vd + i, lane, val);
  10102. break;
  10103. }
  10104. }
  10105. }
  10106. /* Store single structure from one lane from N registers. */
  10107. static void
  10108. do_vec_STn_single (sim_cpu *cpu, uint64_t address)
  10109. {
  10110. /* instr[31] = 0
  10111. instr[30] = element selector 0=>half, 1=>all elements
  10112. instr[29,24] = 00 1101
  10113. instr[23] = 0=>simple, 1=>post
  10114. instr[22] = 0
  10115. instr[21] = width: LD1-or-LD3 (0) / LD2-or-LD4 (1)
  10116. instr[20,16] = 0 0000 (simple), Vinc (reg-post-inc, no SP),
  10117. 11111 (immediate post inc)
  10118. instr[15,13] = opcode
  10119. instr[12] = S, used for lane number
  10120. instr[11,10] = size, also used for lane number
  10121. instr[9,5] = address
  10122. instr[4,0] = Vd */
  10123. unsigned full = INSTR (30, 30);
  10124. unsigned vd = INSTR (4, 0);
  10125. unsigned size = INSTR (11, 10);
  10126. unsigned s = INSTR (12, 12);
  10127. int nregs = ((INSTR (13, 13) << 1) | INSTR (21, 21)) + 1;
  10128. int lane = 0;
  10129. int i;
  10130. NYI_assert (29, 24, 0x0D);
  10131. NYI_assert (22, 22, 0);
  10132. /* Compute the lane number first (using size), and then compute size. */
  10133. LDn_STn_SINGLE_LANE_AND_SIZE ();
  10134. for (i = 0; i < nregs; i++)
  10135. switch (size)
  10136. {
  10137. case 0:
  10138. {
  10139. uint8_t val = aarch64_get_vec_u8 (cpu, vd + i, lane);
  10140. aarch64_set_mem_u8 (cpu, address + i, val);
  10141. break;
  10142. }
  10143. case 1:
  10144. {
  10145. uint16_t val = aarch64_get_vec_u16 (cpu, vd + i, lane);
  10146. aarch64_set_mem_u16 (cpu, address + (i * 2), val);
  10147. break;
  10148. }
  10149. case 2:
  10150. {
  10151. uint32_t val = aarch64_get_vec_u32 (cpu, vd + i, lane);
  10152. aarch64_set_mem_u32 (cpu, address + (i * 4), val);
  10153. break;
  10154. }
  10155. case 3:
  10156. {
  10157. uint64_t val = aarch64_get_vec_u64 (cpu, vd + i, lane);
  10158. aarch64_set_mem_u64 (cpu, address + (i * 8), val);
  10159. break;
  10160. }
  10161. }
  10162. }
  10163. /* Load single structure into all lanes of N registers. */
  10164. static void
  10165. do_vec_LDnR (sim_cpu *cpu, uint64_t address)
  10166. {
  10167. /* instr[31] = 0
  10168. instr[30] = element selector 0=>half, 1=>all elements
  10169. instr[29,24] = 00 1101
  10170. instr[23] = 0=>simple, 1=>post
  10171. instr[22] = 1
  10172. instr[21] = width: LD1R-or-LD3R (0) / LD2R-or-LD4R (1)
  10173. instr[20,16] = 0 0000 (simple), Vinc (reg-post-inc, no SP),
  10174. 11111 (immediate post inc)
  10175. instr[15,14] = 11
  10176. instr[13] = width: LD1R-or-LD2R (0) / LD3R-or-LD4R (1)
  10177. instr[12] = 0
  10178. instr[11,10] = element size 00=> byte(b), 01=> half(h),
  10179. 10=> word(s), 11=> double(d)
  10180. instr[9,5] = address
  10181. instr[4,0] = Vd */
  10182. unsigned full = INSTR (30, 30);
  10183. unsigned vd = INSTR (4, 0);
  10184. unsigned size = INSTR (11, 10);
  10185. int nregs = ((INSTR (13, 13) << 1) | INSTR (21, 21)) + 1;
  10186. int i, n;
  10187. NYI_assert (29, 24, 0x0D);
  10188. NYI_assert (22, 22, 1);
  10189. NYI_assert (15, 14, 3);
  10190. NYI_assert (12, 12, 0);
  10191. for (n = 0; n < nregs; n++)
  10192. switch (size)
  10193. {
  10194. case 0:
  10195. {
  10196. uint8_t val = aarch64_get_mem_u8 (cpu, address + n);
  10197. for (i = 0; i < (full ? 16 : 8); i++)
  10198. aarch64_set_vec_u8 (cpu, vd + n, i, val);
  10199. break;
  10200. }
  10201. case 1:
  10202. {
  10203. uint16_t val = aarch64_get_mem_u16 (cpu, address + (n * 2));
  10204. for (i = 0; i < (full ? 8 : 4); i++)
  10205. aarch64_set_vec_u16 (cpu, vd + n, i, val);
  10206. break;
  10207. }
  10208. case 2:
  10209. {
  10210. uint32_t val = aarch64_get_mem_u32 (cpu, address + (n * 4));
  10211. for (i = 0; i < (full ? 4 : 2); i++)
  10212. aarch64_set_vec_u32 (cpu, vd + n, i, val);
  10213. break;
  10214. }
  10215. case 3:
  10216. {
  10217. uint64_t val = aarch64_get_mem_u64 (cpu, address + (n * 8));
  10218. for (i = 0; i < (full ? 2 : 1); i++)
  10219. aarch64_set_vec_u64 (cpu, vd + n, i, val);
  10220. break;
  10221. }
  10222. default:
  10223. HALT_UNALLOC;
  10224. }
  10225. }
  10226. static void
  10227. do_vec_load_store (sim_cpu *cpu)
  10228. {
  10229. /* {LD|ST}<N> {Vd..Vd+N}, vaddr
  10230. instr[31] = 0
  10231. instr[30] = element selector 0=>half, 1=>all elements
  10232. instr[29,25] = 00110
  10233. instr[24] = 0=>multiple struct, 1=>single struct
  10234. instr[23] = 0=>simple, 1=>post
  10235. instr[22] = 0=>store, 1=>load
  10236. instr[21] = 0 (LDn) / small(0)-large(1) selector (LDnR)
  10237. instr[20,16] = 00000 (simple), Vinc (reg-post-inc, no SP),
  10238. 11111 (immediate post inc)
  10239. instr[15,12] = elements and destinations. eg for load:
  10240. 0000=>LD4 => load multiple 4-element to
  10241. four consecutive registers
  10242. 0100=>LD3 => load multiple 3-element to
  10243. three consecutive registers
  10244. 1000=>LD2 => load multiple 2-element to
  10245. two consecutive registers
  10246. 0010=>LD1 => load multiple 1-element to
  10247. four consecutive registers
  10248. 0110=>LD1 => load multiple 1-element to
  10249. three consecutive registers
  10250. 1010=>LD1 => load multiple 1-element to
  10251. two consecutive registers
  10252. 0111=>LD1 => load multiple 1-element to
  10253. one register
  10254. 1100=>LDR1,LDR2
  10255. 1110=>LDR3,LDR4
  10256. instr[11,10] = element size 00=> byte(b), 01=> half(h),
  10257. 10=> word(s), 11=> double(d)
  10258. instr[9,5] = Vn, can be SP
  10259. instr[4,0] = Vd */
  10260. int single;
  10261. int post;
  10262. int load;
  10263. unsigned vn;
  10264. uint64_t address;
  10265. int type;
  10266. if (INSTR (31, 31) != 0 || INSTR (29, 25) != 0x06)
  10267. HALT_NYI;
  10268. single = INSTR (24, 24);
  10269. post = INSTR (23, 23);
  10270. load = INSTR (22, 22);
  10271. type = INSTR (15, 12);
  10272. vn = INSTR (9, 5);
  10273. address = aarch64_get_reg_u64 (cpu, vn, SP_OK);
  10274. if (! single && INSTR (21, 21) != 0)
  10275. HALT_UNALLOC;
  10276. if (post)
  10277. {
  10278. unsigned vm = INSTR (20, 16);
  10279. if (vm == R31)
  10280. {
  10281. unsigned sizeof_operation;
  10282. if (single)
  10283. {
  10284. if ((type >= 0) && (type <= 11))
  10285. {
  10286. int nregs = ((INSTR (13, 13) << 1) | INSTR (21, 21)) + 1;
  10287. switch (INSTR (15, 14))
  10288. {
  10289. case 0:
  10290. sizeof_operation = nregs * 1;
  10291. break;
  10292. case 1:
  10293. sizeof_operation = nregs * 2;
  10294. break;
  10295. case 2:
  10296. if (INSTR (10, 10) == 0)
  10297. sizeof_operation = nregs * 4;
  10298. else
  10299. sizeof_operation = nregs * 8;
  10300. break;
  10301. default:
  10302. HALT_UNALLOC;
  10303. }
  10304. }
  10305. else if (type == 0xC)
  10306. {
  10307. sizeof_operation = INSTR (21, 21) ? 2 : 1;
  10308. sizeof_operation <<= INSTR (11, 10);
  10309. }
  10310. else if (type == 0xE)
  10311. {
  10312. sizeof_operation = INSTR (21, 21) ? 4 : 3;
  10313. sizeof_operation <<= INSTR (11, 10);
  10314. }
  10315. else
  10316. HALT_UNALLOC;
  10317. }
  10318. else
  10319. {
  10320. switch (type)
  10321. {
  10322. case 0: sizeof_operation = 32; break;
  10323. case 4: sizeof_operation = 24; break;
  10324. case 8: sizeof_operation = 16; break;
  10325. case 7:
  10326. /* One register, immediate offset variant. */
  10327. sizeof_operation = 8;
  10328. break;
  10329. case 10:
  10330. /* Two registers, immediate offset variant. */
  10331. sizeof_operation = 16;
  10332. break;
  10333. case 6:
  10334. /* Three registers, immediate offset variant. */
  10335. sizeof_operation = 24;
  10336. break;
  10337. case 2:
  10338. /* Four registers, immediate offset variant. */
  10339. sizeof_operation = 32;
  10340. break;
  10341. default:
  10342. HALT_UNALLOC;
  10343. }
  10344. if (INSTR (30, 30))
  10345. sizeof_operation *= 2;
  10346. }
  10347. aarch64_set_reg_u64 (cpu, vn, SP_OK, address + sizeof_operation);
  10348. }
  10349. else
  10350. aarch64_set_reg_u64 (cpu, vn, SP_OK,
  10351. address + aarch64_get_reg_u64 (cpu, vm, NO_SP));
  10352. }
  10353. else
  10354. {
  10355. NYI_assert (20, 16, 0);
  10356. }
  10357. if (single)
  10358. {
  10359. if (load)
  10360. {
  10361. if ((type >= 0) && (type <= 11))
  10362. do_vec_LDn_single (cpu, address);
  10363. else if ((type == 0xC) || (type == 0xE))
  10364. do_vec_LDnR (cpu, address);
  10365. else
  10366. HALT_UNALLOC;
  10367. return;
  10368. }
  10369. /* Stores. */
  10370. if ((type >= 0) && (type <= 11))
  10371. {
  10372. do_vec_STn_single (cpu, address);
  10373. return;
  10374. }
  10375. HALT_UNALLOC;
  10376. }
  10377. if (load)
  10378. {
  10379. switch (type)
  10380. {
  10381. case 0: LD4 (cpu, address); return;
  10382. case 4: LD3 (cpu, address); return;
  10383. case 8: LD2 (cpu, address); return;
  10384. case 2: LD1_4 (cpu, address); return;
  10385. case 6: LD1_3 (cpu, address); return;
  10386. case 10: LD1_2 (cpu, address); return;
  10387. case 7: LD1_1 (cpu, address); return;
  10388. default:
  10389. HALT_UNALLOC;
  10390. }
  10391. }
  10392. /* Stores. */
  10393. switch (type)
  10394. {
  10395. case 0: ST4 (cpu, address); return;
  10396. case 4: ST3 (cpu, address); return;
  10397. case 8: ST2 (cpu, address); return;
  10398. case 2: ST1_4 (cpu, address); return;
  10399. case 6: ST1_3 (cpu, address); return;
  10400. case 10: ST1_2 (cpu, address); return;
  10401. case 7: ST1_1 (cpu, address); return;
  10402. default:
  10403. HALT_UNALLOC;
  10404. }
  10405. }
  10406. static void
  10407. dexLdSt (sim_cpu *cpu)
  10408. {
  10409. /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu));
  10410. assert group == GROUP_LDST_0100 || group == GROUP_LDST_0110 ||
  10411. group == GROUP_LDST_1100 || group == GROUP_LDST_1110
  10412. bits [29,28:26] of a LS are the secondary dispatch vector. */
  10413. uint32_t group2 = dispatchLS (aarch64_get_instr (cpu));
  10414. switch (group2)
  10415. {
  10416. case LS_EXCL_000:
  10417. dexLoadExclusive (cpu); return;
  10418. case LS_LIT_010:
  10419. case LS_LIT_011:
  10420. dexLoadLiteral (cpu); return;
  10421. case LS_OTHER_110:
  10422. case LS_OTHER_111:
  10423. dexLoadOther (cpu); return;
  10424. case LS_ADVSIMD_001:
  10425. do_vec_load_store (cpu); return;
  10426. case LS_PAIR_100:
  10427. dex_load_store_pair_gr (cpu); return;
  10428. case LS_PAIR_101:
  10429. dex_load_store_pair_fp (cpu); return;
  10430. default:
  10431. /* Should never reach here. */
  10432. HALT_NYI;
  10433. }
  10434. }
  10435. /* Specific decode and execute for group Data Processing Register. */
  10436. static void
  10437. dexLogicalShiftedRegister (sim_cpu *cpu)
  10438. {
  10439. /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  10440. instr[30,29] = op
  10441. instr[28:24] = 01010
  10442. instr[23,22] = shift : 0 ==> LSL, 1 ==> LSR, 2 ==> ASR, 3 ==> ROR
  10443. instr[21] = N
  10444. instr[20,16] = Rm
  10445. instr[15,10] = count : must be 0xxxxx for 32 bit
  10446. instr[9,5] = Rn
  10447. instr[4,0] = Rd */
  10448. uint32_t size = INSTR (31, 31);
  10449. Shift shiftType = INSTR (23, 22);
  10450. uint32_t count = INSTR (15, 10);
  10451. /* 32 bit operations must have count[5] = 0.
  10452. or else we have an UNALLOC. */
  10453. if (size == 0 && uimm (count, 5, 5))
  10454. HALT_UNALLOC;
  10455. /* Dispatch on size:op:N. */
  10456. switch ((INSTR (31, 29) << 1) | INSTR (21, 21))
  10457. {
  10458. case 0: and32_shift (cpu, shiftType, count); return;
  10459. case 1: bic32_shift (cpu, shiftType, count); return;
  10460. case 2: orr32_shift (cpu, shiftType, count); return;
  10461. case 3: orn32_shift (cpu, shiftType, count); return;
  10462. case 4: eor32_shift (cpu, shiftType, count); return;
  10463. case 5: eon32_shift (cpu, shiftType, count); return;
  10464. case 6: ands32_shift (cpu, shiftType, count); return;
  10465. case 7: bics32_shift (cpu, shiftType, count); return;
  10466. case 8: and64_shift (cpu, shiftType, count); return;
  10467. case 9: bic64_shift (cpu, shiftType, count); return;
  10468. case 10:orr64_shift (cpu, shiftType, count); return;
  10469. case 11:orn64_shift (cpu, shiftType, count); return;
  10470. case 12:eor64_shift (cpu, shiftType, count); return;
  10471. case 13:eon64_shift (cpu, shiftType, count); return;
  10472. case 14:ands64_shift (cpu, shiftType, count); return;
  10473. case 15:bics64_shift (cpu, shiftType, count); return;
  10474. }
  10475. }
  10476. /* 32 bit conditional select. */
  10477. static void
  10478. csel32 (sim_cpu *cpu, CondCode cc)
  10479. {
  10480. unsigned rm = INSTR (20, 16);
  10481. unsigned rn = INSTR (9, 5);
  10482. unsigned rd = INSTR (4, 0);
  10483. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  10484. testConditionCode (cpu, cc)
  10485. ? aarch64_get_reg_u32 (cpu, rn, NO_SP)
  10486. : aarch64_get_reg_u32 (cpu, rm, NO_SP));
  10487. }
  10488. /* 64 bit conditional select. */
  10489. static void
  10490. csel64 (sim_cpu *cpu, CondCode cc)
  10491. {
  10492. unsigned rm = INSTR (20, 16);
  10493. unsigned rn = INSTR (9, 5);
  10494. unsigned rd = INSTR (4, 0);
  10495. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  10496. testConditionCode (cpu, cc)
  10497. ? aarch64_get_reg_u64 (cpu, rn, NO_SP)
  10498. : aarch64_get_reg_u64 (cpu, rm, NO_SP));
  10499. }
  10500. /* 32 bit conditional increment. */
  10501. static void
  10502. csinc32 (sim_cpu *cpu, CondCode cc)
  10503. {
  10504. unsigned rm = INSTR (20, 16);
  10505. unsigned rn = INSTR (9, 5);
  10506. unsigned rd = INSTR (4, 0);
  10507. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  10508. testConditionCode (cpu, cc)
  10509. ? aarch64_get_reg_u32 (cpu, rn, NO_SP)
  10510. : aarch64_get_reg_u32 (cpu, rm, NO_SP) + 1);
  10511. }
  10512. /* 64 bit conditional increment. */
  10513. static void
  10514. csinc64 (sim_cpu *cpu, CondCode cc)
  10515. {
  10516. unsigned rm = INSTR (20, 16);
  10517. unsigned rn = INSTR (9, 5);
  10518. unsigned rd = INSTR (4, 0);
  10519. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  10520. testConditionCode (cpu, cc)
  10521. ? aarch64_get_reg_u64 (cpu, rn, NO_SP)
  10522. : aarch64_get_reg_u64 (cpu, rm, NO_SP) + 1);
  10523. }
  10524. /* 32 bit conditional invert. */
  10525. static void
  10526. csinv32 (sim_cpu *cpu, CondCode cc)
  10527. {
  10528. unsigned rm = INSTR (20, 16);
  10529. unsigned rn = INSTR (9, 5);
  10530. unsigned rd = INSTR (4, 0);
  10531. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  10532. testConditionCode (cpu, cc)
  10533. ? aarch64_get_reg_u32 (cpu, rn, NO_SP)
  10534. : ~ aarch64_get_reg_u32 (cpu, rm, NO_SP));
  10535. }
  10536. /* 64 bit conditional invert. */
  10537. static void
  10538. csinv64 (sim_cpu *cpu, CondCode cc)
  10539. {
  10540. unsigned rm = INSTR (20, 16);
  10541. unsigned rn = INSTR (9, 5);
  10542. unsigned rd = INSTR (4, 0);
  10543. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  10544. testConditionCode (cpu, cc)
  10545. ? aarch64_get_reg_u64 (cpu, rn, NO_SP)
  10546. : ~ aarch64_get_reg_u64 (cpu, rm, NO_SP));
  10547. }
  10548. /* 32 bit conditional negate. */
  10549. static void
  10550. csneg32 (sim_cpu *cpu, CondCode cc)
  10551. {
  10552. unsigned rm = INSTR (20, 16);
  10553. unsigned rn = INSTR (9, 5);
  10554. unsigned rd = INSTR (4, 0);
  10555. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  10556. testConditionCode (cpu, cc)
  10557. ? aarch64_get_reg_u32 (cpu, rn, NO_SP)
  10558. : - aarch64_get_reg_u32 (cpu, rm, NO_SP));
  10559. }
  10560. /* 64 bit conditional negate. */
  10561. static void
  10562. csneg64 (sim_cpu *cpu, CondCode cc)
  10563. {
  10564. unsigned rm = INSTR (20, 16);
  10565. unsigned rn = INSTR (9, 5);
  10566. unsigned rd = INSTR (4, 0);
  10567. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  10568. testConditionCode (cpu, cc)
  10569. ? aarch64_get_reg_u64 (cpu, rn, NO_SP)
  10570. : - aarch64_get_reg_u64 (cpu, rm, NO_SP));
  10571. }
  10572. static void
  10573. dexCondSelect (sim_cpu *cpu)
  10574. {
  10575. /* instr[28,21] = 11011011
  10576. instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  10577. instr[30:11,10] = op : 000 ==> CSEL, 001 ==> CSINC,
  10578. 100 ==> CSINV, 101 ==> CSNEG,
  10579. _1_ ==> UNALLOC
  10580. instr[29] = S : 0 ==> ok, 1 ==> UNALLOC
  10581. instr[15,12] = cond
  10582. instr[29] = S : 0 ==> ok, 1 ==> UNALLOC */
  10583. CondCode cc = INSTR (15, 12);
  10584. uint32_t S = INSTR (29, 29);
  10585. uint32_t op2 = INSTR (11, 10);
  10586. if (S == 1)
  10587. HALT_UNALLOC;
  10588. if (op2 & 0x2)
  10589. HALT_UNALLOC;
  10590. switch ((INSTR (31, 30) << 1) | op2)
  10591. {
  10592. case 0: csel32 (cpu, cc); return;
  10593. case 1: csinc32 (cpu, cc); return;
  10594. case 2: csinv32 (cpu, cc); return;
  10595. case 3: csneg32 (cpu, cc); return;
  10596. case 4: csel64 (cpu, cc); return;
  10597. case 5: csinc64 (cpu, cc); return;
  10598. case 6: csinv64 (cpu, cc); return;
  10599. case 7: csneg64 (cpu, cc); return;
  10600. }
  10601. }
  10602. /* Some helpers for counting leading 1 or 0 bits. */
  10603. /* Counts the number of leading bits which are the same
  10604. in a 32 bit value in the range 1 to 32. */
  10605. static uint32_t
  10606. leading32 (uint32_t value)
  10607. {
  10608. int32_t mask= 0xffff0000;
  10609. uint32_t count= 16; /* Counts number of bits set in mask. */
  10610. uint32_t lo = 1; /* Lower bound for number of sign bits. */
  10611. uint32_t hi = 32; /* Upper bound for number of sign bits. */
  10612. while (lo + 1 < hi)
  10613. {
  10614. int32_t test = (value & mask);
  10615. if (test == 0 || test == mask)
  10616. {
  10617. lo = count;
  10618. count = (lo + hi) / 2;
  10619. mask >>= (count - lo);
  10620. }
  10621. else
  10622. {
  10623. hi = count;
  10624. count = (lo + hi) / 2;
  10625. mask <<= hi - count;
  10626. }
  10627. }
  10628. if (lo != hi)
  10629. {
  10630. int32_t test;
  10631. mask >>= 1;
  10632. test = (value & mask);
  10633. if (test == 0 || test == mask)
  10634. count = hi;
  10635. else
  10636. count = lo;
  10637. }
  10638. return count;
  10639. }
  10640. /* Counts the number of leading bits which are the same
  10641. in a 64 bit value in the range 1 to 64. */
  10642. static uint64_t
  10643. leading64 (uint64_t value)
  10644. {
  10645. int64_t mask= 0xffffffff00000000LL;
  10646. uint64_t count = 32; /* Counts number of bits set in mask. */
  10647. uint64_t lo = 1; /* Lower bound for number of sign bits. */
  10648. uint64_t hi = 64; /* Upper bound for number of sign bits. */
  10649. while (lo + 1 < hi)
  10650. {
  10651. int64_t test = (value & mask);
  10652. if (test == 0 || test == mask)
  10653. {
  10654. lo = count;
  10655. count = (lo + hi) / 2;
  10656. mask >>= (count - lo);
  10657. }
  10658. else
  10659. {
  10660. hi = count;
  10661. count = (lo + hi) / 2;
  10662. mask <<= hi - count;
  10663. }
  10664. }
  10665. if (lo != hi)
  10666. {
  10667. int64_t test;
  10668. mask >>= 1;
  10669. test = (value & mask);
  10670. if (test == 0 || test == mask)
  10671. count = hi;
  10672. else
  10673. count = lo;
  10674. }
  10675. return count;
  10676. }
  10677. /* Bit operations. */
  10678. /* N.B register args may not be SP. */
  10679. /* 32 bit count leading sign bits. */
  10680. static void
  10681. cls32 (sim_cpu *cpu)
  10682. {
  10683. unsigned rn = INSTR (9, 5);
  10684. unsigned rd = INSTR (4, 0);
  10685. /* N.B. the result needs to exclude the leading bit. */
  10686. aarch64_set_reg_u64
  10687. (cpu, rd, NO_SP, leading32 (aarch64_get_reg_u32 (cpu, rn, NO_SP)) - 1);
  10688. }
  10689. /* 64 bit count leading sign bits. */
  10690. static void
  10691. cls64 (sim_cpu *cpu)
  10692. {
  10693. unsigned rn = INSTR (9, 5);
  10694. unsigned rd = INSTR (4, 0);
  10695. /* N.B. the result needs to exclude the leading bit. */
  10696. aarch64_set_reg_u64
  10697. (cpu, rd, NO_SP, leading64 (aarch64_get_reg_u64 (cpu, rn, NO_SP)) - 1);
  10698. }
  10699. /* 32 bit count leading zero bits. */
  10700. static void
  10701. clz32 (sim_cpu *cpu)
  10702. {
  10703. unsigned rn = INSTR (9, 5);
  10704. unsigned rd = INSTR (4, 0);
  10705. uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  10706. /* if the sign (top) bit is set then the count is 0. */
  10707. if (pick32 (value, 31, 31))
  10708. aarch64_set_reg_u64 (cpu, rd, NO_SP, 0L);
  10709. else
  10710. aarch64_set_reg_u64 (cpu, rd, NO_SP, leading32 (value));
  10711. }
  10712. /* 64 bit count leading zero bits. */
  10713. static void
  10714. clz64 (sim_cpu *cpu)
  10715. {
  10716. unsigned rn = INSTR (9, 5);
  10717. unsigned rd = INSTR (4, 0);
  10718. uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  10719. /* if the sign (top) bit is set then the count is 0. */
  10720. if (pick64 (value, 63, 63))
  10721. aarch64_set_reg_u64 (cpu, rd, NO_SP, 0L);
  10722. else
  10723. aarch64_set_reg_u64 (cpu, rd, NO_SP, leading64 (value));
  10724. }
  10725. /* 32 bit reverse bits. */
  10726. static void
  10727. rbit32 (sim_cpu *cpu)
  10728. {
  10729. unsigned rn = INSTR (9, 5);
  10730. unsigned rd = INSTR (4, 0);
  10731. uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  10732. uint32_t result = 0;
  10733. int i;
  10734. for (i = 0; i < 32; i++)
  10735. {
  10736. result <<= 1;
  10737. result |= (value & 1);
  10738. value >>= 1;
  10739. }
  10740. aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
  10741. }
  10742. /* 64 bit reverse bits. */
  10743. static void
  10744. rbit64 (sim_cpu *cpu)
  10745. {
  10746. unsigned rn = INSTR (9, 5);
  10747. unsigned rd = INSTR (4, 0);
  10748. uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  10749. uint64_t result = 0;
  10750. int i;
  10751. for (i = 0; i < 64; i++)
  10752. {
  10753. result <<= 1;
  10754. result |= (value & 1UL);
  10755. value >>= 1;
  10756. }
  10757. aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
  10758. }
  10759. /* 32 bit reverse bytes. */
  10760. static void
  10761. rev32 (sim_cpu *cpu)
  10762. {
  10763. unsigned rn = INSTR (9, 5);
  10764. unsigned rd = INSTR (4, 0);
  10765. uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  10766. uint32_t result = 0;
  10767. int i;
  10768. for (i = 0; i < 4; i++)
  10769. {
  10770. result <<= 8;
  10771. result |= (value & 0xff);
  10772. value >>= 8;
  10773. }
  10774. aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
  10775. }
  10776. /* 64 bit reverse bytes. */
  10777. static void
  10778. rev64 (sim_cpu *cpu)
  10779. {
  10780. unsigned rn = INSTR (9, 5);
  10781. unsigned rd = INSTR (4, 0);
  10782. uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  10783. uint64_t result = 0;
  10784. int i;
  10785. for (i = 0; i < 8; i++)
  10786. {
  10787. result <<= 8;
  10788. result |= (value & 0xffULL);
  10789. value >>= 8;
  10790. }
  10791. aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
  10792. }
  10793. /* 32 bit reverse shorts. */
  10794. /* N.B.this reverses the order of the bytes in each half word. */
  10795. static void
  10796. revh32 (sim_cpu *cpu)
  10797. {
  10798. unsigned rn = INSTR (9, 5);
  10799. unsigned rd = INSTR (4, 0);
  10800. uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  10801. uint32_t result = 0;
  10802. int i;
  10803. for (i = 0; i < 2; i++)
  10804. {
  10805. result <<= 8;
  10806. result |= (value & 0x00ff00ff);
  10807. value >>= 8;
  10808. }
  10809. aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
  10810. }
  10811. /* 64 bit reverse shorts. */
  10812. /* N.B.this reverses the order of the bytes in each half word. */
  10813. static void
  10814. revh64 (sim_cpu *cpu)
  10815. {
  10816. unsigned rn = INSTR (9, 5);
  10817. unsigned rd = INSTR (4, 0);
  10818. uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  10819. uint64_t result = 0;
  10820. int i;
  10821. for (i = 0; i < 2; i++)
  10822. {
  10823. result <<= 8;
  10824. result |= (value & 0x00ff00ff00ff00ffULL);
  10825. value >>= 8;
  10826. }
  10827. aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
  10828. }
  10829. static void
  10830. dexDataProc1Source (sim_cpu *cpu)
  10831. {
  10832. /* instr[30] = 1
  10833. instr[28,21] = 111010110
  10834. instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  10835. instr[29] = S : 0 ==> ok, 1 ==> UNALLOC
  10836. instr[20,16] = opcode2 : 00000 ==> ok, ow ==> UNALLOC
  10837. instr[15,10] = opcode : 000000 ==> RBIT, 000001 ==> REV16,
  10838. 000010 ==> REV, 000011 ==> UNALLOC
  10839. 000100 ==> CLZ, 000101 ==> CLS
  10840. ow ==> UNALLOC
  10841. instr[9,5] = rn : may not be SP
  10842. instr[4,0] = rd : may not be SP. */
  10843. uint32_t S = INSTR (29, 29);
  10844. uint32_t opcode2 = INSTR (20, 16);
  10845. uint32_t opcode = INSTR (15, 10);
  10846. uint32_t dispatch = ((INSTR (31, 31) << 3) | opcode);
  10847. if (S == 1)
  10848. HALT_UNALLOC;
  10849. if (opcode2 != 0)
  10850. HALT_UNALLOC;
  10851. if (opcode & 0x38)
  10852. HALT_UNALLOC;
  10853. switch (dispatch)
  10854. {
  10855. case 0: rbit32 (cpu); return;
  10856. case 1: revh32 (cpu); return;
  10857. case 2: rev32 (cpu); return;
  10858. case 4: clz32 (cpu); return;
  10859. case 5: cls32 (cpu); return;
  10860. case 8: rbit64 (cpu); return;
  10861. case 9: revh64 (cpu); return;
  10862. case 10:rev32 (cpu); return;
  10863. case 11:rev64 (cpu); return;
  10864. case 12:clz64 (cpu); return;
  10865. case 13:cls64 (cpu); return;
  10866. default: HALT_UNALLOC;
  10867. }
  10868. }
  10869. /* Variable shift.
  10870. Shifts by count supplied in register.
  10871. N.B register args may not be SP.
  10872. These all use the shifted auxiliary function for
  10873. simplicity and clarity. Writing the actual shift
  10874. inline would avoid a branch and so be faster but
  10875. would also necessitate getting signs right. */
  10876. /* 32 bit arithmetic shift right. */
  10877. static void
  10878. asrv32 (sim_cpu *cpu)
  10879. {
  10880. unsigned rm = INSTR (20, 16);
  10881. unsigned rn = INSTR (9, 5);
  10882. unsigned rd = INSTR (4, 0);
  10883. aarch64_set_reg_u64
  10884. (cpu, rd, NO_SP,
  10885. shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), ASR,
  10886. (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f)));
  10887. }
  10888. /* 64 bit arithmetic shift right. */
  10889. static void
  10890. asrv64 (sim_cpu *cpu)
  10891. {
  10892. unsigned rm = INSTR (20, 16);
  10893. unsigned rn = INSTR (9, 5);
  10894. unsigned rd = INSTR (4, 0);
  10895. aarch64_set_reg_u64
  10896. (cpu, rd, NO_SP,
  10897. shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), ASR,
  10898. (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f)));
  10899. }
  10900. /* 32 bit logical shift left. */
  10901. static void
  10902. lslv32 (sim_cpu *cpu)
  10903. {
  10904. unsigned rm = INSTR (20, 16);
  10905. unsigned rn = INSTR (9, 5);
  10906. unsigned rd = INSTR (4, 0);
  10907. aarch64_set_reg_u64
  10908. (cpu, rd, NO_SP,
  10909. shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), LSL,
  10910. (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f)));
  10911. }
  10912. /* 64 bit arithmetic shift left. */
  10913. static void
  10914. lslv64 (sim_cpu *cpu)
  10915. {
  10916. unsigned rm = INSTR (20, 16);
  10917. unsigned rn = INSTR (9, 5);
  10918. unsigned rd = INSTR (4, 0);
  10919. aarch64_set_reg_u64
  10920. (cpu, rd, NO_SP,
  10921. shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), LSL,
  10922. (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f)));
  10923. }
  10924. /* 32 bit logical shift right. */
  10925. static void
  10926. lsrv32 (sim_cpu *cpu)
  10927. {
  10928. unsigned rm = INSTR (20, 16);
  10929. unsigned rn = INSTR (9, 5);
  10930. unsigned rd = INSTR (4, 0);
  10931. aarch64_set_reg_u64
  10932. (cpu, rd, NO_SP,
  10933. shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), LSR,
  10934. (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f)));
  10935. }
  10936. /* 64 bit logical shift right. */
  10937. static void
  10938. lsrv64 (sim_cpu *cpu)
  10939. {
  10940. unsigned rm = INSTR (20, 16);
  10941. unsigned rn = INSTR (9, 5);
  10942. unsigned rd = INSTR (4, 0);
  10943. aarch64_set_reg_u64
  10944. (cpu, rd, NO_SP,
  10945. shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), LSR,
  10946. (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f)));
  10947. }
  10948. /* 32 bit rotate right. */
  10949. static void
  10950. rorv32 (sim_cpu *cpu)
  10951. {
  10952. unsigned rm = INSTR (20, 16);
  10953. unsigned rn = INSTR (9, 5);
  10954. unsigned rd = INSTR (4, 0);
  10955. aarch64_set_reg_u64
  10956. (cpu, rd, NO_SP,
  10957. shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), ROR,
  10958. (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f)));
  10959. }
  10960. /* 64 bit rotate right. */
  10961. static void
  10962. rorv64 (sim_cpu *cpu)
  10963. {
  10964. unsigned rm = INSTR (20, 16);
  10965. unsigned rn = INSTR (9, 5);
  10966. unsigned rd = INSTR (4, 0);
  10967. aarch64_set_reg_u64
  10968. (cpu, rd, NO_SP,
  10969. shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), ROR,
  10970. (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f)));
  10971. }
  10972. /* divide. */
  10973. /* 32 bit signed divide. */
  10974. static void
  10975. cpuiv32 (sim_cpu *cpu)
  10976. {
  10977. unsigned rm = INSTR (20, 16);
  10978. unsigned rn = INSTR (9, 5);
  10979. unsigned rd = INSTR (4, 0);
  10980. /* N.B. the pseudo-code does the divide using 64 bit data. */
  10981. /* TODO : check that this rounds towards zero as required. */
  10982. int64_t dividend = aarch64_get_reg_s32 (cpu, rn, NO_SP);
  10983. int64_t divisor = aarch64_get_reg_s32 (cpu, rm, NO_SP);
  10984. aarch64_set_reg_s64 (cpu, rd, NO_SP,
  10985. divisor ? ((int32_t) (dividend / divisor)) : 0);
  10986. }
  10987. /* 64 bit signed divide. */
  10988. static void
  10989. cpuiv64 (sim_cpu *cpu)
  10990. {
  10991. unsigned rm = INSTR (20, 16);
  10992. unsigned rn = INSTR (9, 5);
  10993. unsigned rd = INSTR (4, 0);
  10994. /* TODO : check that this rounds towards zero as required. */
  10995. int64_t divisor = aarch64_get_reg_s64 (cpu, rm, NO_SP);
  10996. aarch64_set_reg_s64
  10997. (cpu, rd, NO_SP,
  10998. divisor ? (aarch64_get_reg_s64 (cpu, rn, NO_SP) / divisor) : 0);
  10999. }
  11000. /* 32 bit unsigned divide. */
  11001. static void
  11002. udiv32 (sim_cpu *cpu)
  11003. {
  11004. unsigned rm = INSTR (20, 16);
  11005. unsigned rn = INSTR (9, 5);
  11006. unsigned rd = INSTR (4, 0);
  11007. /* N.B. the pseudo-code does the divide using 64 bit data. */
  11008. uint64_t dividend = aarch64_get_reg_u32 (cpu, rn, NO_SP);
  11009. uint64_t divisor = aarch64_get_reg_u32 (cpu, rm, NO_SP);
  11010. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  11011. divisor ? (uint32_t) (dividend / divisor) : 0);
  11012. }
  11013. /* 64 bit unsigned divide. */
  11014. static void
  11015. udiv64 (sim_cpu *cpu)
  11016. {
  11017. unsigned rm = INSTR (20, 16);
  11018. unsigned rn = INSTR (9, 5);
  11019. unsigned rd = INSTR (4, 0);
  11020. /* TODO : check that this rounds towards zero as required. */
  11021. uint64_t divisor = aarch64_get_reg_u64 (cpu, rm, NO_SP);
  11022. aarch64_set_reg_u64
  11023. (cpu, rd, NO_SP,
  11024. divisor ? (aarch64_get_reg_u64 (cpu, rn, NO_SP) / divisor) : 0);
  11025. }
  11026. static void
  11027. dexDataProc2Source (sim_cpu *cpu)
  11028. {
  11029. /* assert instr[30] == 0
  11030. instr[28,21] == 11010110
  11031. instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
  11032. instr[29] = S : 0 ==> ok, 1 ==> UNALLOC
  11033. instr[15,10] = opcode : 000010 ==> UDIV, 000011 ==> CPUIV,
  11034. 001000 ==> LSLV, 001001 ==> LSRV
  11035. 001010 ==> ASRV, 001011 ==> RORV
  11036. ow ==> UNALLOC. */
  11037. uint32_t dispatch;
  11038. uint32_t S = INSTR (29, 29);
  11039. uint32_t opcode = INSTR (15, 10);
  11040. if (S == 1)
  11041. HALT_UNALLOC;
  11042. if (opcode & 0x34)
  11043. HALT_UNALLOC;
  11044. dispatch = ( (INSTR (31, 31) << 3)
  11045. | (uimm (opcode, 3, 3) << 2)
  11046. | uimm (opcode, 1, 0));
  11047. switch (dispatch)
  11048. {
  11049. case 2: udiv32 (cpu); return;
  11050. case 3: cpuiv32 (cpu); return;
  11051. case 4: lslv32 (cpu); return;
  11052. case 5: lsrv32 (cpu); return;
  11053. case 6: asrv32 (cpu); return;
  11054. case 7: rorv32 (cpu); return;
  11055. case 10: udiv64 (cpu); return;
  11056. case 11: cpuiv64 (cpu); return;
  11057. case 12: lslv64 (cpu); return;
  11058. case 13: lsrv64 (cpu); return;
  11059. case 14: asrv64 (cpu); return;
  11060. case 15: rorv64 (cpu); return;
  11061. default: HALT_UNALLOC;
  11062. }
  11063. }
  11064. /* Multiply. */
  11065. /* 32 bit multiply and add. */
  11066. static void
  11067. madd32 (sim_cpu *cpu)
  11068. {
  11069. unsigned rm = INSTR (20, 16);
  11070. unsigned ra = INSTR (14, 10);
  11071. unsigned rn = INSTR (9, 5);
  11072. unsigned rd = INSTR (4, 0);
  11073. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11074. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  11075. aarch64_get_reg_u32 (cpu, ra, NO_SP)
  11076. + aarch64_get_reg_u32 (cpu, rn, NO_SP)
  11077. * aarch64_get_reg_u32 (cpu, rm, NO_SP));
  11078. }
  11079. /* 64 bit multiply and add. */
  11080. static void
  11081. madd64 (sim_cpu *cpu)
  11082. {
  11083. unsigned rm = INSTR (20, 16);
  11084. unsigned ra = INSTR (14, 10);
  11085. unsigned rn = INSTR (9, 5);
  11086. unsigned rd = INSTR (4, 0);
  11087. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11088. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  11089. aarch64_get_reg_u64 (cpu, ra, NO_SP)
  11090. + (aarch64_get_reg_u64 (cpu, rn, NO_SP)
  11091. * aarch64_get_reg_u64 (cpu, rm, NO_SP)));
  11092. }
  11093. /* 32 bit multiply and sub. */
  11094. static void
  11095. msub32 (sim_cpu *cpu)
  11096. {
  11097. unsigned rm = INSTR (20, 16);
  11098. unsigned ra = INSTR (14, 10);
  11099. unsigned rn = INSTR (9, 5);
  11100. unsigned rd = INSTR (4, 0);
  11101. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11102. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  11103. aarch64_get_reg_u32 (cpu, ra, NO_SP)
  11104. - aarch64_get_reg_u32 (cpu, rn, NO_SP)
  11105. * aarch64_get_reg_u32 (cpu, rm, NO_SP));
  11106. }
  11107. /* 64 bit multiply and sub. */
  11108. static void
  11109. msub64 (sim_cpu *cpu)
  11110. {
  11111. unsigned rm = INSTR (20, 16);
  11112. unsigned ra = INSTR (14, 10);
  11113. unsigned rn = INSTR (9, 5);
  11114. unsigned rd = INSTR (4, 0);
  11115. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11116. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  11117. aarch64_get_reg_u64 (cpu, ra, NO_SP)
  11118. - aarch64_get_reg_u64 (cpu, rn, NO_SP)
  11119. * aarch64_get_reg_u64 (cpu, rm, NO_SP));
  11120. }
  11121. /* Signed multiply add long -- source, source2 : 32 bit, source3 : 64 bit. */
  11122. static void
  11123. smaddl (sim_cpu *cpu)
  11124. {
  11125. unsigned rm = INSTR (20, 16);
  11126. unsigned ra = INSTR (14, 10);
  11127. unsigned rn = INSTR (9, 5);
  11128. unsigned rd = INSTR (4, 0);
  11129. /* N.B. we need to multiply the signed 32 bit values in rn, rm to
  11130. obtain a 64 bit product. */
  11131. aarch64_set_reg_s64
  11132. (cpu, rd, NO_SP,
  11133. aarch64_get_reg_s64 (cpu, ra, NO_SP)
  11134. + ((int64_t) aarch64_get_reg_s32 (cpu, rn, NO_SP))
  11135. * ((int64_t) aarch64_get_reg_s32 (cpu, rm, NO_SP)));
  11136. }
  11137. /* Signed multiply sub long -- source, source2 : 32 bit, source3 : 64 bit. */
  11138. static void
  11139. smsubl (sim_cpu *cpu)
  11140. {
  11141. unsigned rm = INSTR (20, 16);
  11142. unsigned ra = INSTR (14, 10);
  11143. unsigned rn = INSTR (9, 5);
  11144. unsigned rd = INSTR (4, 0);
  11145. /* N.B. we need to multiply the signed 32 bit values in rn, rm to
  11146. obtain a 64 bit product. */
  11147. aarch64_set_reg_s64
  11148. (cpu, rd, NO_SP,
  11149. aarch64_get_reg_s64 (cpu, ra, NO_SP)
  11150. - ((int64_t) aarch64_get_reg_s32 (cpu, rn, NO_SP))
  11151. * ((int64_t) aarch64_get_reg_s32 (cpu, rm, NO_SP)));
  11152. }
  11153. /* Integer Multiply/Divide. */
  11154. /* First some macros and a helper function. */
  11155. /* Macros to test or access elements of 64 bit words. */
  11156. /* Mask used to access lo 32 bits of 64 bit unsigned int. */
  11157. #define LOW_WORD_MASK ((1ULL << 32) - 1)
  11158. /* Return the lo 32 bit word of a 64 bit unsigned int as a 64 bit unsigned int. */
  11159. #define lowWordToU64(_value_u64) ((_value_u64) & LOW_WORD_MASK)
  11160. /* Return the hi 32 bit word of a 64 bit unsigned int as a 64 bit unsigned int. */
  11161. #define highWordToU64(_value_u64) ((_value_u64) >> 32)
  11162. /* Offset of sign bit in 64 bit signed integger. */
  11163. #define SIGN_SHIFT_U64 63
  11164. /* The sign bit itself -- also identifies the minimum negative int value. */
  11165. #define SIGN_BIT_U64 (1UL << SIGN_SHIFT_U64)
  11166. /* Return true if a 64 bit signed int presented as an unsigned int is the
  11167. most negative value. */
  11168. #define isMinimumU64(_value_u64) ((_value_u64) == SIGN_BIT_U64)
  11169. /* Return true (non-zero) if a 64 bit signed int presented as an unsigned
  11170. int has its sign bit set to false. */
  11171. #define isSignSetU64(_value_u64) ((_value_u64) & SIGN_BIT_U64)
  11172. /* Return 1L or -1L according to whether a 64 bit signed int presented as
  11173. an unsigned int has its sign bit set or not. */
  11174. #define signOfU64(_value_u64) (1L + (((value_u64) >> SIGN_SHIFT_U64) * -2L)
  11175. /* Clear the sign bit of a 64 bit signed int presented as an unsigned int. */
  11176. #define clearSignU64(_value_u64) ((_value_u64) &= ~SIGN_BIT_U64)
  11177. /* Multiply two 64 bit ints and return.
  11178. the hi 64 bits of the 128 bit product. */
  11179. static uint64_t
  11180. mul64hi (uint64_t value1, uint64_t value2)
  11181. {
  11182. uint64_t resultmid1;
  11183. uint64_t result;
  11184. uint64_t value1_lo = lowWordToU64 (value1);
  11185. uint64_t value1_hi = highWordToU64 (value1) ;
  11186. uint64_t value2_lo = lowWordToU64 (value2);
  11187. uint64_t value2_hi = highWordToU64 (value2);
  11188. /* Cross-multiply and collect results. */
  11189. uint64_t xproductlo = value1_lo * value2_lo;
  11190. uint64_t xproductmid1 = value1_lo * value2_hi;
  11191. uint64_t xproductmid2 = value1_hi * value2_lo;
  11192. uint64_t xproducthi = value1_hi * value2_hi;
  11193. uint64_t carry = 0;
  11194. /* Start accumulating 64 bit results. */
  11195. /* Drop bottom half of lowest cross-product. */
  11196. uint64_t resultmid = xproductlo >> 32;
  11197. /* Add in middle products. */
  11198. resultmid = resultmid + xproductmid1;
  11199. /* Check for overflow. */
  11200. if (resultmid < xproductmid1)
  11201. /* Carry over 1 into top cross-product. */
  11202. carry++;
  11203. resultmid1 = resultmid + xproductmid2;
  11204. /* Check for overflow. */
  11205. if (resultmid1 < xproductmid2)
  11206. /* Carry over 1 into top cross-product. */
  11207. carry++;
  11208. /* Drop lowest 32 bits of middle cross-product. */
  11209. result = resultmid1 >> 32;
  11210. /* Move carry bit to just above middle cross-product highest bit. */
  11211. carry = carry << 32;
  11212. /* Add top cross-product plus and any carry. */
  11213. result += xproducthi + carry;
  11214. return result;
  11215. }
  11216. /* Signed multiply high, source, source2 :
  11217. 64 bit, dest <-- high 64-bit of result. */
  11218. static void
  11219. smulh (sim_cpu *cpu)
  11220. {
  11221. uint64_t uresult;
  11222. int64_t result;
  11223. unsigned rm = INSTR (20, 16);
  11224. unsigned rn = INSTR (9, 5);
  11225. unsigned rd = INSTR (4, 0);
  11226. GReg ra = INSTR (14, 10);
  11227. int64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
  11228. int64_t value2 = aarch64_get_reg_u64 (cpu, rm, NO_SP);
  11229. uint64_t uvalue1;
  11230. uint64_t uvalue2;
  11231. int negate = 0;
  11232. if (ra != R31)
  11233. HALT_UNALLOC;
  11234. /* Convert to unsigned and use the unsigned mul64hi routine
  11235. the fix the sign up afterwards. */
  11236. if (value1 < 0)
  11237. {
  11238. negate = !negate;
  11239. uvalue1 = -value1;
  11240. }
  11241. else
  11242. {
  11243. uvalue1 = value1;
  11244. }
  11245. if (value2 < 0)
  11246. {
  11247. negate = !negate;
  11248. uvalue2 = -value2;
  11249. }
  11250. else
  11251. {
  11252. uvalue2 = value2;
  11253. }
  11254. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11255. uresult = mul64hi (uvalue1, uvalue2);
  11256. result = uresult;
  11257. if (negate)
  11258. {
  11259. /* Multiply 128-bit result by -1, which means highpart gets inverted,
  11260. and has carry in added only if low part is 0. */
  11261. result = ~result;
  11262. if ((uvalue1 * uvalue2) == 0)
  11263. result += 1;
  11264. }
  11265. aarch64_set_reg_s64 (cpu, rd, NO_SP, result);
  11266. }
  11267. /* Unsigned multiply add long -- source, source2 :
  11268. 32 bit, source3 : 64 bit. */
  11269. static void
  11270. umaddl (sim_cpu *cpu)
  11271. {
  11272. unsigned rm = INSTR (20, 16);
  11273. unsigned ra = INSTR (14, 10);
  11274. unsigned rn = INSTR (9, 5);
  11275. unsigned rd = INSTR (4, 0);
  11276. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11277. /* N.B. we need to multiply the signed 32 bit values in rn, rm to
  11278. obtain a 64 bit product. */
  11279. aarch64_set_reg_u64
  11280. (cpu, rd, NO_SP,
  11281. aarch64_get_reg_u64 (cpu, ra, NO_SP)
  11282. + ((uint64_t) aarch64_get_reg_u32 (cpu, rn, NO_SP))
  11283. * ((uint64_t) aarch64_get_reg_u32 (cpu, rm, NO_SP)));
  11284. }
  11285. /* Unsigned multiply sub long -- source, source2 : 32 bit, source3 : 64 bit. */
  11286. static void
  11287. umsubl (sim_cpu *cpu)
  11288. {
  11289. unsigned rm = INSTR (20, 16);
  11290. unsigned ra = INSTR (14, 10);
  11291. unsigned rn = INSTR (9, 5);
  11292. unsigned rd = INSTR (4, 0);
  11293. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11294. /* N.B. we need to multiply the signed 32 bit values in rn, rm to
  11295. obtain a 64 bit product. */
  11296. aarch64_set_reg_u64
  11297. (cpu, rd, NO_SP,
  11298. aarch64_get_reg_u64 (cpu, ra, NO_SP)
  11299. - ((uint64_t) aarch64_get_reg_u32 (cpu, rn, NO_SP))
  11300. * ((uint64_t) aarch64_get_reg_u32 (cpu, rm, NO_SP)));
  11301. }
  11302. /* Unsigned multiply high, source, source2 :
  11303. 64 bit, dest <-- high 64-bit of result. */
  11304. static void
  11305. umulh (sim_cpu *cpu)
  11306. {
  11307. unsigned rm = INSTR (20, 16);
  11308. unsigned rn = INSTR (9, 5);
  11309. unsigned rd = INSTR (4, 0);
  11310. GReg ra = INSTR (14, 10);
  11311. if (ra != R31)
  11312. HALT_UNALLOC;
  11313. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11314. aarch64_set_reg_u64 (cpu, rd, NO_SP,
  11315. mul64hi (aarch64_get_reg_u64 (cpu, rn, NO_SP),
  11316. aarch64_get_reg_u64 (cpu, rm, NO_SP)));
  11317. }
  11318. static void
  11319. dexDataProc3Source (sim_cpu *cpu)
  11320. {
  11321. /* assert instr[28,24] == 11011. */
  11322. /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit (for rd at least)
  11323. instr[30,29] = op54 : 00 ==> ok, ow ==> UNALLOC
  11324. instr[23,21] = op31 : 111 ==> UNALLOC, o2 ==> ok
  11325. instr[15] = o0 : 0/1 ==> ok
  11326. instr[23,21:15] ==> op : 0000 ==> MADD, 0001 ==> MSUB, (32/64 bit)
  11327. 0010 ==> SMADDL, 0011 ==> SMSUBL, (64 bit only)
  11328. 0100 ==> SMULH, (64 bit only)
  11329. 1010 ==> UMADDL, 1011 ==> UNSUBL, (64 bit only)
  11330. 1100 ==> UMULH (64 bit only)
  11331. ow ==> UNALLOC. */
  11332. uint32_t dispatch;
  11333. uint32_t size = INSTR (31, 31);
  11334. uint32_t op54 = INSTR (30, 29);
  11335. uint32_t op31 = INSTR (23, 21);
  11336. uint32_t o0 = INSTR (15, 15);
  11337. if (op54 != 0)
  11338. HALT_UNALLOC;
  11339. if (size == 0)
  11340. {
  11341. if (op31 != 0)
  11342. HALT_UNALLOC;
  11343. if (o0 == 0)
  11344. madd32 (cpu);
  11345. else
  11346. msub32 (cpu);
  11347. return;
  11348. }
  11349. dispatch = (op31 << 1) | o0;
  11350. switch (dispatch)
  11351. {
  11352. case 0: madd64 (cpu); return;
  11353. case 1: msub64 (cpu); return;
  11354. case 2: smaddl (cpu); return;
  11355. case 3: smsubl (cpu); return;
  11356. case 4: smulh (cpu); return;
  11357. case 10: umaddl (cpu); return;
  11358. case 11: umsubl (cpu); return;
  11359. case 12: umulh (cpu); return;
  11360. default: HALT_UNALLOC;
  11361. }
  11362. }
  11363. static void
  11364. dexDPReg (sim_cpu *cpu)
  11365. {
  11366. /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu));
  11367. assert group == GROUP_DPREG_0101 || group == GROUP_DPREG_1101
  11368. bits [28:24:21] of a DPReg are the secondary dispatch vector. */
  11369. uint32_t group2 = dispatchDPReg (aarch64_get_instr (cpu));
  11370. switch (group2)
  11371. {
  11372. case DPREG_LOG_000:
  11373. case DPREG_LOG_001:
  11374. dexLogicalShiftedRegister (cpu); return;
  11375. case DPREG_ADDSHF_010:
  11376. dexAddSubtractShiftedRegister (cpu); return;
  11377. case DPREG_ADDEXT_011:
  11378. dexAddSubtractExtendedRegister (cpu); return;
  11379. case DPREG_ADDCOND_100:
  11380. {
  11381. /* This set bundles a variety of different operations. */
  11382. /* Check for. */
  11383. /* 1) add/sub w carry. */
  11384. uint32_t mask1 = 0x1FE00000U;
  11385. uint32_t val1 = 0x1A000000U;
  11386. /* 2) cond compare register/immediate. */
  11387. uint32_t mask2 = 0x1FE00000U;
  11388. uint32_t val2 = 0x1A400000U;
  11389. /* 3) cond select. */
  11390. uint32_t mask3 = 0x1FE00000U;
  11391. uint32_t val3 = 0x1A800000U;
  11392. /* 4) data proc 1/2 source. */
  11393. uint32_t mask4 = 0x1FE00000U;
  11394. uint32_t val4 = 0x1AC00000U;
  11395. if ((aarch64_get_instr (cpu) & mask1) == val1)
  11396. dexAddSubtractWithCarry (cpu);
  11397. else if ((aarch64_get_instr (cpu) & mask2) == val2)
  11398. CondCompare (cpu);
  11399. else if ((aarch64_get_instr (cpu) & mask3) == val3)
  11400. dexCondSelect (cpu);
  11401. else if ((aarch64_get_instr (cpu) & mask4) == val4)
  11402. {
  11403. /* Bit 30 is clear for data proc 2 source
  11404. and set for data proc 1 source. */
  11405. if (aarch64_get_instr (cpu) & (1U << 30))
  11406. dexDataProc1Source (cpu);
  11407. else
  11408. dexDataProc2Source (cpu);
  11409. }
  11410. else
  11411. /* Should not reach here. */
  11412. HALT_NYI;
  11413. return;
  11414. }
  11415. case DPREG_3SRC_110:
  11416. dexDataProc3Source (cpu); return;
  11417. case DPREG_UNALLOC_101:
  11418. HALT_UNALLOC;
  11419. case DPREG_3SRC_111:
  11420. dexDataProc3Source (cpu); return;
  11421. default:
  11422. /* Should never reach here. */
  11423. HALT_NYI;
  11424. }
  11425. }
  11426. /* Unconditional Branch immediate.
  11427. Offset is a PC-relative byte offset in the range +/- 128MiB.
  11428. The offset is assumed to be raw from the decode i.e. the
  11429. simulator is expected to scale them from word offsets to byte. */
  11430. /* Unconditional branch. */
  11431. static void
  11432. buc (sim_cpu *cpu, int32_t offset)
  11433. {
  11434. aarch64_set_next_PC_by_offset (cpu, offset);
  11435. }
  11436. static unsigned stack_depth = 0;
  11437. /* Unconditional branch and link -- writes return PC to LR. */
  11438. static void
  11439. bl (sim_cpu *cpu, int32_t offset)
  11440. {
  11441. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11442. aarch64_save_LR (cpu);
  11443. aarch64_set_next_PC_by_offset (cpu, offset);
  11444. if (TRACE_BRANCH_P (cpu))
  11445. {
  11446. ++ stack_depth;
  11447. TRACE_BRANCH (cpu,
  11448. " %*scall %" PRIx64 " [%s]"
  11449. " [args: %" PRIx64 " %" PRIx64 " %" PRIx64 "]",
  11450. stack_depth, " ", aarch64_get_next_PC (cpu),
  11451. aarch64_get_func (CPU_STATE (cpu),
  11452. aarch64_get_next_PC (cpu)),
  11453. aarch64_get_reg_u64 (cpu, 0, NO_SP),
  11454. aarch64_get_reg_u64 (cpu, 1, NO_SP),
  11455. aarch64_get_reg_u64 (cpu, 2, NO_SP)
  11456. );
  11457. }
  11458. }
  11459. /* Unconditional Branch register.
  11460. Branch/return address is in source register. */
  11461. /* Unconditional branch. */
  11462. static void
  11463. br (sim_cpu *cpu)
  11464. {
  11465. unsigned rn = INSTR (9, 5);
  11466. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11467. aarch64_set_next_PC (cpu, aarch64_get_reg_u64 (cpu, rn, NO_SP));
  11468. }
  11469. /* Unconditional branch and link -- writes return PC to LR. */
  11470. static void
  11471. blr (sim_cpu *cpu)
  11472. {
  11473. /* Ensure we read the destination before we write LR. */
  11474. uint64_t target = aarch64_get_reg_u64 (cpu, INSTR (9, 5), NO_SP);
  11475. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11476. aarch64_save_LR (cpu);
  11477. aarch64_set_next_PC (cpu, target);
  11478. if (TRACE_BRANCH_P (cpu))
  11479. {
  11480. ++ stack_depth;
  11481. TRACE_BRANCH (cpu,
  11482. " %*scall %" PRIx64 " [%s]"
  11483. " [args: %" PRIx64 " %" PRIx64 " %" PRIx64 "]",
  11484. stack_depth, " ", aarch64_get_next_PC (cpu),
  11485. aarch64_get_func (CPU_STATE (cpu),
  11486. aarch64_get_next_PC (cpu)),
  11487. aarch64_get_reg_u64 (cpu, 0, NO_SP),
  11488. aarch64_get_reg_u64 (cpu, 1, NO_SP),
  11489. aarch64_get_reg_u64 (cpu, 2, NO_SP)
  11490. );
  11491. }
  11492. }
  11493. /* Return -- assembler will default source to LR this is functionally
  11494. equivalent to br but, presumably, unlike br it side effects the
  11495. branch predictor. */
  11496. static void
  11497. ret (sim_cpu *cpu)
  11498. {
  11499. unsigned rn = INSTR (9, 5);
  11500. aarch64_set_next_PC (cpu, aarch64_get_reg_u64 (cpu, rn, NO_SP));
  11501. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11502. if (TRACE_BRANCH_P (cpu))
  11503. {
  11504. TRACE_BRANCH (cpu,
  11505. " %*sreturn [result: %" PRIx64 "]",
  11506. stack_depth, " ", aarch64_get_reg_u64 (cpu, 0, NO_SP));
  11507. -- stack_depth;
  11508. }
  11509. }
  11510. /* NOP -- we implement this and call it from the decode in case we
  11511. want to intercept it later. */
  11512. static void
  11513. nop (sim_cpu *cpu)
  11514. {
  11515. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11516. }
  11517. /* Data synchronization barrier. */
  11518. static void
  11519. dsb (sim_cpu *cpu)
  11520. {
  11521. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11522. }
  11523. /* Data memory barrier. */
  11524. static void
  11525. dmb (sim_cpu *cpu)
  11526. {
  11527. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11528. }
  11529. /* Instruction synchronization barrier. */
  11530. static void
  11531. isb (sim_cpu *cpu)
  11532. {
  11533. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11534. }
  11535. static void
  11536. dexBranchImmediate (sim_cpu *cpu)
  11537. {
  11538. /* assert instr[30,26] == 00101
  11539. instr[31] ==> 0 == B, 1 == BL
  11540. instr[25,0] == imm26 branch offset counted in words. */
  11541. uint32_t top = INSTR (31, 31);
  11542. /* We have a 26 byte signed word offset which we need to pass to the
  11543. execute routine as a signed byte offset. */
  11544. int32_t offset = simm32 (aarch64_get_instr (cpu), 25, 0) << 2;
  11545. if (top)
  11546. bl (cpu, offset);
  11547. else
  11548. buc (cpu, offset);
  11549. }
  11550. /* Control Flow. */
  11551. /* Conditional branch
  11552. Offset is a PC-relative byte offset in the range +/- 1MiB pos is
  11553. a bit position in the range 0 .. 63
  11554. cc is a CondCode enum value as pulled out of the decode
  11555. N.B. any offset register (source) can only be Xn or Wn. */
  11556. static void
  11557. bcc (sim_cpu *cpu, int32_t offset, CondCode cc)
  11558. {
  11559. /* The test returns TRUE if CC is met. */
  11560. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11561. if (testConditionCode (cpu, cc))
  11562. aarch64_set_next_PC_by_offset (cpu, offset);
  11563. }
  11564. /* 32 bit branch on register non-zero. */
  11565. static void
  11566. cbnz32 (sim_cpu *cpu, int32_t offset)
  11567. {
  11568. unsigned rt = INSTR (4, 0);
  11569. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11570. if (aarch64_get_reg_u32 (cpu, rt, NO_SP) != 0)
  11571. aarch64_set_next_PC_by_offset (cpu, offset);
  11572. }
  11573. /* 64 bit branch on register zero. */
  11574. static void
  11575. cbnz (sim_cpu *cpu, int32_t offset)
  11576. {
  11577. unsigned rt = INSTR (4, 0);
  11578. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11579. if (aarch64_get_reg_u64 (cpu, rt, NO_SP) != 0)
  11580. aarch64_set_next_PC_by_offset (cpu, offset);
  11581. }
  11582. /* 32 bit branch on register non-zero. */
  11583. static void
  11584. cbz32 (sim_cpu *cpu, int32_t offset)
  11585. {
  11586. unsigned rt = INSTR (4, 0);
  11587. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11588. if (aarch64_get_reg_u32 (cpu, rt, NO_SP) == 0)
  11589. aarch64_set_next_PC_by_offset (cpu, offset);
  11590. }
  11591. /* 64 bit branch on register zero. */
  11592. static void
  11593. cbz (sim_cpu *cpu, int32_t offset)
  11594. {
  11595. unsigned rt = INSTR (4, 0);
  11596. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11597. if (aarch64_get_reg_u64 (cpu, rt, NO_SP) == 0)
  11598. aarch64_set_next_PC_by_offset (cpu, offset);
  11599. }
  11600. /* Branch on register bit test non-zero -- one size fits all. */
  11601. static void
  11602. tbnz (sim_cpu *cpu, uint32_t pos, int32_t offset)
  11603. {
  11604. unsigned rt = INSTR (4, 0);
  11605. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11606. if (aarch64_get_reg_u64 (cpu, rt, NO_SP) & (((uint64_t) 1) << pos))
  11607. aarch64_set_next_PC_by_offset (cpu, offset);
  11608. }
  11609. /* Branch on register bit test zero -- one size fits all. */
  11610. static void
  11611. tbz (sim_cpu *cpu, uint32_t pos, int32_t offset)
  11612. {
  11613. unsigned rt = INSTR (4, 0);
  11614. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11615. if (!(aarch64_get_reg_u64 (cpu, rt, NO_SP) & (((uint64_t) 1) << pos)))
  11616. aarch64_set_next_PC_by_offset (cpu, offset);
  11617. }
  11618. static void
  11619. dexCompareBranchImmediate (sim_cpu *cpu)
  11620. {
  11621. /* instr[30,25] = 01 1010
  11622. instr[31] = size : 0 ==> 32, 1 ==> 64
  11623. instr[24] = op : 0 ==> CBZ, 1 ==> CBNZ
  11624. instr[23,5] = simm19 branch offset counted in words
  11625. instr[4,0] = rt */
  11626. uint32_t size = INSTR (31, 31);
  11627. uint32_t op = INSTR (24, 24);
  11628. int32_t offset = simm32 (aarch64_get_instr (cpu), 23, 5) << 2;
  11629. if (size == 0)
  11630. {
  11631. if (op == 0)
  11632. cbz32 (cpu, offset);
  11633. else
  11634. cbnz32 (cpu, offset);
  11635. }
  11636. else
  11637. {
  11638. if (op == 0)
  11639. cbz (cpu, offset);
  11640. else
  11641. cbnz (cpu, offset);
  11642. }
  11643. }
  11644. static void
  11645. dexTestBranchImmediate (sim_cpu *cpu)
  11646. {
  11647. /* instr[31] = b5 : bit 5 of test bit idx
  11648. instr[30,25] = 01 1011
  11649. instr[24] = op : 0 ==> TBZ, 1 == TBNZ
  11650. instr[23,19] = b40 : bits 4 to 0 of test bit idx
  11651. instr[18,5] = simm14 : signed offset counted in words
  11652. instr[4,0] = uimm5 */
  11653. uint32_t pos = ((INSTR (31, 31) << 5) | INSTR (23, 19));
  11654. int32_t offset = simm32 (aarch64_get_instr (cpu), 18, 5) << 2;
  11655. NYI_assert (30, 25, 0x1b);
  11656. if (INSTR (24, 24) == 0)
  11657. tbz (cpu, pos, offset);
  11658. else
  11659. tbnz (cpu, pos, offset);
  11660. }
  11661. static void
  11662. dexCondBranchImmediate (sim_cpu *cpu)
  11663. {
  11664. /* instr[31,25] = 010 1010
  11665. instr[24] = op1; op => 00 ==> B.cond
  11666. instr[23,5] = simm19 : signed offset counted in words
  11667. instr[4] = op0
  11668. instr[3,0] = cond */
  11669. int32_t offset;
  11670. uint32_t op = ((INSTR (24, 24) << 1) | INSTR (4, 4));
  11671. NYI_assert (31, 25, 0x2a);
  11672. if (op != 0)
  11673. HALT_UNALLOC;
  11674. offset = simm32 (aarch64_get_instr (cpu), 23, 5) << 2;
  11675. bcc (cpu, offset, INSTR (3, 0));
  11676. }
  11677. static void
  11678. dexBranchRegister (sim_cpu *cpu)
  11679. {
  11680. /* instr[31,25] = 110 1011
  11681. instr[24,21] = op : 0 ==> BR, 1 => BLR, 2 => RET, 3 => ERET, 4 => DRPS
  11682. instr[20,16] = op2 : must be 11111
  11683. instr[15,10] = op3 : must be 000000
  11684. instr[4,0] = op2 : must be 11111. */
  11685. uint32_t op = INSTR (24, 21);
  11686. uint32_t op2 = INSTR (20, 16);
  11687. uint32_t op3 = INSTR (15, 10);
  11688. uint32_t op4 = INSTR (4, 0);
  11689. NYI_assert (31, 25, 0x6b);
  11690. if (op2 != 0x1F || op3 != 0 || op4 != 0)
  11691. HALT_UNALLOC;
  11692. if (op == 0)
  11693. br (cpu);
  11694. else if (op == 1)
  11695. blr (cpu);
  11696. else if (op == 2)
  11697. ret (cpu);
  11698. else
  11699. {
  11700. /* ERET and DRPS accept 0b11111 for rn = instr [4,0]. */
  11701. /* anything else is unallocated. */
  11702. uint32_t rn = INSTR (4, 0);
  11703. if (rn != 0x1f)
  11704. HALT_UNALLOC;
  11705. if (op == 4 || op == 5)
  11706. HALT_NYI;
  11707. HALT_UNALLOC;
  11708. }
  11709. }
  11710. /* FIXME: We should get the Angel SWI values from ../../libgloss/aarch64/svc.h
  11711. but this may not be available. So instead we define the values we need
  11712. here. */
  11713. #define AngelSVC_Reason_Open 0x01
  11714. #define AngelSVC_Reason_Close 0x02
  11715. #define AngelSVC_Reason_Write 0x05
  11716. #define AngelSVC_Reason_Read 0x06
  11717. #define AngelSVC_Reason_IsTTY 0x09
  11718. #define AngelSVC_Reason_Seek 0x0A
  11719. #define AngelSVC_Reason_FLen 0x0C
  11720. #define AngelSVC_Reason_Remove 0x0E
  11721. #define AngelSVC_Reason_Rename 0x0F
  11722. #define AngelSVC_Reason_Clock 0x10
  11723. #define AngelSVC_Reason_Time 0x11
  11724. #define AngelSVC_Reason_System 0x12
  11725. #define AngelSVC_Reason_Errno 0x13
  11726. #define AngelSVC_Reason_GetCmdLine 0x15
  11727. #define AngelSVC_Reason_HeapInfo 0x16
  11728. #define AngelSVC_Reason_ReportException 0x18
  11729. #define AngelSVC_Reason_Elapsed 0x30
  11730. static void
  11731. handle_halt (sim_cpu *cpu, uint32_t val)
  11732. {
  11733. uint64_t result = 0;
  11734. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11735. if (val != 0xf000)
  11736. {
  11737. TRACE_SYSCALL (cpu, " HLT [0x%x]", val);
  11738. sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
  11739. sim_stopped, SIM_SIGTRAP);
  11740. }
  11741. /* We have encountered an Angel SVC call. See if we can process it. */
  11742. switch (aarch64_get_reg_u32 (cpu, 0, NO_SP))
  11743. {
  11744. case AngelSVC_Reason_HeapInfo:
  11745. {
  11746. /* Get the values. */
  11747. uint64_t stack_top = aarch64_get_stack_start (cpu);
  11748. uint64_t heap_base = aarch64_get_heap_start (cpu);
  11749. /* Get the pointer */
  11750. uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK);
  11751. ptr = aarch64_get_mem_u64 (cpu, ptr);
  11752. /* Fill in the memory block. */
  11753. /* Start addr of heap. */
  11754. aarch64_set_mem_u64 (cpu, ptr + 0, heap_base);
  11755. /* End addr of heap. */
  11756. aarch64_set_mem_u64 (cpu, ptr + 8, stack_top);
  11757. /* Lowest stack addr. */
  11758. aarch64_set_mem_u64 (cpu, ptr + 16, heap_base);
  11759. /* Initial stack addr. */
  11760. aarch64_set_mem_u64 (cpu, ptr + 24, stack_top);
  11761. TRACE_SYSCALL (cpu, " AngelSVC: Get Heap Info");
  11762. }
  11763. break;
  11764. case AngelSVC_Reason_Open:
  11765. {
  11766. /* Get the pointer */
  11767. /* uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK);. */
  11768. /* FIXME: For now we just assume that we will only be asked
  11769. to open the standard file descriptors. */
  11770. static int fd = 0;
  11771. result = fd ++;
  11772. TRACE_SYSCALL (cpu, " AngelSVC: Open file %d", fd - 1);
  11773. }
  11774. break;
  11775. case AngelSVC_Reason_Close:
  11776. {
  11777. uint64_t fh = aarch64_get_reg_u64 (cpu, 1, SP_OK);
  11778. TRACE_SYSCALL (cpu, " AngelSVC: Close file %d", (int) fh);
  11779. result = 0;
  11780. }
  11781. break;
  11782. case AngelSVC_Reason_Errno:
  11783. result = 0;
  11784. TRACE_SYSCALL (cpu, " AngelSVC: Get Errno");
  11785. break;
  11786. case AngelSVC_Reason_Clock:
  11787. result =
  11788. #ifdef CLOCKS_PER_SEC
  11789. (CLOCKS_PER_SEC >= 100)
  11790. ? (clock () / (CLOCKS_PER_SEC / 100))
  11791. : ((clock () * 100) / CLOCKS_PER_SEC)
  11792. #else
  11793. /* Presume unix... clock() returns microseconds. */
  11794. (clock () / 10000)
  11795. #endif
  11796. ;
  11797. TRACE_SYSCALL (cpu, " AngelSVC: Get Clock");
  11798. break;
  11799. case AngelSVC_Reason_GetCmdLine:
  11800. {
  11801. /* Get the pointer */
  11802. uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK);
  11803. ptr = aarch64_get_mem_u64 (cpu, ptr);
  11804. /* FIXME: No command line for now. */
  11805. aarch64_set_mem_u64 (cpu, ptr, 0);
  11806. TRACE_SYSCALL (cpu, " AngelSVC: Get Command Line");
  11807. }
  11808. break;
  11809. case AngelSVC_Reason_IsTTY:
  11810. result = 1;
  11811. TRACE_SYSCALL (cpu, " AngelSVC: IsTTY ?");
  11812. break;
  11813. case AngelSVC_Reason_Write:
  11814. {
  11815. /* Get the pointer */
  11816. uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK);
  11817. /* Get the write control block. */
  11818. uint64_t fd = aarch64_get_mem_u64 (cpu, ptr);
  11819. uint64_t buf = aarch64_get_mem_u64 (cpu, ptr + 8);
  11820. uint64_t len = aarch64_get_mem_u64 (cpu, ptr + 16);
  11821. TRACE_SYSCALL (cpu, "write of %" PRIx64 " bytes from %"
  11822. PRIx64 " on descriptor %" PRIx64,
  11823. len, buf, fd);
  11824. if (len > 1280)
  11825. {
  11826. TRACE_SYSCALL (cpu,
  11827. " AngelSVC: Write: Suspiciously long write: %ld",
  11828. (long) len);
  11829. sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
  11830. sim_stopped, SIM_SIGBUS);
  11831. }
  11832. else if (fd == 1)
  11833. {
  11834. printf ("%.*s", (int) len, aarch64_get_mem_ptr (cpu, buf));
  11835. }
  11836. else if (fd == 2)
  11837. {
  11838. TRACE (cpu, 0, "\n");
  11839. sim_io_eprintf (CPU_STATE (cpu), "%.*s",
  11840. (int) len, aarch64_get_mem_ptr (cpu, buf));
  11841. TRACE (cpu, 0, "\n");
  11842. }
  11843. else
  11844. {
  11845. TRACE_SYSCALL (cpu,
  11846. " AngelSVC: Write: Unexpected file handle: %d",
  11847. (int) fd);
  11848. sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
  11849. sim_stopped, SIM_SIGABRT);
  11850. }
  11851. }
  11852. break;
  11853. case AngelSVC_Reason_ReportException:
  11854. {
  11855. /* Get the pointer */
  11856. uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK);
  11857. /*ptr = aarch64_get_mem_u64 (cpu, ptr);. */
  11858. uint64_t type = aarch64_get_mem_u64 (cpu, ptr);
  11859. uint64_t state = aarch64_get_mem_u64 (cpu, ptr + 8);
  11860. TRACE_SYSCALL (cpu,
  11861. "Angel Exception: type 0x%" PRIx64 " state %" PRIx64,
  11862. type, state);
  11863. if (type == 0x20026)
  11864. sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
  11865. sim_exited, state);
  11866. else
  11867. sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
  11868. sim_stopped, SIM_SIGINT);
  11869. }
  11870. break;
  11871. case AngelSVC_Reason_Read:
  11872. case AngelSVC_Reason_FLen:
  11873. case AngelSVC_Reason_Seek:
  11874. case AngelSVC_Reason_Remove:
  11875. case AngelSVC_Reason_Time:
  11876. case AngelSVC_Reason_System:
  11877. case AngelSVC_Reason_Rename:
  11878. case AngelSVC_Reason_Elapsed:
  11879. default:
  11880. TRACE_SYSCALL (cpu, " HLT [Unknown angel %x]",
  11881. aarch64_get_reg_u32 (cpu, 0, NO_SP));
  11882. sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
  11883. sim_stopped, SIM_SIGTRAP);
  11884. }
  11885. aarch64_set_reg_u64 (cpu, 0, NO_SP, result);
  11886. }
  11887. static void
  11888. dexExcpnGen (sim_cpu *cpu)
  11889. {
  11890. /* instr[31:24] = 11010100
  11891. instr[23,21] = opc : 000 ==> GEN EXCPN, 001 ==> BRK
  11892. 010 ==> HLT, 101 ==> DBG GEN EXCPN
  11893. instr[20,5] = imm16
  11894. instr[4,2] = opc2 000 ==> OK, ow ==> UNALLOC
  11895. instr[1,0] = LL : discriminates opc */
  11896. uint32_t opc = INSTR (23, 21);
  11897. uint32_t imm16 = INSTR (20, 5);
  11898. uint32_t opc2 = INSTR (4, 2);
  11899. uint32_t LL;
  11900. NYI_assert (31, 24, 0xd4);
  11901. if (opc2 != 0)
  11902. HALT_UNALLOC;
  11903. LL = INSTR (1, 0);
  11904. /* We only implement HLT and BRK for now. */
  11905. if (opc == 1 && LL == 0)
  11906. {
  11907. TRACE_EVENTS (cpu, " BRK [0x%x]", imm16);
  11908. sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
  11909. sim_exited, aarch64_get_reg_s32 (cpu, R0, SP_OK));
  11910. }
  11911. if (opc == 2 && LL == 0)
  11912. handle_halt (cpu, imm16);
  11913. else if (opc == 0 || opc == 5)
  11914. HALT_NYI;
  11915. else
  11916. HALT_UNALLOC;
  11917. }
  11918. /* Stub for accessing system registers. */
  11919. static uint64_t
  11920. system_get (sim_cpu *cpu, unsigned op0, unsigned op1, unsigned crn,
  11921. unsigned crm, unsigned op2)
  11922. {
  11923. if (crn == 0 && op1 == 3 && crm == 0 && op2 == 7)
  11924. /* DCZID_EL0 - the Data Cache Zero ID register.
  11925. We do not support DC ZVA at the moment, so
  11926. we return a value with the disable bit set.
  11927. We implement support for the DCZID register since
  11928. it is used by the C library's memset function. */
  11929. return ((uint64_t) 1) << 4;
  11930. if (crn == 0 && op1 == 3 && crm == 0 && op2 == 1)
  11931. /* Cache Type Register. */
  11932. return 0x80008000UL;
  11933. if (crn == 13 && op1 == 3 && crm == 0 && op2 == 2)
  11934. /* TPIDR_EL0 - thread pointer id. */
  11935. return aarch64_get_thread_id (cpu);
  11936. if (op1 == 3 && crm == 4 && op2 == 0)
  11937. return aarch64_get_FPCR (cpu);
  11938. if (op1 == 3 && crm == 4 && op2 == 1)
  11939. return aarch64_get_FPSR (cpu);
  11940. else if (op1 == 3 && crm == 2 && op2 == 0)
  11941. return aarch64_get_CPSR (cpu);
  11942. HALT_NYI;
  11943. }
  11944. static void
  11945. system_set (sim_cpu *cpu, unsigned op0, unsigned op1, unsigned crn,
  11946. unsigned crm, unsigned op2, uint64_t val)
  11947. {
  11948. if (op1 == 3 && crm == 4 && op2 == 0)
  11949. aarch64_set_FPCR (cpu, val);
  11950. else if (op1 == 3 && crm == 4 && op2 == 1)
  11951. aarch64_set_FPSR (cpu, val);
  11952. else if (op1 == 3 && crm == 2 && op2 == 0)
  11953. aarch64_set_CPSR (cpu, val);
  11954. else
  11955. HALT_NYI;
  11956. }
  11957. static void
  11958. do_mrs (sim_cpu *cpu)
  11959. {
  11960. /* instr[31:20] = 1101 0101 0001 1
  11961. instr[19] = op0
  11962. instr[18,16] = op1
  11963. instr[15,12] = CRn
  11964. instr[11,8] = CRm
  11965. instr[7,5] = op2
  11966. instr[4,0] = Rt */
  11967. unsigned sys_op0 = INSTR (19, 19) + 2;
  11968. unsigned sys_op1 = INSTR (18, 16);
  11969. unsigned sys_crn = INSTR (15, 12);
  11970. unsigned sys_crm = INSTR (11, 8);
  11971. unsigned sys_op2 = INSTR (7, 5);
  11972. unsigned rt = INSTR (4, 0);
  11973. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  11974. aarch64_set_reg_u64 (cpu, rt, NO_SP,
  11975. system_get (cpu, sys_op0, sys_op1, sys_crn, sys_crm, sys_op2));
  11976. }
  11977. static void
  11978. do_MSR_immediate (sim_cpu *cpu)
  11979. {
  11980. /* instr[31:19] = 1101 0101 0000 0
  11981. instr[18,16] = op1
  11982. instr[15,12] = 0100
  11983. instr[11,8] = CRm
  11984. instr[7,5] = op2
  11985. instr[4,0] = 1 1111 */
  11986. unsigned op1 = INSTR (18, 16);
  11987. /*unsigned crm = INSTR (11, 8);*/
  11988. unsigned op2 = INSTR (7, 5);
  11989. NYI_assert (31, 19, 0x1AA0);
  11990. NYI_assert (15, 12, 0x4);
  11991. NYI_assert (4, 0, 0x1F);
  11992. if (op1 == 0)
  11993. {
  11994. if (op2 == 5)
  11995. HALT_NYI; /* set SPSel. */
  11996. else
  11997. HALT_UNALLOC;
  11998. }
  11999. else if (op1 == 3)
  12000. {
  12001. if (op2 == 6)
  12002. HALT_NYI; /* set DAIFset. */
  12003. else if (op2 == 7)
  12004. HALT_NYI; /* set DAIFclr. */
  12005. else
  12006. HALT_UNALLOC;
  12007. }
  12008. else
  12009. HALT_UNALLOC;
  12010. }
  12011. static void
  12012. do_MSR_reg (sim_cpu *cpu)
  12013. {
  12014. /* instr[31:20] = 1101 0101 0001
  12015. instr[19] = op0
  12016. instr[18,16] = op1
  12017. instr[15,12] = CRn
  12018. instr[11,8] = CRm
  12019. instr[7,5] = op2
  12020. instr[4,0] = Rt */
  12021. unsigned sys_op0 = INSTR (19, 19) + 2;
  12022. unsigned sys_op1 = INSTR (18, 16);
  12023. unsigned sys_crn = INSTR (15, 12);
  12024. unsigned sys_crm = INSTR (11, 8);
  12025. unsigned sys_op2 = INSTR (7, 5);
  12026. unsigned rt = INSTR (4, 0);
  12027. NYI_assert (31, 20, 0xD51);
  12028. TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
  12029. system_set (cpu, sys_op0, sys_op1, sys_crn, sys_crm, sys_op2,
  12030. aarch64_get_reg_u64 (cpu, rt, NO_SP));
  12031. }
  12032. static void
  12033. do_SYS (sim_cpu *cpu)
  12034. {
  12035. /* instr[31,19] = 1101 0101 0000 1
  12036. instr[18,16] = op1
  12037. instr[15,12] = CRn
  12038. instr[11,8] = CRm
  12039. instr[7,5] = op2
  12040. instr[4,0] = Rt */
  12041. NYI_assert (31, 19, 0x1AA1);
  12042. /* FIXME: For now we just silently accept system ops. */
  12043. }
  12044. static void
  12045. dexSystem (sim_cpu *cpu)
  12046. {
  12047. /* instr[31:22] = 1101 01010 0
  12048. instr[21] = L
  12049. instr[20,19] = op0
  12050. instr[18,16] = op1
  12051. instr[15,12] = CRn
  12052. instr[11,8] = CRm
  12053. instr[7,5] = op2
  12054. instr[4,0] = uimm5 */
  12055. /* We are interested in HINT, DSB, DMB and ISB
  12056. Hint #0 encodes NOOP (this is the only hint we care about)
  12057. L == 0, op0 == 0, op1 = 011, CRn = 0010, Rt = 11111,
  12058. CRm op2 != 0000 000 OR CRm op2 == 0000 000 || CRm op > 0000 101
  12059. DSB, DMB, ISB are data store barrier, data memory barrier and
  12060. instruction store barrier, respectively, where
  12061. L == 0, op0 == 0, op1 = 011, CRn = 0011, Rt = 11111,
  12062. op2 : DSB ==> 100, DMB ==> 101, ISB ==> 110
  12063. CRm<3:2> ==> domain, CRm<1:0> ==> types,
  12064. domain : 00 ==> OuterShareable, 01 ==> Nonshareable,
  12065. 10 ==> InerShareable, 11 ==> FullSystem
  12066. types : 01 ==> Reads, 10 ==> Writes,
  12067. 11 ==> All, 00 ==> All (domain == FullSystem). */
  12068. unsigned rt = INSTR (4, 0);
  12069. NYI_assert (31, 22, 0x354);
  12070. switch (INSTR (21, 12))
  12071. {
  12072. case 0x032:
  12073. if (rt == 0x1F)
  12074. {
  12075. /* NOP has CRm != 0000 OR. */
  12076. /* (CRm == 0000 AND (op2 == 000 OR op2 > 101)). */
  12077. uint32_t crm = INSTR (11, 8);
  12078. uint32_t op2 = INSTR (7, 5);
  12079. if (crm != 0 || (op2 == 0 || op2 > 5))
  12080. {
  12081. /* Actually call nop method so we can reimplement it later. */
  12082. nop (cpu);
  12083. return;
  12084. }
  12085. }
  12086. HALT_NYI;
  12087. case 0x033:
  12088. {
  12089. uint32_t op2 = INSTR (7, 5);
  12090. switch (op2)
  12091. {
  12092. case 2: HALT_NYI;
  12093. case 4: dsb (cpu); return;
  12094. case 5: dmb (cpu); return;
  12095. case 6: isb (cpu); return;
  12096. default: HALT_UNALLOC;
  12097. }
  12098. }
  12099. case 0x3B0:
  12100. case 0x3B4:
  12101. case 0x3BD:
  12102. do_mrs (cpu);
  12103. return;
  12104. case 0x0B7:
  12105. do_SYS (cpu); /* DC is an alias of SYS. */
  12106. return;
  12107. default:
  12108. if (INSTR (21, 20) == 0x1)
  12109. do_MSR_reg (cpu);
  12110. else if (INSTR (21, 19) == 0 && INSTR (15, 12) == 0x4)
  12111. do_MSR_immediate (cpu);
  12112. else
  12113. HALT_NYI;
  12114. return;
  12115. }
  12116. }
  12117. static void
  12118. dexBr (sim_cpu *cpu)
  12119. {
  12120. /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu));
  12121. assert group == GROUP_BREXSYS_1010 || group == GROUP_BREXSYS_1011
  12122. bits [31,29] of a BrExSys are the secondary dispatch vector. */
  12123. uint32_t group2 = dispatchBrExSys (aarch64_get_instr (cpu));
  12124. switch (group2)
  12125. {
  12126. case BR_IMM_000:
  12127. return dexBranchImmediate (cpu);
  12128. case BR_IMMCMP_001:
  12129. /* Compare has bit 25 clear while test has it set. */
  12130. if (!INSTR (25, 25))
  12131. dexCompareBranchImmediate (cpu);
  12132. else
  12133. dexTestBranchImmediate (cpu);
  12134. return;
  12135. case BR_IMMCOND_010:
  12136. /* This is a conditional branch if bit 25 is clear otherwise
  12137. unallocated. */
  12138. if (!INSTR (25, 25))
  12139. dexCondBranchImmediate (cpu);
  12140. else
  12141. HALT_UNALLOC;
  12142. return;
  12143. case BR_UNALLOC_011:
  12144. HALT_UNALLOC;
  12145. case BR_IMM_100:
  12146. dexBranchImmediate (cpu);
  12147. return;
  12148. case BR_IMMCMP_101:
  12149. /* Compare has bit 25 clear while test has it set. */
  12150. if (!INSTR (25, 25))
  12151. dexCompareBranchImmediate (cpu);
  12152. else
  12153. dexTestBranchImmediate (cpu);
  12154. return;
  12155. case BR_REG_110:
  12156. /* Unconditional branch reg has bit 25 set. */
  12157. if (INSTR (25, 25))
  12158. dexBranchRegister (cpu);
  12159. /* This includes both Excpn Gen, System and unalloc operations.
  12160. We need to decode the Excpn Gen operation BRK so we can plant
  12161. debugger entry points.
  12162. Excpn Gen operations have instr [24] = 0.
  12163. we need to decode at least one of the System operations NOP
  12164. which is an alias for HINT #0.
  12165. System operations have instr [24,22] = 100. */
  12166. else if (INSTR (24, 24) == 0)
  12167. dexExcpnGen (cpu);
  12168. else if (INSTR (24, 22) == 4)
  12169. dexSystem (cpu);
  12170. else
  12171. HALT_UNALLOC;
  12172. return;
  12173. case BR_UNALLOC_111:
  12174. HALT_UNALLOC;
  12175. default:
  12176. /* Should never reach here. */
  12177. HALT_NYI;
  12178. }
  12179. }
  12180. static void
  12181. aarch64_decode_and_execute (sim_cpu *cpu, uint64_t pc)
  12182. {
  12183. /* We need to check if gdb wants an in here. */
  12184. /* checkBreak (cpu);. */
  12185. uint64_t group = dispatchGroup (aarch64_get_instr (cpu));
  12186. switch (group)
  12187. {
  12188. case GROUP_PSEUDO_0000: dexPseudo (cpu); break;
  12189. case GROUP_LDST_0100: dexLdSt (cpu); break;
  12190. case GROUP_DPREG_0101: dexDPReg (cpu); break;
  12191. case GROUP_LDST_0110: dexLdSt (cpu); break;
  12192. case GROUP_ADVSIMD_0111: dexAdvSIMD0 (cpu); break;
  12193. case GROUP_DPIMM_1000: dexDPImm (cpu); break;
  12194. case GROUP_DPIMM_1001: dexDPImm (cpu); break;
  12195. case GROUP_BREXSYS_1010: dexBr (cpu); break;
  12196. case GROUP_BREXSYS_1011: dexBr (cpu); break;
  12197. case GROUP_LDST_1100: dexLdSt (cpu); break;
  12198. case GROUP_DPREG_1101: dexDPReg (cpu); break;
  12199. case GROUP_LDST_1110: dexLdSt (cpu); break;
  12200. case GROUP_ADVSIMD_1111: dexAdvSIMD1 (cpu); break;
  12201. case GROUP_UNALLOC_0001:
  12202. case GROUP_UNALLOC_0010:
  12203. case GROUP_UNALLOC_0011:
  12204. HALT_UNALLOC;
  12205. default:
  12206. /* Should never reach here. */
  12207. HALT_NYI;
  12208. }
  12209. }
  12210. static bfd_boolean
  12211. aarch64_step (sim_cpu *cpu)
  12212. {
  12213. uint64_t pc = aarch64_get_PC (cpu);
  12214. if (pc == TOP_LEVEL_RETURN_PC)
  12215. return FALSE;
  12216. aarch64_set_next_PC (cpu, pc + 4);
  12217. /* Code is always little-endian. */
  12218. sim_core_read_buffer (CPU_STATE (cpu), cpu, read_map,
  12219. & aarch64_get_instr (cpu), pc, 4);
  12220. aarch64_get_instr (cpu) = endian_le2h_4 (aarch64_get_instr (cpu));
  12221. TRACE_INSN (cpu, " pc = %" PRIx64 " instr = %08x", pc,
  12222. aarch64_get_instr (cpu));
  12223. TRACE_DISASM (cpu, pc);
  12224. aarch64_decode_and_execute (cpu, pc);
  12225. return TRUE;
  12226. }
  12227. void
  12228. aarch64_run (SIM_DESC sd)
  12229. {
  12230. sim_cpu *cpu = STATE_CPU (sd, 0);
  12231. while (aarch64_step (cpu))
  12232. {
  12233. aarch64_update_PC (cpu);
  12234. if (sim_events_tick (sd))
  12235. sim_events_process (sd);
  12236. }
  12237. sim_engine_halt (sd, cpu, NULL, aarch64_get_PC (cpu),
  12238. sim_exited, aarch64_get_reg_s32 (cpu, R0, NO_SP));
  12239. }
  12240. void
  12241. aarch64_init (sim_cpu *cpu, uint64_t pc)
  12242. {
  12243. uint64_t sp = aarch64_get_stack_start (cpu);
  12244. /* Install SP, FP and PC and set LR to -20
  12245. so we can detect a top-level return. */
  12246. aarch64_set_reg_u64 (cpu, SP, SP_OK, sp);
  12247. aarch64_set_reg_u64 (cpu, FP, SP_OK, sp);
  12248. aarch64_set_reg_u64 (cpu, LR, SP_OK, TOP_LEVEL_RETURN_PC);
  12249. aarch64_set_next_PC (cpu, pc);
  12250. aarch64_update_PC (cpu);
  12251. aarch64_init_LIT_table ();
  12252. }