armdis.c 221 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243
  1. /*++
  2. Copyright (c) 2014 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. armdis.c
  9. Abstract:
  10. This module implements support for the ARM disassembler.
  11. Author:
  12. Evan Green 20-Mar-2014
  13. Environment:
  14. Debug
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include "dbgrtl.h"
  20. #include "disasm.h"
  21. #include "armdis.h"
  22. #include "thmdis.h"
  23. #include <string.h>
  24. #include <stdio.h>
  25. //
  26. // ---------------------------------------------------------------- Definitions
  27. //
  28. //
  29. // Define the bitmask of vector list printing flags.
  30. //
  31. #define DBG_ARM_VECTOR_LIST_FLAG_ALL_LANES 0x00000001
  32. #define DBG_ARM_VECTOR_LIST_FLAG_INDEX 0x00000002
  33. //
  34. // ------------------------------------------------------ Data Type Definitions
  35. //
  36. //
  37. // ----------------------------------------------- Internal Function Prototypes
  38. //
  39. VOID
  40. DbgpArmDecodeUnconditional (
  41. PARM_DISASSEMBLY Context
  42. );
  43. VOID
  44. DbgpArmDecodeDataProcessingAndMiscellaneous (
  45. PARM_DISASSEMBLY Context
  46. );
  47. VOID
  48. DbgpArmDecodeMediaInstruction (
  49. PARM_DISASSEMBLY Context
  50. );
  51. VOID
  52. DbgpArmDecodeBranchAndBlockTransfer (
  53. PARM_DISASSEMBLY Context
  54. );
  55. VOID
  56. DbgpArmDecodeCoprocessorSupervisor (
  57. PARM_DISASSEMBLY Context
  58. );
  59. VOID
  60. DbgpArmDecodeMemoryHintSimdMisc (
  61. PARM_DISASSEMBLY Context
  62. );
  63. VOID
  64. DbgpArmDecodeStoreReturnState (
  65. PARM_DISASSEMBLY Context
  66. );
  67. VOID
  68. DbgpArmDecodeReturnFromException (
  69. PARM_DISASSEMBLY Context
  70. );
  71. VOID
  72. DbgpArmDecodeBranch (
  73. PARM_DISASSEMBLY Context
  74. );
  75. VOID
  76. DbgpArmDecodeUndefined (
  77. PARM_DISASSEMBLY Context
  78. );
  79. VOID
  80. DbgpArmDecodeUnpredictable (
  81. PARM_DISASSEMBLY Context
  82. );
  83. VOID
  84. DbgpArmDecodeNop (
  85. PARM_DISASSEMBLY Context
  86. );
  87. VOID
  88. DbgpArmDecodeChangeProcessorState (
  89. PARM_DISASSEMBLY Context
  90. );
  91. VOID
  92. DbgpArmDecodeSetEndianness (
  93. PARM_DISASSEMBLY Context
  94. );
  95. VOID
  96. DbgpArmDecodePreloadInstruction (
  97. PARM_DISASSEMBLY Context
  98. );
  99. VOID
  100. DbgpArmDecodeClearExclusive (
  101. PARM_DISASSEMBLY Context
  102. );
  103. VOID
  104. DbgpArmDecodeDataSynchronizationBarrier (
  105. PARM_DISASSEMBLY Context
  106. );
  107. VOID
  108. DbgpArmDecodeDataMemoryBarrier (
  109. PARM_DISASSEMBLY Context
  110. );
  111. VOID
  112. DbgpArmDecodeInstructionSynchronizationBarrier (
  113. PARM_DISASSEMBLY Context
  114. );
  115. VOID
  116. DbgpArmDecodeParallelAdditionSubtraction (
  117. PARM_DISASSEMBLY Context
  118. );
  119. VOID
  120. DbgpArmDecodePackingInstructions (
  121. PARM_DISASSEMBLY Context
  122. );
  123. VOID
  124. DbgpArmDecodeExtensionWithRotation (
  125. PARM_DISASSEMBLY Context
  126. );
  127. VOID
  128. DbgpArmDecodeSelectBytes (
  129. PARM_DISASSEMBLY Context
  130. );
  131. VOID
  132. DbgpArmDecodePackHalfword (
  133. PARM_DISASSEMBLY Context
  134. );
  135. VOID
  136. DbgpArmDecodeReverse (
  137. PARM_DISASSEMBLY Context
  138. );
  139. VOID
  140. DbgpArmDecodeSaturate (
  141. PARM_DISASSEMBLY Context
  142. );
  143. VOID
  144. DbgpArmDecodeSumofAbsoluteDifferences (
  145. PARM_DISASSEMBLY Context
  146. );
  147. VOID
  148. DbgpArmDecodeBitFieldInstructions (
  149. PARM_DISASSEMBLY Context
  150. );
  151. VOID
  152. DbgpArmDecodePermanentlyUndefined (
  153. PARM_DISASSEMBLY Context
  154. );
  155. VOID
  156. DbgpArmDecodeLoadStore (
  157. PARM_DISASSEMBLY Context
  158. );
  159. VOID
  160. DbgpArmDecodeExtraLoadStore (
  161. PARM_DISASSEMBLY Context
  162. );
  163. VOID
  164. DbgpArmDecodeLoadStoreMultiple (
  165. PARM_DISASSEMBLY Context
  166. );
  167. VOID
  168. DbgpArmDecodeDataProcessing (
  169. PARM_DISASSEMBLY Context
  170. );
  171. VOID
  172. DbgpArmDecodeLoadImmediate (
  173. PARM_DISASSEMBLY Context
  174. );
  175. VOID
  176. DbgpArmDecodeMiscellaneous (
  177. PARM_DISASSEMBLY Context
  178. );
  179. VOID
  180. DbgpArmDecodeMsrImmediateAndHints (
  181. PARM_DISASSEMBLY Context
  182. );
  183. VOID
  184. DbgpArmDecodeMultiply (
  185. PARM_DISASSEMBLY Context
  186. );
  187. VOID
  188. DbgpArmDecodeSynchronization (
  189. PARM_DISASSEMBLY Context
  190. );
  191. VOID
  192. DbgpArmDecodeSupervisorCall (
  193. PARM_DISASSEMBLY Context
  194. );
  195. VOID
  196. DbgpArmDecodeFloatingPointTwoRegisters (
  197. PARM_DISASSEMBLY Context
  198. );
  199. VOID
  200. DbgpArmDecodeFloatingPointThreeRegisters (
  201. PARM_DISASSEMBLY Context
  202. );
  203. VOID
  204. DbgpArmDecodeFloatingPointVectorConvert (
  205. PARM_DISASSEMBLY Context
  206. );
  207. VOID
  208. DbgpArmDecodeFloatingPointVectorCompare (
  209. PARM_DISASSEMBLY Context
  210. );
  211. VOID
  212. DbgpArmDecodeSimdSmallMove (
  213. PARM_DISASSEMBLY Context
  214. );
  215. VOID
  216. DbgpArmDecodeSimdSpecialMove (
  217. PARM_DISASSEMBLY Context
  218. );
  219. VOID
  220. DbgpArmDecodeSimdDuplicate (
  221. PARM_DISASSEMBLY Context
  222. );
  223. VOID
  224. DbgpArmDecodeSimdLoadStoreRegister (
  225. PARM_DISASSEMBLY Context
  226. );
  227. VOID
  228. DbgpArmDecodeSimdLoadStoreMultiple (
  229. PARM_DISASSEMBLY Context
  230. );
  231. VOID
  232. DbgpArmDecodeSimdElementLoadAllLanes (
  233. PARM_DISASSEMBLY Context
  234. );
  235. VOID
  236. DbgpArmDecodeSimdElementLoadStoreSingle (
  237. PARM_DISASSEMBLY Context
  238. );
  239. VOID
  240. DbgpArmDecodeSimdElementLoadStoreMultiple (
  241. PARM_DISASSEMBLY Context
  242. );
  243. VOID
  244. DbgpArmDecodeSimdThreeRegistersSameLength (
  245. PARM_DISASSEMBLY Context
  246. );
  247. VOID
  248. DbgpArmDecodeSimdOneRegister (
  249. PARM_DISASSEMBLY Context
  250. );
  251. VOID
  252. DbgpArmDecodeSimdTwoRegistersWithShift (
  253. PARM_DISASSEMBLY Context
  254. );
  255. VOID
  256. DbgpArmDecodeSimdThreeRegistersDifferentLength (
  257. PARM_DISASSEMBLY Context
  258. );
  259. VOID
  260. DbgpArmDecodeSimdTwoRegistersWithScalar (
  261. PARM_DISASSEMBLY Context
  262. );
  263. VOID
  264. DbgpArmDecodeSimdTwoRegistersMiscellaneous (
  265. PARM_DISASSEMBLY Context
  266. );
  267. VOID
  268. DbgpArmDecodeSimdVectorExtract (
  269. PARM_DISASSEMBLY Context
  270. );
  271. VOID
  272. DbgpArmDecodeSimdVectorTableLookup (
  273. PARM_DISASSEMBLY Context
  274. );
  275. VOID
  276. DbgpArmDecodeSimdVectorDuplicate (
  277. PARM_DISASSEMBLY Context
  278. );
  279. PSTR
  280. DbgpArmGetLoadStoreTypeString (
  281. ULONG Instruction
  282. );
  283. PSTR
  284. DbgpArmGetBankedRegisterString (
  285. ULONG Instruction
  286. );
  287. VOID
  288. DbgpArmPrintStatusRegister (
  289. PSTR Operand,
  290. ULONG Instruction
  291. );
  292. VOID
  293. DbgpArmPrintVectorList (
  294. PSTR Destination,
  295. ULONG DestinationSize,
  296. ULONG VectorStart,
  297. ULONG VectorCount,
  298. ULONG VectorIncrement,
  299. PSTR VectorTypeString,
  300. ULONG VectorIndex,
  301. ULONG Flags
  302. );
  303. VOID
  304. DbgpArmDecodeImmediateShift (
  305. PSTR Destination,
  306. ULONG DestinationSize,
  307. ULONG Register,
  308. ULONG Type,
  309. ULONG Immediate
  310. );
  311. //
  312. // -------------------------------------------------------------------- Globals
  313. //
  314. //
  315. // Define decode tables.
  316. //
  317. ARM_DECODE_BRANCH DbgArmTopLevelTable[] = {
  318. {0xF0000000, 0xF0000000, 0, DbgpArmDecodeUnconditional},
  319. {0x0C000000, 0x00000000, 0, DbgpArmDecodeDataProcessingAndMiscellaneous},
  320. {0x0E000010, 0x06000010, 0, DbgpArmDecodeMediaInstruction},
  321. {0x0C000000, 0x04000000, 0, DbgpArmDecodeLoadStore},
  322. {0x0C000000, 0x08000000, 0, DbgpArmDecodeBranchAndBlockTransfer},
  323. {0x0C000000, 0x0C000000, 0, DbgpArmDecodeCoprocessorSupervisor},
  324. };
  325. ARM_DECODE_BRANCH DbgArmUnconditionalTable[] = {
  326. {0x08000000, 0x00000000, 0, DbgpArmDecodeMemoryHintSimdMisc},
  327. {0x0E500000, 0x08400000, 0, DbgpArmDecodeStoreReturnState},
  328. {0x0E500000, 0x08100000, 0, DbgpArmDecodeReturnFromException},
  329. {0x0E000000, 0x0A000000, 0, DbgpArmDecodeBranch},
  330. {0x0F000010, 0x0E000000, 0, DbgpArmDecodeCoprocessorMove},
  331. {0x000000E0, 0x000000A0, 0, DbgpArmDecodeUndefined},
  332. {0x0FE00000, 0x0C400000, 0, DbgpArmDecodeCoprocessorMoveTwo},
  333. {0x0FA00000, 0x0C000000, 0, DbgpArmDecodeUndefined},
  334. {0x0E000000, 0x0C000000, 0, DbgpArmDecodeCoprocessorLoadStore},
  335. {0x0F100010, 0x0E000010, 0, DbgpArmDecodeCoprocessorMove},
  336. {0x0F100010, 0x0E100010, 0, DbgpArmDecodeCoprocessorMove},
  337. };
  338. ARM_DECODE_BRANCH DbgArmMemoryHintSimdMiscTable[] = {
  339. {0x07F10020, 0x01000000, 0, DbgpArmDecodeChangeProcessorState},
  340. {0x07F100F0, 0x01010000, 0, DbgpArmDecodeSetEndianness},
  341. {0x06000000, 0x02000000, 0, DbgpArmDecodeSimdDataProcessing},
  342. {0x07100000, 0x04000000, 0, DbgpArmDecodeSimdElementLoadStore},
  343. {0x07700000, 0x04100000, 0, DbgpArmDecodeNop},
  344. {0x07700000, 0x04500000, 0, DbgpArmDecodePreloadInstruction},
  345. {0x07300000, 0x04300000, 0, DbgpArmDecodeUnpredictable},
  346. {0x077F0000, 0x051F0000, 0, DbgpArmDecodeUnpredictable},
  347. {0x07300000, 0x05100000, 0, DbgpArmDecodePreloadInstruction},
  348. {0x07F00000, 0x05300000, 0, DbgpArmDecodeUnpredictable},
  349. {0x07F000F0, 0x05700000, 0, DbgpArmDecodeUnpredictable},
  350. {0x07F000E0, 0x05700020, 0, DbgpArmDecodeUnpredictable},
  351. {0x07F000F0, 0x05700070, 0, DbgpArmDecodeUnpredictable},
  352. {0x07F00080, 0x05700080, 0, DbgpArmDecodeUnpredictable},
  353. {0x07F000F0, 0x05700010, 0, DbgpArmDecodeClearExclusive},
  354. {0x07F000F0, 0x05700040, 0, DbgpArmDecodeDataSynchronizationBarrier},
  355. {0x07F000F0, 0x05700050, 0, DbgpArmDecodeDataMemoryBarrier},
  356. {0x07F000F0, 0x05700060, 0, DbgpArmDecodeInstructionSynchronizationBarrier},
  357. {0x07B00000, 0x05B00000, 0, DbgpArmDecodeUnpredictable},
  358. {0x07700010, 0x06100000, 0, DbgpArmDecodeNop},
  359. {0x07700010, 0x06500000, 0, DbgpArmDecodePreloadInstruction},
  360. {0x07300010, 0x07100000, 0, DbgpArmDecodePreloadInstruction},
  361. {0x06300010, 0x06300000, 0, DbgpArmDecodeUnpredictable},
  362. {0x07F000F0, 0x07F000F0, 0, DbgpArmDecodeUndefined},
  363. };
  364. ARM_DECODE_BRANCH DbgArmSimdDataProcessingTable[] = {
  365. {0x00800000, 0x00000000, 0, DbgpArmDecodeSimdThreeRegistersSameLength},
  366. {0x00B80090, 0x00800010, 0, DbgpArmDecodeSimdOneRegister},
  367. {0x00800010, 0x00800010, 0, DbgpArmDecodeSimdTwoRegistersWithShift},
  368. {0x00A00050, 0x00800000, 0, DbgpArmDecodeSimdThreeRegistersDifferentLength},
  369. {0x00B00050, 0x00A00000, 0, DbgpArmDecodeSimdThreeRegistersDifferentLength},
  370. {0x00A00050, 0x00800040, 0, DbgpArmDecodeSimdTwoRegistersWithScalar},
  371. {0x00B00050, 0x00A00040, 0, DbgpArmDecodeSimdTwoRegistersWithScalar},
  372. {0x01B00010, 0x00B00000, 0, DbgpArmDecodeSimdVectorExtract},
  373. {0x01B00810, 0x01B00000, 0, DbgpArmDecodeSimdTwoRegistersMiscellaneous},
  374. {0x01B00C10, 0x01B00800, 0, DbgpArmDecodeSimdVectorTableLookup},
  375. {0x01B00F90, 0x01B00C00, 0, DbgpArmDecodeSimdVectorDuplicate},
  376. };
  377. ARM_DECODE_BRANCH DbgArmSimdElementLoadStoreTable[] = {
  378. {0x00A00C00, 0x00A00C00, 0, DbgpArmDecodeSimdElementLoadAllLanes},
  379. {0x00800000, 0x00800000, 0, DbgpArmDecodeSimdElementLoadStoreSingle},
  380. {0x00800000, 0x00000000, 0, DbgpArmDecodeSimdElementLoadStoreMultiple},
  381. };
  382. ARM_DECODE_BRANCH DbgArmDataProcessingAndMiscellaneousTable[] = {
  383. {0x03900080, 0x01000000, 0, DbgpArmDecodeMiscellaneous},
  384. {0x03900090, 0x01000080, 0, DbgpArmDecodeMultiply},
  385. {0x02000010, 0x00000000, 0, DbgpArmDecodeDataProcessing},
  386. {0x02000090, 0x00000010, 0, DbgpArmDecodeDataProcessing},
  387. {0x030000F0, 0x00000090, 0, DbgpArmDecodeMultiply},
  388. {0x030000F0, 0x01000090, 0, DbgpArmDecodeSynchronization},
  389. {0x032000F0, 0x002000B0, 0, DbgpArmDecodeExtraLoadStore},
  390. {0x032000D0, 0x002000D0, 0, DbgpArmDecodeExtraLoadStore},
  391. {0x020000F0, 0x000000B0, 0, DbgpArmDecodeExtraLoadStore},
  392. {0x020000D0, 0x000000D0, 0, DbgpArmDecodeExtraLoadStore},
  393. {0x03F00000, 0x03000000, 0, DbgpArmDecodeLoadImmediate},
  394. {0x03F00000, 0x03400000, 0, DbgpArmDecodeLoadImmediate},
  395. {0x03B00000, 0x03200000, 0, DbgpArmDecodeMsrImmediateAndHints},
  396. {0x02000000, 0x02000000, 0, DbgpArmDecodeDataProcessing},
  397. };
  398. ARM_DECODE_BRANCH DbgArmMediaInstructionTable[] = {
  399. {0x01800000, 0x00000000, 0, DbgpArmDecodeParallelAdditionSubtraction},
  400. {0x01800000, 0x00800000, 0, DbgpArmDecodePackingInstructions},
  401. {0x01800000, 0x01000000, 0, DbgpArmDecodeMultiply},
  402. {0x01F000E0, 0x01800000, 0, DbgpArmDecodeSumofAbsoluteDifferences},
  403. {0x01A00060, 0x01A00040, 0, DbgpArmDecodeBitFieldInstructions},
  404. {0x01E00060, 0x01C00000, 0, DbgpArmDecodeBitFieldInstructions},
  405. {0xF1F000E0, 0xE1F000E0, 0, DbgpArmDecodePermanentlyUndefined},
  406. };
  407. ARM_DECODE_BRANCH DbgArmPackingInstructionTable[] = {
  408. {0x000000E0, 0x00000060, 0, DbgpArmDecodeExtensionWithRotation},
  409. {0x007000E0, 0x000000A0, 0, DbgpArmDecodeSelectBytes},
  410. {0x00700020, 0x00000000, 0, DbgpArmDecodePackHalfword},
  411. {0x00300060, 0x00300020, 0, DbgpArmDecodeReverse},
  412. {0x003000E0, 0x00200020, 0, DbgpArmDecodeSaturate},
  413. {0x00200020, 0x00200000, 0, DbgpArmDecodeSaturate}
  414. };
  415. ARM_DECODE_BRANCH DbgArmBranchAndBlockTransferTable[] = {
  416. {0x02000000, 0x02000000, 0, DbgpArmDecodeBranch},
  417. {0x02000000, 0x00000000, 0, DbgpArmDecodeLoadStoreMultiple},
  418. };
  419. ARM_DECODE_BRANCH DbgArmCoprocessorSupervisorTable[] = {
  420. {0x03E00000, 0x00000000, 0, DbgpArmDecodeUndefined},
  421. {0x03000000, 0x03000000, 0, DbgpArmDecodeSupervisorCall},
  422. {0x03E00E00, 0x00400A00, 0, DbgpArmDecodeSimd64BitTransfers},
  423. {0x02000E00, 0x00000A00, 0, DbgpArmDecodeSimdLoadStore},
  424. {0x03000E10, 0x02000A00, 0, DbgpArmDecodeFloatingPoint},
  425. {0x03000E10, 0x02000A10, 0, DbgpArmDecodeSimdSmallTransfers},
  426. {0x03E00000, 0x00400000, 0, DbgpArmDecodeCoprocessorMoveTwo},
  427. {0x02000000, 0x00000000, 0, DbgpArmDecodeCoprocessorLoadStore},
  428. {0x03000000, 0x02000000, 0, DbgpArmDecodeCoprocessorMove},
  429. };
  430. ARM_DECODE_BRANCH DbgArmFloatingPointTable[] = {
  431. {0x00B00040, 0x00B00000, 0, DbgpArmDecodeFloatingPointTwoRegisters},
  432. {0x00BE0040, 0x00B00040, 0, DbgpArmDecodeFloatingPointTwoRegisters},
  433. {0x00BE0040, 0x00B20040, 0, DbgpArmDecodeFloatingPointVectorConvert},
  434. {0x00BE0040, 0x00B40040, 0, DbgpArmDecodeFloatingPointVectorCompare},
  435. {0x00BF00C0, 0x00B700C0, 0, DbgpArmDecodeFloatingPointVectorConvert},
  436. {0x00BF0040, 0x00B80040, 0, DbgpArmDecodeFloatingPointVectorConvert},
  437. {0x00BE0040, 0x00BA0040, 0, DbgpArmDecodeFloatingPointVectorConvert},
  438. {0x00BE0040, 0x00BC0040, 0, DbgpArmDecodeFloatingPointVectorConvert},
  439. {0x00BE0040, 0x00BE0040, 0, DbgpArmDecodeFloatingPointVectorConvert},
  440. {0x00B00000, 0x00B00000, 0, DbgpArmDecodeUndefined},
  441. {0x00B00040, 0x00800040, 0, DbgpArmDecodeUndefined},
  442. {0x00000000, 0x00000000, 0, DbgpArmDecodeFloatingPointThreeRegisters},
  443. };
  444. ARM_DECODE_BRANCH DbgArmSimdSmallTransferTable[] = {
  445. {0x00F00100, 0x00000000, 0, DbgpArmDecodeSimdSmallMove},
  446. {0x00F00100, 0x00E00000, 0, DbgpArmDecodeSimdSpecialMove},
  447. {0x00900100, 0x00000100, 0, DbgpArmDecodeSimdSmallMove},
  448. {0x00900140, 0x00800100, 0, DbgpArmDecodeSimdDuplicate},
  449. {0x00F00100, 0x00100000, 0, DbgpArmDecodeSimdSmallMove},
  450. {0x00F00100, 0x00F00000, 0, DbgpArmDecodeSimdSpecialMove},
  451. {0x00100100, 0x00100100, 0, DbgpArmDecodeSimdSmallMove},
  452. };
  453. ARM_DECODE_BRANCH DbgArmSimdLoadStoreTable[] = {
  454. {0x01200000, 0x01000000, 0, DbgpArmDecodeSimdLoadStoreRegister},
  455. {0x01800000, 0x00800000, 0, DbgpArmDecodeSimdLoadStoreMultiple},
  456. {0x01800000, 0x01000000, 0, DbgpArmDecodeSimdLoadStoreMultiple},
  457. };
  458. PSTR DbgArmRegisterNames[] = {
  459. "r0",
  460. "r1",
  461. "r2",
  462. "r3",
  463. "r4",
  464. "r5",
  465. "r6",
  466. "r7",
  467. "r8",
  468. "r9",
  469. "r10",
  470. "fp",
  471. "ip",
  472. "sp",
  473. "lr",
  474. "pc",
  475. "f0"
  476. "f1",
  477. "f2",
  478. "f3",
  479. "f4",
  480. "f5",
  481. "f6",
  482. "f7",
  483. "fps",
  484. "cpsr"
  485. };
  486. PSTR DbgArmSpecialRegisterNames[16] = {
  487. "fpsid",
  488. "fpscr",
  489. "<arch>",
  490. "<arch>",
  491. "<arch>",
  492. "<arch>",
  493. "mvfr1",
  494. "mvfr0",
  495. "fpexc",
  496. "fpinst",
  497. "fpinst2",
  498. "<arch>",
  499. "<arch>",
  500. "<arch>",
  501. "<arch>",
  502. "<arch>",
  503. };
  504. PSTR DbgArmConditionCodes[16] = {
  505. "eq",
  506. "ne",
  507. "cs",
  508. "cc",
  509. "mi",
  510. "pl",
  511. "vs",
  512. "vc",
  513. "hi",
  514. "ls",
  515. "ge",
  516. "lt",
  517. "gt",
  518. "le",
  519. "",
  520. "",
  521. };
  522. PSTR DbgArmDataProcessingMnemonics[16] = {
  523. "and",
  524. "eor",
  525. "sub",
  526. "rsb",
  527. "add",
  528. "adc",
  529. "sbc",
  530. "rsc",
  531. "tst",
  532. "teq",
  533. "cmp",
  534. "cmn",
  535. "orr",
  536. "mov",
  537. "bic",
  538. "mvn"
  539. };
  540. PSTR DbgArmSynchronizationMnemonics[8] = {
  541. "strex",
  542. "ldrex",
  543. "strexd",
  544. "ldrexd",
  545. "strexb",
  546. "ldrexb",
  547. "strexh",
  548. "ldrexh"
  549. };
  550. PSTR DbgArmBankedRegisters[64] = {
  551. "r8_usr",
  552. "r9_usr",
  553. "r10_usr",
  554. "r11_usr",
  555. "r12_usr",
  556. "sp_usr",
  557. "lr_usr",
  558. "UNPREDICTABLE",
  559. "r8_fiq",
  560. "r9_fiq",
  561. "r10_fiq",
  562. "r11_fiq",
  563. "r12_fiq",
  564. "sp_fiq",
  565. "lr_fiq",
  566. "UNPREDICTABLE",
  567. "lr_irq",
  568. "sp_irq",
  569. "lr_svc",
  570. "sp_svc",
  571. "lr_abr",
  572. "sp_abt",
  573. "lr_und",
  574. "sp_und",
  575. "UNPREDICTABLE",
  576. "UNPREDICTABLE",
  577. "UNPREDICTABLE",
  578. "UNPREDICTABLE",
  579. "lr_mon",
  580. "sp_mon",
  581. "elr_hyp",
  582. "sp_hyp",
  583. "UNPREDICTABLE",
  584. "UNPREDICTABLE",
  585. "UNPREDICTABLE",
  586. "UNPREDICTABLE",
  587. "UNPREDICTABLE",
  588. "UNPREDICTABLE",
  589. "UNPREDICTABLE",
  590. "UNPREDICTABLE",
  591. "UNPREDICTABLE",
  592. "UNPREDICTABLE",
  593. "UNPREDICTABLE",
  594. "UNPREDICTABLE",
  595. "UNPREDICTABLE",
  596. "UNPREDICTABLE",
  597. "spsr_fiq",
  598. "UNPREDICTABLE",
  599. "spsr_irq",
  600. "UNPREDICTABLE",
  601. "spsr_svc",
  602. "UNPREDICTABLE",
  603. "spsr_abt",
  604. "UNPREDICTABLE",
  605. "spsr_und",
  606. "UNPREDICTABLE",
  607. "UNPREDICTABLE",
  608. "UNPREDICTABLE",
  609. "UNPREDICTABLE",
  610. "UNPREDICTABLE",
  611. "spsr_mon",
  612. "spsr_hyp"
  613. };
  614. PSTR DbgArmParallelArithmeticMnemonics[2][24] = {
  615. {
  616. "sadd16",
  617. "sasx",
  618. "ssax",
  619. "ssub16",
  620. "sadd8",
  621. NULL,
  622. NULL,
  623. "ssub8",
  624. "qadd16",
  625. "qasx",
  626. "qsax",
  627. "qsub16",
  628. "qadd8",
  629. NULL,
  630. NULL,
  631. "qsub8",
  632. "shadd16",
  633. "shasx",
  634. "shsax",
  635. "shsub16",
  636. "shadd8",
  637. NULL,
  638. NULL,
  639. "shsub8"
  640. },
  641. {
  642. "uadd16",
  643. "uasx",
  644. "usax",
  645. "usub16",
  646. "uadd8",
  647. NULL,
  648. NULL,
  649. "usub8",
  650. "uqadd16",
  651. "uqasx"
  652. "uqsax"
  653. "uqsub16",
  654. "uqadd8",
  655. NULL,
  656. NULL,
  657. "uqsub8",
  658. "uhadd16",
  659. "uhasx",
  660. "uhsax",
  661. "uhsub16",
  662. "uhadd8",
  663. NULL,
  664. NULL,
  665. "uhsub8"
  666. }
  667. };
  668. PSTR DbgArmExtensionRotationMnemonics[2][8] = {
  669. {
  670. "sxtab16",
  671. NULL,
  672. "sxtab",
  673. "sxtah",
  674. "uxtab16",
  675. NULL,
  676. "uxtab",
  677. "uxtah"
  678. },
  679. {
  680. "sxtb16",
  681. NULL,
  682. "sxtb",
  683. "sxth",
  684. "uxtb16",
  685. NULL,
  686. "uxtb",
  687. "uxth"
  688. }
  689. };
  690. PSTR DbgArmReverseMnemonics[4] = {
  691. "rev",
  692. "rbit",
  693. "rev16",
  694. "revsh"
  695. };
  696. PSTR DbgArmSimdElementLoadStoreMultipleElementSuffix[] = {
  697. ARM_SIMD_ELEMENT_LOAD_STORE_4_ELEMENT_SUFFIX,
  698. ARM_SIMD_ELEMENT_LOAD_STORE_4_ELEMENT_SUFFIX,
  699. ARM_SIMD_ELEMENT_LOAD_STORE_1_ELEMENT_SUFFIX,
  700. ARM_SIMD_ELEMENT_LOAD_STORE_2_ELEMENT_SUFFIX,
  701. ARM_SIMD_ELEMENT_LOAD_STORE_3_ELEMENT_SUFFIX,
  702. ARM_SIMD_ELEMENT_LOAD_STORE_3_ELEMENT_SUFFIX,
  703. ARM_SIMD_ELEMENT_LOAD_STORE_1_ELEMENT_SUFFIX,
  704. ARM_SIMD_ELEMENT_LOAD_STORE_1_ELEMENT_SUFFIX,
  705. ARM_SIMD_ELEMENT_LOAD_STORE_2_ELEMENT_SUFFIX,
  706. ARM_SIMD_ELEMENT_LOAD_STORE_2_ELEMENT_SUFFIX,
  707. ARM_SIMD_ELEMENT_LOAD_STORE_1_ELEMENT_SUFFIX
  708. };
  709. ULONG DbgArmSimdElementLoadStoreMultipleVectorCount[] = {
  710. 4, 4, 4, 4, 3, 3, 1, 2, 2, 2
  711. };
  712. //
  713. // ------------------------------------------------------------------ Functions
  714. //
  715. BOOL
  716. DbgpArmDisassemble (
  717. ULONGLONG InstructionPointer,
  718. PBYTE InstructionStream,
  719. PSTR Buffer,
  720. ULONG BufferLength,
  721. PDISASSEMBLED_INSTRUCTION Disassembly,
  722. MACHINE_LANGUAGE Language
  723. )
  724. /*++
  725. Routine Description:
  726. This routine decodes one instruction from an ARM binary instruction
  727. stream into a human readable form.
  728. Arguments:
  729. InstructionPointer - Supplies the instruction pointer for the start of the
  730. instruction stream.
  731. InstructionStream - Supplies a pointer to the binary instruction stream.
  732. Buffer - Supplies a pointer to the buffer where the human
  733. readable strings will be printed. This buffer must be allocated by the
  734. caller.
  735. BufferLength - Supplies the length of the supplied buffer.
  736. Disassembly - Supplies a pointer to the structure that will receive
  737. information about the instruction.
  738. Language - Supplies the machine language to interpret this stream as.
  739. Return Value:
  740. TRUE on success.
  741. FALSE if the instruction was unknown.
  742. --*/
  743. {
  744. ULONG ConditionCode;
  745. ARM_DISASSEMBLY Context;
  746. BOOL Decoded;
  747. BOOL Result;
  748. RtlZeroMemory(Disassembly, sizeof(DISASSEMBLED_INSTRUCTION));
  749. if (BufferLength < ARM_INSTRUCTION_SIZE) {
  750. Result = FALSE;
  751. goto ArmDisassembleEnd;
  752. }
  753. RtlZeroMemory(&Context, sizeof(ARM_DISASSEMBLY));
  754. Context.Result = Disassembly;
  755. Context.InstructionPointer = InstructionPointer;
  756. //
  757. // Get the instruction word. Always take the max, four bytes, even if the
  758. // instruction might only end up being two.
  759. //
  760. Context.Instruction = *((PULONG)InstructionStream);
  761. //
  762. // If this is Thumb, then just call the thumb decode function and skip the
  763. // rest of this.
  764. //
  765. if (Language == MachineLanguageThumb2) {
  766. DbgpThumbDecode(&Context);
  767. Result = TRUE;
  768. goto ArmDisassembleEnd;
  769. }
  770. //
  771. // Use the ARM tables to decode the instruction.
  772. //
  773. ASSERT(Language == MachineLanguageArm);
  774. strcpy(Context.Mnemonic, "Unknown");
  775. Decoded = ARM_DECODE_WITH_TABLE(&Context, DbgArmTopLevelTable);
  776. if (Decoded != FALSE) {
  777. ConditionCode = Context.Instruction >> ARM_CONDITION_SHIFT;
  778. strcat(Context.Mnemonic, DbgArmConditionCodes[ConditionCode]);
  779. }
  780. Result = TRUE;
  781. Disassembly->BinaryLength = 4;
  782. ArmDisassembleEnd:
  783. if ((strlen(Context.Mnemonic) +
  784. strlen(Context.PostConditionMnemonicSuffix) +
  785. strlen(Context.Operand1) +
  786. strlen(Context.Operand2) +
  787. strlen(Context.Operand3) +
  788. strlen(Context.Operand4) + 5) > BufferLength) {
  789. Result = FALSE;
  790. }
  791. if (Result != FALSE) {
  792. strcat(Context.Mnemonic, Context.PostConditionMnemonicSuffix);
  793. strcpy(Buffer, Context.Mnemonic);
  794. Disassembly->Mnemonic = Buffer;
  795. Buffer += strlen(Context.Mnemonic) + 1;
  796. BufferLength -= strlen(Context.Mnemonic) + 1;
  797. if (*(Context.Operand1) != '\0') {
  798. strcpy(Buffer, Context.Operand1);
  799. Disassembly->DestinationOperand = Buffer;
  800. Buffer += strlen(Context.Operand1) + 1;
  801. BufferLength -= strlen(Context.Operand1) + 1;
  802. }
  803. if (*(Context.Operand2) != '\0') {
  804. strcpy(Buffer, Context.Operand2);
  805. Disassembly->SourceOperand = Buffer;
  806. Buffer += strlen(Context.Operand2) + 1;
  807. BufferLength -= strlen(Context.Operand2) + 1;
  808. }
  809. if (*(Context.Operand3) != '\0') {
  810. strcpy(Buffer, Context.Operand3);
  811. Disassembly->ThirdOperand = Buffer;
  812. Buffer += strlen(Context.Operand3) + 1;
  813. BufferLength -= strlen(Context.Operand3) + 1;
  814. }
  815. if (*(Context.Operand4) != '\0') {
  816. strcpy(Buffer, Context.Operand4);
  817. Disassembly->FourthOperand = Buffer;
  818. }
  819. }
  820. return Result;
  821. }
  822. BOOL
  823. DbgpArmDecodeWithTable (
  824. PARM_DISASSEMBLY Context,
  825. PARM_DECODE_BRANCH Table,
  826. ULONG TableSize
  827. )
  828. /*++
  829. Routine Description:
  830. This routine checks the masks and values specified by the given table, and
  831. calls the appropriate disassembly routine.
  832. Arguments:
  833. Context - Supplies a pointer to the disassembly context.
  834. Table - Supplies a pointer to the decode branch table.
  835. TableSize - Supplies the number of elements in the table.
  836. Return Value:
  837. TRUE if a match was found.
  838. --*/
  839. {
  840. ULONG Instruction;
  841. ULONG Mask;
  842. ULONG Shift;
  843. ULONG TableIndex;
  844. ULONG Value;
  845. Instruction = Context->Instruction;
  846. for (TableIndex = 0; TableIndex < TableSize; TableIndex += 1) {
  847. Shift = Table[TableIndex].Shift;
  848. Mask = Table[TableIndex].Mask << Shift;
  849. Value = Table[TableIndex].Value << Shift;
  850. if ((Instruction & Mask) == Value) {
  851. //
  852. // Call the disassembly routine, this table entry matched.
  853. //
  854. Table[TableIndex].Disassemble(Context);
  855. return TRUE;
  856. }
  857. }
  858. //
  859. // Nothing matched.
  860. //
  861. return FALSE;
  862. }
  863. VOID
  864. DbgpArmDecodeCoprocessorMove (
  865. PARM_DISASSEMBLY Context
  866. )
  867. /*++
  868. Routine Description:
  869. This routine decodes a coprocessor move instruction.
  870. Arguments:
  871. Context - Supplies a pointer to the disassembly context.
  872. Return Value:
  873. None.
  874. --*/
  875. {
  876. PSTR BaseMnemonic;
  877. ULONG Condition;
  878. ULONG Coprocessor;
  879. ULONG Instruction;
  880. PSTR MnemonicSuffix;
  881. ULONG Opcode1;
  882. ULONG Opcode2;
  883. ULONG RegisterD;
  884. ULONG RegisterM;
  885. ULONG RegisterN;
  886. Instruction = Context->Instruction;
  887. //
  888. // Get the basic fields for CDP, MRC, and MCR instructions.
  889. //
  890. Coprocessor = (Instruction & ARM_COPROCESSOR_NUMBER_MASK) >>
  891. ARM_COPROCESSOR_NUMBER_SHIFT;
  892. RegisterD = (Instruction & ARM_DESTINATION_REGISTER_MASK) >>
  893. ARM_DESTINATION_REGISTER_SHIFT;
  894. RegisterN = (Instruction & ARM_COPROCESSOR_RN_MASK) >>
  895. ARM_COPROCESSOR_RN_SHIFT;
  896. RegisterM = (Instruction & ARM_COPROCESSOR_RM_MASK) >>
  897. ARM_COPROCESSOR_RM_SHIFT;
  898. Opcode2 = (Instruction & ARM_COPROCESSOR_OPCODE2_MASK) >>
  899. ARM_COPROCESSOR_OPCODE2_SHIFT;
  900. //
  901. // CDP has a different opcode 1 shift, so this needs to be adjusted for
  902. // that instruction.
  903. //
  904. Opcode1 = (Instruction & ARM_MCR_MRC_OPCODE1_MASK) >>
  905. ARM_MCR_MRC_OPCODE1_SHIFT;
  906. //
  907. // If the CDP bit is 0, then this instruction is a CDP instruction.
  908. //
  909. if ((Instruction & ARM_COPROCESSOR_CDP_BIT) == 0) {
  910. BaseMnemonic = ARM_CDP_MNEMONIC;
  911. Opcode1 = (Instruction & ARM_CDP_OPCODE1_MASK) >> ARM_CDP_OPCODE1_SHIFT;
  912. sprintf(Context->Operand2, "c%d", RegisterD);
  913. //
  914. // If it's not a CDP instruction, check the other constant bit, which if
  915. // set indicates a MRC, if clear indicates MCR.
  916. //
  917. } else if ((Instruction & ARM_COPROCESSOR_MRC_BIT) != 0) {
  918. BaseMnemonic = ARM_MRC_MNEMONIC;
  919. sprintf(Context->Operand2, "r%d", RegisterD);
  920. } else {
  921. BaseMnemonic = ARM_MCR_MNEMONIC;
  922. sprintf(Context->Operand2, "r%d", RegisterD);
  923. }
  924. //
  925. // If the condition is 0xF, then these are CDP2, MRC2, and MCR2
  926. // instructions.
  927. //
  928. MnemonicSuffix = "";
  929. Condition = Context->Instruction >> ARM_CONDITION_SHIFT;
  930. if (Condition == ARM_CONDITION_UNCONDITIONAL) {
  931. MnemonicSuffix = "2";
  932. }
  933. sprintf(Context->Mnemonic, "%s%s", BaseMnemonic, MnemonicSuffix);
  934. sprintf(Context->Operand1, "p%d, %d", Coprocessor, Opcode1);
  935. sprintf(Context->Operand3, "c%d, c%d, %d", RegisterN, RegisterM, Opcode2);
  936. return;
  937. }
  938. VOID
  939. DbgpArmDecodeCoprocessorMoveTwo (
  940. PARM_DISASSEMBLY Context
  941. )
  942. /*++
  943. Routine Description:
  944. This routine decodes a coprocessor move instruction to/from two ARM
  945. registers.
  946. Arguments:
  947. Context - Supplies a pointer to the disassembly context.
  948. Return Value:
  949. None.
  950. --*/
  951. {
  952. PSTR BaseMnemonic;
  953. ULONG Condition;
  954. ULONG Coprocessor;
  955. ULONG Instruction;
  956. PSTR MnemonicSuffix;
  957. ULONG Opcode1;
  958. ULONG RegisterM;
  959. ULONG RegisterT;
  960. ULONG RegisterT2;
  961. Instruction = Context->Instruction;
  962. //
  963. // Get the basic fields for MRRC and MCRR instructions.
  964. //
  965. Coprocessor = (Instruction & ARM_COPROCESSOR_NUMBER_MASK) >>
  966. ARM_COPROCESSOR_NUMBER_SHIFT;
  967. RegisterT = (Instruction & ARM_DESTINATION_REGISTER_MASK) >>
  968. ARM_DESTINATION_REGISTER_SHIFT;
  969. RegisterT2 = (Instruction & ARM_DESTINATION_REGISTER2_MASK) >>
  970. ARM_DESTINATION_REGISTER2_SHIFT;
  971. RegisterM = (Instruction & ARM_COPROCESSOR_RM_MASK) >>
  972. ARM_COPROCESSOR_RM_SHIFT;
  973. Opcode1 = (Instruction & ARM_MCRR_MRRC_OPCODE1_MASK) >>
  974. ARM_MCRR_MRRC_OPCODE1_SHIFT;
  975. //
  976. // Check the non-constant bit to determine if this is MRRC or MCRR.
  977. //
  978. if ((Instruction & ARM_COPROCESSOR_MRRC_BIT) != 0) {
  979. BaseMnemonic = ARM_MRRC_MNEMONIC;
  980. } else {
  981. BaseMnemonic = ARM_MCRR_MNEMONIC;
  982. }
  983. //
  984. // If the condition is 0xF, then these are MRRC2 and MCRR2 instructions.
  985. //
  986. MnemonicSuffix = "";
  987. Condition = Context->Instruction >> ARM_CONDITION_SHIFT;
  988. if (Condition == ARM_CONDITION_UNCONDITIONAL) {
  989. MnemonicSuffix = "2";
  990. }
  991. sprintf(Context->Mnemonic, "%s%s", BaseMnemonic, MnemonicSuffix);
  992. sprintf(Context->Operand1, "p%d, %d", Coprocessor, Opcode1);
  993. sprintf(Context->Operand2,
  994. "%s, %s",
  995. DbgArmRegisterNames[RegisterT],
  996. DbgArmRegisterNames[RegisterT2]);
  997. sprintf(Context->Operand3, "c%d", RegisterM);
  998. return;
  999. }
  1000. VOID
  1001. DbgpArmDecodeCoprocessorLoadStore (
  1002. PARM_DISASSEMBLY Context
  1003. )
  1004. /*++
  1005. Routine Description:
  1006. This routine decodes a coprocessor data instruction.
  1007. Arguments:
  1008. Context - Supplies a pointer to the disassembly context.
  1009. Return Value:
  1010. None.
  1011. --*/
  1012. {
  1013. PSTR BaseMnemonic;
  1014. ULONG Condition;
  1015. UCHAR CoprocessorDestination;
  1016. UCHAR CoprocessorNumber;
  1017. PSTR FirstSuffix;
  1018. ULONG Immediate8;
  1019. ULONG Instruction;
  1020. UCHAR Rn;
  1021. PSTR SecondSuffix;
  1022. UCHAR SignCharacter;
  1023. UCHAR WriteBack;
  1024. Instruction = Context->Instruction;
  1025. //
  1026. // Determine whether it's a long load/store or regular.
  1027. //
  1028. SecondSuffix = "";
  1029. if ((Instruction & ARM_COPROCESSOR_DATA_LONG_BIT) != 0) {
  1030. SecondSuffix = ARM_COPROCESSOR_LONG_MNEMONIC;
  1031. }
  1032. //
  1033. // Determine whether the immediate is added or subtracted.
  1034. //
  1035. if ((Instruction & ARM_ADD_SUBTRACT_BIT) != 0) {
  1036. SignCharacter = '+';
  1037. } else {
  1038. SignCharacter = '-';
  1039. }
  1040. //
  1041. // Get the register numbers and values involved.
  1042. //
  1043. CoprocessorDestination =
  1044. (Instruction & ARM_COPROCESSOR_DATA_DESTINATION_MASK) >>
  1045. ARM_COPROCESSOR_DATA_DESTINATION_SHIFT;
  1046. Rn = (Instruction & ARM_COPROCESSOR_RN_MASK) >> ARM_COPROCESSOR_RN_SHIFT;
  1047. Immediate8 = (UCHAR)(Instruction & 0xFF);
  1048. CoprocessorNumber = (Instruction & ARM_COPROCESSOR_NUMBER_MASK) >>
  1049. ARM_COPROCESSOR_NUMBER_SHIFT;
  1050. //
  1051. // Determine the mnemonic.
  1052. //
  1053. if ((Instruction & ARM_LOAD_BIT) != 0) {
  1054. BaseMnemonic = ARM_COPROCESSOR_LOAD_MNEMONIC;
  1055. } else {
  1056. BaseMnemonic = ARM_COPROCESSOR_STORE_MNEMONIC;
  1057. }
  1058. //
  1059. // If the condition is 0xF, then these are MRRC2 and MCRR2 instructions.
  1060. //
  1061. FirstSuffix = "";
  1062. Condition = Context->Instruction >> ARM_CONDITION_SHIFT;
  1063. if (Condition == ARM_CONDITION_UNCONDITIONAL) {
  1064. FirstSuffix = "2";
  1065. }
  1066. sprintf(Context->Mnemonic,
  1067. "%s%s%s",
  1068. BaseMnemonic,
  1069. FirstSuffix,
  1070. SecondSuffix);
  1071. //
  1072. // Write out the first two operands.
  1073. //
  1074. sprintf(Context->Operand1, "p%d", CoprocessorNumber);
  1075. sprintf(Context->Operand2, "c%d", CoprocessorDestination);
  1076. //
  1077. // Depending on the addressing mode, write out the third operand. If the
  1078. // pre-index bit is set, the addressing mode is either pre-indexed or
  1079. // offset.
  1080. //
  1081. if ((Instruction & ARM_PREINDEX_BIT) != 0) {
  1082. if ((Instruction & ARM_WRITE_BACK_BIT) != 0) {
  1083. WriteBack = '!';
  1084. } else {
  1085. WriteBack = ' ';
  1086. }
  1087. sprintf(Context->Operand3,
  1088. "[%s, #%c%d]%c",
  1089. DbgArmRegisterNames[Rn],
  1090. SignCharacter,
  1091. Immediate8 * 4,
  1092. WriteBack);
  1093. //
  1094. // The pre-index bit is not set, so the addressing mode is either post-
  1095. // indexed or unindexed.
  1096. //
  1097. } else {
  1098. if ((Instruction & ARM_WRITE_BACK_BIT) != 0) {
  1099. sprintf(Context->Operand3,
  1100. "[%s], #%c%d",
  1101. DbgArmRegisterNames[Rn],
  1102. SignCharacter,
  1103. Immediate8 * 4);
  1104. } else {
  1105. sprintf(Context->Operand3,
  1106. "[%s], {%d}",
  1107. DbgArmRegisterNames[Rn],
  1108. Immediate8);
  1109. }
  1110. }
  1111. return;
  1112. }
  1113. VOID
  1114. DbgpArmDecodeFloatingPoint (
  1115. PARM_DISASSEMBLY Context
  1116. )
  1117. /*++
  1118. Routine Description:
  1119. This routine decodes a floating point data processing instructions.
  1120. Arguments:
  1121. Context - Supplies a pointer to the disassembly context.
  1122. Return Value:
  1123. None.
  1124. --*/
  1125. {
  1126. ARM_DECODE_WITH_TABLE(Context, DbgArmFloatingPointTable);
  1127. return;
  1128. }
  1129. VOID
  1130. DbgpArmDecodeSimdSmallTransfers (
  1131. PARM_DISASSEMBLY Context
  1132. )
  1133. /*++
  1134. Routine Description:
  1135. This routine decodes a transfers between SIMD and floating point 8-bit,
  1136. 16-bit, and 32-bit registers and the ARM core.
  1137. Arguments:
  1138. Context - Supplies a pointer to the disassembly context.
  1139. Return Value:
  1140. None.
  1141. --*/
  1142. {
  1143. ARM_DECODE_WITH_TABLE(Context, DbgArmSimdSmallTransferTable);
  1144. return;
  1145. }
  1146. VOID
  1147. DbgpArmDecodeSimd64BitTransfers (
  1148. PARM_DISASSEMBLY Context
  1149. )
  1150. /*++
  1151. Routine Description:
  1152. This routine decodes a transfers between SIMD and floating point 64-bit
  1153. registers and the ARM core.
  1154. Arguments:
  1155. Context - Supplies a pointer to the disassembly context.
  1156. Return Value:
  1157. None.
  1158. --*/
  1159. {
  1160. ULONG Instruction;
  1161. PSTR RegisterString;
  1162. ULONG Rt;
  1163. ULONG Rt2;
  1164. ULONG Vector;
  1165. PSTR VectorString;
  1166. Instruction = Context->Instruction;
  1167. Vector = (Instruction & ARM_SIMD_TRANSFER_64_VECTOR_MASK) >>
  1168. ARM_SIMD_TRANSFER_64_VECTOR_SHIFT;
  1169. Rt = (Instruction & ARM_SIMD_TRANSFER_64_RT_MASK) >>
  1170. ARM_SIMD_TRANSFER_64_RT_SHIFT;
  1171. Rt2 = (Instruction & ARM_SIMD_TRANSFER_64_RT2_MASK) >>
  1172. ARM_SIMD_TRANSFER_64_RT2_SHIFT;
  1173. if ((Instruction & ARM_SIMD_TRANSFER_64_TO_REGISTER) != 0) {
  1174. RegisterString = Context->Operand1;
  1175. VectorString = Context->Operand2;
  1176. } else {
  1177. VectorString = Context->Operand1;
  1178. RegisterString = Context->Operand2;
  1179. }
  1180. strcpy(Context->Mnemonic, ARM_VMOV_MNEMONIC);
  1181. sprintf(RegisterString,
  1182. "%s, %s",
  1183. DbgArmRegisterNames[Rt],
  1184. DbgArmRegisterNames[Rt2]);
  1185. if ((Instruction & ARM_SIMD_TRANSFER_64_DOUBLE) != 0) {
  1186. if ((Instruction & ARM_SIMD_TRANSFER_64_VECTOR_BIT) != 0) {
  1187. Vector |= (1 << 4);
  1188. }
  1189. sprintf(VectorString,
  1190. "%s%d",
  1191. ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR,
  1192. Vector);
  1193. } else {
  1194. Vector <<= 1;
  1195. if ((Instruction & ARM_SIMD_TRANSFER_64_VECTOR_BIT) != 0) {
  1196. Vector |= 1;
  1197. }
  1198. sprintf(VectorString,
  1199. "%s%d, %s%d",
  1200. ARM_FLOATING_POINT_SINGLE_PRECISION_VECTOR,
  1201. Vector,
  1202. ARM_FLOATING_POINT_SINGLE_PRECISION_VECTOR,
  1203. Vector + 1);
  1204. }
  1205. return;
  1206. }
  1207. VOID
  1208. DbgpArmDecodeSimdLoadStore (
  1209. PARM_DISASSEMBLY Context
  1210. )
  1211. /*++
  1212. Routine Description:
  1213. This routine decodes a load/store instructions involving SIMD and floating
  1214. point registers.
  1215. Arguments:
  1216. Context - Supplies a pointer to the disassembly context.
  1217. Return Value:
  1218. None.
  1219. --*/
  1220. {
  1221. ARM_DECODE_WITH_TABLE(Context, DbgArmSimdLoadStoreTable);
  1222. return;
  1223. }
  1224. VOID
  1225. DbgpArmDecodeSimdElementLoadStore (
  1226. PARM_DISASSEMBLY Context
  1227. )
  1228. /*++
  1229. Routine Description:
  1230. This routine decodes a SIMD element and structure load and store
  1231. instructions.
  1232. Arguments:
  1233. Context - Supplies a pointer to the disassembly context.
  1234. Return Value:
  1235. None.
  1236. --*/
  1237. {
  1238. ARM_DECODE_WITH_TABLE(Context, DbgArmSimdElementLoadStoreTable);
  1239. return;
  1240. }
  1241. VOID
  1242. DbgpArmDecodeSimdDataProcessing (
  1243. PARM_DISASSEMBLY Context
  1244. )
  1245. /*++
  1246. Routine Description:
  1247. This routine decodes the SIMD data processing instructions.
  1248. Arguments:
  1249. Context - Supplies a pointer to the disassembly context.
  1250. Return Value:
  1251. None.
  1252. --*/
  1253. {
  1254. ARM_DECODE_WITH_TABLE(Context, DbgArmSimdDataProcessingTable);
  1255. return;
  1256. }
  1257. VOID
  1258. DbgpArmDecodeRegisterList (
  1259. PSTR Destination,
  1260. ULONG DestinationSize,
  1261. ULONG RegisterList
  1262. )
  1263. /*++
  1264. Routine Description:
  1265. This routine converts an ARM register list to a string.
  1266. Arguments:
  1267. Destination - Supplies a pointer to the destination string.
  1268. DestinationSize - Supplies the size of the destination string.
  1269. RegisterList - Supplies the register bitmask.
  1270. Return Value:
  1271. None.
  1272. --*/
  1273. {
  1274. ULONG CurrentRegister;
  1275. BOOL FirstRegister;
  1276. strcpy(Destination, "{");
  1277. //
  1278. // Loop through the registers, adding the ones specified in the bitfield.
  1279. //
  1280. FirstRegister = TRUE;
  1281. for (CurrentRegister = 0; CurrentRegister < 16; CurrentRegister += 1) {
  1282. if ((RegisterList & 0x00000001) != 0) {
  1283. if (FirstRegister == FALSE) {
  1284. strcat(Destination, ", ");
  1285. }
  1286. strcat(Destination, DbgArmRegisterNames[CurrentRegister]);
  1287. FirstRegister = FALSE;
  1288. }
  1289. RegisterList = RegisterList >> 1;
  1290. }
  1291. strcat(Destination, "}");
  1292. return;
  1293. }
  1294. VOID
  1295. DbgpArmPrintMode (
  1296. PSTR Destination,
  1297. ULONG Mode
  1298. )
  1299. /*++
  1300. Routine Description:
  1301. This routine prints the given ARM processor mode.
  1302. Arguments:
  1303. Destination - Supplies a pointer where the mode will be printed.
  1304. Mode - Supplies the mode to print. Only the bottom 5 bits will be examined.
  1305. Return Value:
  1306. None.
  1307. --*/
  1308. {
  1309. PSTR ModeString;
  1310. Mode &= ARM_MODE_MASK;
  1311. ModeString = NULL;
  1312. if (Mode == ARM_MODE_USER) {
  1313. ModeString = ARM_MODE_USER_STRING;
  1314. } else if (Mode == ARM_MODE_FIQ) {
  1315. ModeString = ARM_MODE_FIQ_STRING;
  1316. } else if (Mode == ARM_MODE_IRQ) {
  1317. ModeString = ARM_MODE_IRQ_STRING;
  1318. } else if (Mode == ARM_MODE_SVC) {
  1319. ModeString = ARM_MODE_SVC_STRING;
  1320. } else if (Mode == ARM_MODE_ABORT) {
  1321. ModeString = ARM_MODE_ABORT_STRING;
  1322. } else if (Mode == ARM_MODE_UNDEF) {
  1323. ModeString = ARM_MODE_UNDEF_STRING;
  1324. } else if (Mode == ARM_MODE_SYSTEM) {
  1325. ModeString = ARM_MODE_SYSTEM_STRING;
  1326. }
  1327. if (ModeString != NULL) {
  1328. sprintf(Destination, "#%s", ModeString);
  1329. } else {
  1330. sprintf(Destination, "%02X", Mode);
  1331. }
  1332. return;
  1333. }
  1334. VOID
  1335. DbgpArmPrintBarrierMode (
  1336. PSTR Destination,
  1337. ULONG Mode
  1338. )
  1339. /*++
  1340. Routine Description:
  1341. This routine prints the memory barrier (dsb, dmb, isb) type. For full
  1342. system (sy), nothing is printed.
  1343. Arguments:
  1344. Destination - Supplies a pointer where the mode will be printed.
  1345. Mode - Supplies the mode to print. Only the bottom 4 bits will be examined.
  1346. Return Value:
  1347. None.
  1348. --*/
  1349. {
  1350. PSTR ModeString;
  1351. ModeString = NULL;
  1352. Mode &= ARM_BARRIER_MODE_MASK;
  1353. if (Mode == ARM_BARRIER_MODE_FULL) {
  1354. ModeString = ARM_BARRIER_MODE_FULL_STRING;
  1355. } else if (Mode == ARM_BARRIER_MODE_ST) {
  1356. ModeString = ARM_BARRIER_MODE_ST_STRING;
  1357. } else if (Mode == ARM_BARRIER_MODE_ISH) {
  1358. ModeString = ARM_BARRIER_MODE_ISH_STRING;
  1359. } else if (Mode == ARM_BARRIER_MODE_ISHST) {
  1360. ModeString = ARM_BARRIER_MODE_ISHST_STRING;
  1361. } else if (Mode == ARM_BARRIER_MODE_NSH) {
  1362. ModeString = ARM_BARRIER_MODE_NSH_STRING;
  1363. } else if (Mode == ARM_BARRIER_MODE_NSHST) {
  1364. ModeString = ARM_BARRIER_MODE_NSHST_STRING;
  1365. } else if (Mode == ARM_BARRIER_MODE_OSH) {
  1366. ModeString = ARM_BARRIER_MODE_OSH_STRING;
  1367. } else if (Mode == ARM_BARRIER_MODE_OSHST) {
  1368. ModeString = ARM_BARRIER_MODE_OSHST_STRING;
  1369. }
  1370. if (ModeString != NULL) {
  1371. strcpy(Destination, ModeString);
  1372. } else {
  1373. sprintf(Destination, "#%02X", Mode);
  1374. }
  1375. return;
  1376. }
  1377. //
  1378. // --------------------------------------------------------- Internal Functions
  1379. //
  1380. VOID
  1381. DbgpArmDecodeUnconditional (
  1382. PARM_DISASSEMBLY Context
  1383. )
  1384. /*++
  1385. Routine Description:
  1386. This routine decodes instructions with the unconditional condition code 0xF.
  1387. Arguments:
  1388. Context - Supplies a pointer to the disassembly context.
  1389. Return Value:
  1390. None.
  1391. --*/
  1392. {
  1393. ARM_DECODE_WITH_TABLE(Context, DbgArmUnconditionalTable);
  1394. return;
  1395. }
  1396. VOID
  1397. DbgpArmDecodeDataProcessingAndMiscellaneous (
  1398. PARM_DISASSEMBLY Context
  1399. )
  1400. /*++
  1401. Routine Description:
  1402. This routine decodes the data processing and miscellaneous instructions.
  1403. Arguments:
  1404. Context - Supplies a pointer to the disassembly context.
  1405. Return Value:
  1406. None.
  1407. --*/
  1408. {
  1409. ARM_DECODE_WITH_TABLE(Context, DbgArmDataProcessingAndMiscellaneousTable);
  1410. return;
  1411. }
  1412. VOID
  1413. DbgpArmDecodeMediaInstruction (
  1414. PARM_DISASSEMBLY Context
  1415. )
  1416. /*++
  1417. Routine Description:
  1418. This routine decodes an instruction that falls into the Media Extension
  1419. class of instructions.
  1420. Arguments:
  1421. Context - Supplies a pointer to the disassembly context.
  1422. Return Value:
  1423. None.
  1424. --*/
  1425. {
  1426. ARM_DECODE_WITH_TABLE(Context, DbgArmMediaInstructionTable);
  1427. return;
  1428. }
  1429. VOID
  1430. DbgpArmDecodeBranchAndBlockTransfer (
  1431. PARM_DISASSEMBLY Context
  1432. )
  1433. /*++
  1434. Routine Description:
  1435. This routine decodes both branch and block transfer instructions.
  1436. Arguments:
  1437. Context - Supplies a pointer to the disassembly context.
  1438. Return Value:
  1439. None.
  1440. --*/
  1441. {
  1442. ARM_DECODE_WITH_TABLE(Context, DbgArmBranchAndBlockTransferTable);
  1443. return;
  1444. }
  1445. VOID
  1446. DbgpArmDecodeCoprocessorSupervisor (
  1447. PARM_DISASSEMBLY Context
  1448. )
  1449. /*++
  1450. Routine Description:
  1451. This routine decodes a coprocessor move or supervisor instruction. This
  1452. routine also decodes floating point instructions and SIMD to floating point
  1453. transfers.
  1454. Arguments:
  1455. Context - Supplies a pointer to the disassembly context.
  1456. Return Value:
  1457. None.
  1458. --*/
  1459. {
  1460. ARM_DECODE_WITH_TABLE(Context, DbgArmCoprocessorSupervisorTable);
  1461. return;
  1462. }
  1463. VOID
  1464. DbgpArmDecodeMemoryHintSimdMisc (
  1465. PARM_DISASSEMBLY Context
  1466. )
  1467. /*++
  1468. Routine Description:
  1469. This routine decodes instructions that are either memory hints, advanced
  1470. SIMD instructions, or miscellaneous instructions.
  1471. Arguments:
  1472. Context - Supplies a pointer to the disassembly context.
  1473. Return Value:
  1474. None.
  1475. --*/
  1476. {
  1477. ARM_DECODE_WITH_TABLE(Context, DbgArmMemoryHintSimdMiscTable);
  1478. return;
  1479. }
  1480. VOID
  1481. DbgpArmDecodeStoreReturnState (
  1482. PARM_DISASSEMBLY Context
  1483. )
  1484. /*++
  1485. Routine Description:
  1486. This routine decodes the store return state (SRS) instruction.
  1487. Arguments:
  1488. Context - Supplies a pointer to the disassembly context.
  1489. Return Value:
  1490. None.
  1491. --*/
  1492. {
  1493. PSTR MnemonicSuffix;
  1494. INT Result;
  1495. MnemonicSuffix = DbgpArmGetLoadStoreTypeString(Context->Instruction);
  1496. sprintf(Context->Mnemonic, "%s%s", ARM_SRS_MNEMONIC, MnemonicSuffix);
  1497. DbgpArmPrintMode(Context->Operand2, Context->Instruction);
  1498. if ((Context->Instruction & ARM_WRITE_BACK_BIT) != 0) {
  1499. Result = snprintf(Context->Operand1,
  1500. sizeof(Context->Operand1),
  1501. "%s!, %s",
  1502. DbgArmRegisterNames[ARM_STACK_REGISTER],
  1503. Context->Operand2);
  1504. } else {
  1505. Result = snprintf(Context->Operand1,
  1506. sizeof(Context->Operand1),
  1507. "%s, %s",
  1508. DbgArmRegisterNames[ARM_STACK_REGISTER],
  1509. Context->Operand2);
  1510. }
  1511. if (Result < 0) {
  1512. Context->Operand1[0] = '\0';
  1513. }
  1514. Context->Operand2[0] = '\0';
  1515. return;
  1516. }
  1517. VOID
  1518. DbgpArmDecodeReturnFromException (
  1519. PARM_DISASSEMBLY Context
  1520. )
  1521. /*++
  1522. Routine Description:
  1523. This routine decodes the return from exception (RFE) instruction.
  1524. Arguments:
  1525. Context - Supplies a pointer to the disassembly context.
  1526. Return Value:
  1527. None.
  1528. --*/
  1529. {
  1530. PSTR MnemonicSuffix;
  1531. ULONG Rn;
  1532. Rn = (Context->Instruction & ARM_UNCONDITIONAL_RN_MASK) >>
  1533. ARM_UNCONDITIONAL_RN_SHIFT;
  1534. MnemonicSuffix = DbgpArmGetLoadStoreTypeString(Context->Instruction);
  1535. sprintf(Context->Mnemonic, "%s%s", ARM_RFE_MNEMONIC, MnemonicSuffix);
  1536. if ((Context->Instruction & ARM_WRITE_BACK_BIT) != 0) {
  1537. sprintf(Context->Operand1, "%s!", DbgArmRegisterNames[Rn]);
  1538. } else {
  1539. sprintf(Context->Operand1, "%s", DbgArmRegisterNames[Rn]);
  1540. }
  1541. return;
  1542. }
  1543. VOID
  1544. DbgpArmDecodeBranch (
  1545. PARM_DISASSEMBLY Context
  1546. )
  1547. /*++
  1548. Routine Description:
  1549. This routine decodes the branch instructions.
  1550. Arguments:
  1551. Context - Supplies a pointer to the disassembly context.
  1552. Return Value:
  1553. None.
  1554. --*/
  1555. {
  1556. PSTR BaseMnemonic;
  1557. ULONG Condition;
  1558. ULONG Instruction;
  1559. LONG Offset;
  1560. ULONGLONG OperandAddress;
  1561. Instruction = Context->Instruction;
  1562. Offset = (Instruction & ARM_IMMEDIATE24_MASK) << 2;
  1563. //
  1564. // If the condition is set to unconditional, then this is a BLX
  1565. // instruction. The current instruction set is ARM and the target
  1566. // instruction set is Thumb.
  1567. //
  1568. Condition = Instruction >> ARM_CONDITION_SHIFT;
  1569. if (Condition == ARM_CONDITION_UNCONDITIONAL) {
  1570. BaseMnemonic = ARM_BLX_MNEMONIC;
  1571. if ((Instruction & ARM_BLX_H_BIT) != 0) {
  1572. Offset |= 0x2;
  1573. }
  1574. //
  1575. // Or in the bottom bit as this is a transition to Thumb mode and all
  1576. // addresses should off by 1.
  1577. //
  1578. Offset |= 0x1;
  1579. //
  1580. // Otherwise if the link bit is set, then it is a BL instruction with the
  1581. // current and target instruction set both being ARM.
  1582. //
  1583. } else if ((Instruction & ARM_BRANCH_LINK_BIT) != 0) {
  1584. BaseMnemonic = ARM_BL_MNEMONIC;
  1585. //
  1586. // Otherwise it is just a plain branch instruction.
  1587. //
  1588. } else {
  1589. BaseMnemonic = ARM_B_MNEMONIC;
  1590. }
  1591. //
  1592. // Sign-extend the offset.
  1593. //
  1594. if ((Offset & 0x02000000) != 0) {
  1595. Offset |= 0xFC000000;
  1596. }
  1597. strcpy(Context->Mnemonic, BaseMnemonic);
  1598. //
  1599. // The immediate value in the instruction is relative to the PC value of
  1600. // this instruction, which is this instruction's address plus 8.
  1601. //
  1602. OperandAddress = Context->InstructionPointer + 8;
  1603. OperandAddress += (LONGLONG)Offset;
  1604. Context->Result->OperandAddress = OperandAddress;
  1605. Context->Result->AddressIsDestination = TRUE;
  1606. Context->Result->AddressIsValid = TRUE;
  1607. snprintf(Context->Operand1,
  1608. sizeof(Context->Operand1),
  1609. "[0x%08llx]",
  1610. OperandAddress);
  1611. return;
  1612. }
  1613. VOID
  1614. DbgpArmDecodeUndefined (
  1615. PARM_DISASSEMBLY Context
  1616. )
  1617. /*++
  1618. Routine Description:
  1619. This routine catches undefined corners of the instruction space.
  1620. Arguments:
  1621. Context - Supplies a pointer to the disassembly context.
  1622. Return Value:
  1623. None.
  1624. --*/
  1625. {
  1626. strcpy(Context->Mnemonic, "Undefined");
  1627. return;
  1628. }
  1629. VOID
  1630. DbgpArmDecodeUnpredictable (
  1631. PARM_DISASSEMBLY Context
  1632. )
  1633. /*++
  1634. Routine Description:
  1635. This routine catches unpredictable corners of the instruction space.
  1636. Arguments:
  1637. Context - Supplies a pointer to the disassembly context.
  1638. Return Value:
  1639. None.
  1640. --*/
  1641. {
  1642. strcpy(Context->Mnemonic, "Unpredictable");
  1643. return;
  1644. }
  1645. VOID
  1646. DbgpArmDecodeNop (
  1647. PARM_DISASSEMBLY Context
  1648. )
  1649. /*++
  1650. Routine Description:
  1651. This routine handles instructions that are treated as no operation.
  1652. Arguments:
  1653. Context - Supplies a pointer to the disassembly context.
  1654. Return Value:
  1655. None.
  1656. --*/
  1657. {
  1658. strcpy(Context->Mnemonic, "NOP");
  1659. return;
  1660. }
  1661. VOID
  1662. DbgpArmDecodeChangeProcessorState (
  1663. PARM_DISASSEMBLY Context
  1664. )
  1665. /*++
  1666. Routine Description:
  1667. This routine decodes the change processor state instruction.
  1668. Arguments:
  1669. Context - Supplies a pointer to the disassembly context.
  1670. Return Value:
  1671. None.
  1672. --*/
  1673. {
  1674. ULONG Instruction;
  1675. Instruction = Context->Instruction;
  1676. if ((Instruction & ARM_CPS_IMOD_DISABLE) != 0) {
  1677. strcpy(Context->Mnemonic, ARM_CPS_MNEMONIC_DISABLE);
  1678. } else {
  1679. strcpy(Context->Mnemonic, ARM_CPS_MNEMONIC_ENABLE);
  1680. }
  1681. Context->Operand1[0] = '\0';
  1682. if ((Instruction & ARM_CPS_FLAG_A) != 0) {
  1683. strcat(Context->Operand1, ARM_CPS_FLAG_A_STRING);
  1684. }
  1685. if ((Instruction & ARM_CPS_FLAG_I) != 0) {
  1686. strcat(Context->Operand1, ARM_CPS_FLAG_I_STRING);
  1687. }
  1688. if ((Instruction & ARM_CPS_FLAG_F) != 0) {
  1689. strcat(Context->Operand1, ARM_CPS_FLAG_F_STRING);
  1690. }
  1691. if ((Instruction & ARM_MODE_MASK) != 0) {
  1692. DbgpArmPrintMode(Context->Operand2, Instruction);
  1693. if ((Instruction &
  1694. (ARM_CPS_FLAG_A | ARM_CPS_FLAG_I | ARM_CPS_FLAG_F)) != 0) {
  1695. strcat(Context->Operand1, ", ");
  1696. }
  1697. strcat(Context->Operand1, Context->Operand2);
  1698. Context->Operand2[0] = '\0';
  1699. }
  1700. return;
  1701. }
  1702. VOID
  1703. DbgpArmDecodeSetEndianness (
  1704. PARM_DISASSEMBLY Context
  1705. )
  1706. /*++
  1707. Routine Description:
  1708. This routine decodes the set endianness instruction.
  1709. Arguments:
  1710. Context - Supplies a pointer to the disassembly context.
  1711. Return Value:
  1712. None.
  1713. --*/
  1714. {
  1715. if ((Context->Instruction & ARM_SETEND_BIG_ENDIAN) != 0) {
  1716. strcpy(Context->Operand1, ARM_SETEND_BE_STRING);
  1717. } else {
  1718. strcpy(Context->Operand1, ARM_SETEND_LE_STRING);
  1719. }
  1720. strcpy(Context->Mnemonic, ARM_SETEND_MNEMONIC);
  1721. return;
  1722. }
  1723. VOID
  1724. DbgpArmDecodePreloadInstruction (
  1725. PARM_DISASSEMBLY Context
  1726. )
  1727. /*++
  1728. Routine Description:
  1729. This routine decodes the preload instructions, both the immediate/literal
  1730. versions and the register based versions.
  1731. Arguments:
  1732. Context - Supplies a pointer to the disassembly context.
  1733. Return Value:
  1734. None.
  1735. --*/
  1736. {
  1737. PSTR BaseMnemonic;
  1738. ULONG Immediate;
  1739. ULONG Instruction;
  1740. PSTR MnemonicSuffix;
  1741. LONG Offset;
  1742. ULONGLONG OperandAddress;
  1743. ULONG RegisterM;
  1744. ULONG RegisterN;
  1745. CHAR ShiftString[35];
  1746. CHAR SignCharacter;
  1747. //
  1748. // Sort out the bits that are common to the immediate and register preload
  1749. // instructions.
  1750. //
  1751. Instruction = Context->Instruction;
  1752. MnemonicSuffix = "";
  1753. if ((Instruction & ARM_PRELOAD_DATA_BIT) != 0) {
  1754. BaseMnemonic = ARM_PRELOAD_DATA_MNEMONIC;
  1755. if ((Instruction & ARM_PRELOAD_DATA_READ_BIT) == 0) {
  1756. MnemonicSuffix = "w";
  1757. }
  1758. } else {
  1759. BaseMnemonic = ARM_PRELOAD_MNEMONIC;
  1760. }
  1761. RegisterN = (Instruction & ARM_PRELOAD_RN_MASK) >> ARM_PRELOAD_RN_SHIFT;
  1762. if ((Instruction & ARM_PRELOAD_ADD_BIT) != 0) {
  1763. SignCharacter = '+';
  1764. } else {
  1765. SignCharacter = '-';
  1766. }
  1767. sprintf(Context->Mnemonic, "%s%s", BaseMnemonic, MnemonicSuffix);
  1768. //
  1769. // If this is a register preload instruction, get the second register and
  1770. // calculate the shift value.
  1771. //
  1772. if ((Instruction & ARM_PRELOAD_REGISTER_BIT) != 0) {
  1773. Immediate = (Instruction & ARM_PRELOAD_IMMEDIATE5_MASK) >>
  1774. ARM_PRELOAD_IMMEDIATE5_SHIFT;
  1775. RegisterM = (Instruction & ARM_PRELOAD_RM_MASK) >> ARM_PRELOAD_RM_SHIFT;
  1776. DbgpArmDecodeImmediateShift(ShiftString,
  1777. sizeof(ShiftString),
  1778. RegisterM,
  1779. (Instruction & ARM_SHIFT_TYPE),
  1780. Immediate);
  1781. sprintf(Context->Operand1,
  1782. "[%s, %c%s]",
  1783. DbgArmRegisterNames[RegisterN],
  1784. SignCharacter,
  1785. ShiftString);
  1786. //
  1787. // Otherwise build out the immediate/literal value.
  1788. //
  1789. } else {
  1790. Offset = (Instruction & ARM_PRELOAD_IMMEDIATE12_MASK) >>
  1791. ARM_PRELOAD_IMMEDIATE12_SHIFT;
  1792. //
  1793. // If the register is the PC, then the immediate value in the
  1794. // instruction is relative to the PC value of this instruction, which
  1795. // is this instruction's address plus 8.
  1796. //
  1797. if (RegisterN == ARM_PC_REGISTER) {
  1798. OperandAddress = Context->InstructionPointer + 8;
  1799. if ((Instruction & ARM_PRELOAD_ADD_BIT) == 0) {
  1800. Offset = -Offset;
  1801. }
  1802. OperandAddress += (LONGLONG)Offset;
  1803. Context->Result->OperandAddress = OperandAddress;
  1804. Context->Result->AddressIsDestination = TRUE;
  1805. Context->Result->AddressIsValid = TRUE;
  1806. snprintf(Context->Operand1,
  1807. sizeof(Context->Operand1),
  1808. "[0x%08llx]",
  1809. OperandAddress);
  1810. } else {
  1811. snprintf(Context->Operand1,
  1812. sizeof(Context->Operand1),
  1813. "[%s, #%c%d]",
  1814. DbgArmRegisterNames[RegisterN],
  1815. SignCharacter,
  1816. Offset);
  1817. }
  1818. }
  1819. return;
  1820. }
  1821. VOID
  1822. DbgpArmDecodeClearExclusive (
  1823. PARM_DISASSEMBLY Context
  1824. )
  1825. /*++
  1826. Routine Description:
  1827. This routine decodes the clear exclusive instruction.
  1828. Arguments:
  1829. Context - Supplies a pointer to the disassembly context.
  1830. Return Value:
  1831. None.
  1832. --*/
  1833. {
  1834. strcpy(Context->Mnemonic, ARM_CLREX_MNEMONIC);
  1835. return;
  1836. }
  1837. VOID
  1838. DbgpArmDecodeDataSynchronizationBarrier (
  1839. PARM_DISASSEMBLY Context
  1840. )
  1841. /*++
  1842. Routine Description:
  1843. This routine decodes the data synchronization barrier instruction.
  1844. Arguments:
  1845. Context - Supplies a pointer to the disassembly context.
  1846. Return Value:
  1847. None.
  1848. --*/
  1849. {
  1850. DbgpArmPrintBarrierMode(Context->Operand1, Context->Instruction);
  1851. strcpy(Context->Mnemonic, ARM_DSB_MNEMONIC);
  1852. return;
  1853. }
  1854. VOID
  1855. DbgpArmDecodeDataMemoryBarrier (
  1856. PARM_DISASSEMBLY Context
  1857. )
  1858. /*++
  1859. Routine Description:
  1860. This routine decodes the data memory barrier instruction.
  1861. Arguments:
  1862. Context - Supplies a pointer to the disassembly context.
  1863. Return Value:
  1864. None.
  1865. --*/
  1866. {
  1867. DbgpArmPrintBarrierMode(Context->Operand1, Context->Instruction);
  1868. strcpy(Context->Mnemonic, ARM_DMB_MNEMONIC);
  1869. return;
  1870. }
  1871. VOID
  1872. DbgpArmDecodeInstructionSynchronizationBarrier (
  1873. PARM_DISASSEMBLY Context
  1874. )
  1875. /*++
  1876. Routine Description:
  1877. This routine decodes the instruction synchronization barrier instruction.
  1878. Arguments:
  1879. Context - Supplies a pointer to the disassembly context.
  1880. Return Value:
  1881. None.
  1882. --*/
  1883. {
  1884. DbgpArmPrintBarrierMode(Context->Operand1, Context->Instruction);
  1885. strcpy(Context->Mnemonic, ARM_ISB_MNEMONIC);
  1886. return;
  1887. }
  1888. VOID
  1889. DbgpArmDecodeParallelAdditionSubtraction (
  1890. PARM_DISASSEMBLY Context
  1891. )
  1892. /*++
  1893. Routine Description:
  1894. This routine decodes the parallel addition and subtraction instructions.
  1895. Arguments:
  1896. Context - Supplies a pointer to the disassembly context.
  1897. Return Value:
  1898. None.
  1899. --*/
  1900. {
  1901. PSTR BaseMnemonic;
  1902. ULONG Instruction;
  1903. ULONG Op2;
  1904. ULONG ParallelOp;
  1905. ULONG Rd;
  1906. ULONG Rm;
  1907. ULONG Rn;
  1908. ULONG Unsigned;
  1909. Instruction = Context->Instruction;
  1910. Unsigned = 0;
  1911. if ((Instruction & ARM_PARALLEL_ARITHMETIC_UNSIGNED) != 0) {
  1912. Unsigned = 1;
  1913. }
  1914. ParallelOp = (Instruction & ARM_PARALLEL_ARITHMETIC_OP1_MASK) >>
  1915. ARM_PARALLEL_ARITHMETIC_OP1_SHIFT;
  1916. Op2 = (Instruction & ARM_PARALLEL_ARITHMETIC_OP2_MASK) >>
  1917. ARM_PARALLEL_ARITHMETIC_OP2_SHIFT;
  1918. ParallelOp |= ((Op2 - 1) << 2);
  1919. BaseMnemonic = NULL;
  1920. if (ParallelOp < ARM_PARALLEL_ARITHMETIC_OP_MAX) {
  1921. BaseMnemonic = DbgArmParallelArithmeticMnemonics[Unsigned][ParallelOp];
  1922. }
  1923. if (BaseMnemonic == NULL) {
  1924. DbgpArmDecodeUndefined(Context);
  1925. return;
  1926. }
  1927. Rn = (Instruction & ARM_PARALLEL_ARITHMETIC_RN_MASK) >>
  1928. ARM_PARALLEL_ARITHMETIC_RN_SHIFT;
  1929. Rd = (Instruction & ARM_PARALLEL_ARITHMETIC_RD_MASK) >>
  1930. ARM_PARALLEL_ARITHMETIC_RD_SHIFT;
  1931. Rm = (Instruction & ARM_PARALLEL_ARITHMETIC_RM_MASK) >>
  1932. ARM_PARALLEL_ARITHMETIC_RM_SHIFT;
  1933. strcpy(Context->Mnemonic, BaseMnemonic);
  1934. strcpy(Context->Operand1, DbgArmRegisterNames[Rd]);
  1935. strcpy(Context->Operand2, DbgArmRegisterNames[Rn]);
  1936. strcpy(Context->Operand3, DbgArmRegisterNames[Rm]);
  1937. return;
  1938. }
  1939. VOID
  1940. DbgpArmDecodePackingInstructions (
  1941. PARM_DISASSEMBLY Context
  1942. )
  1943. /*++
  1944. Routine Description:
  1945. This routine decodes the packing, unpacking, saturation, and reversal
  1946. instructions.
  1947. Arguments:
  1948. Context - Supplies a pointer to the disassembly context.
  1949. Return Value:
  1950. None.
  1951. --*/
  1952. {
  1953. ARM_DECODE_WITH_TABLE(Context, DbgArmPackingInstructionTable);
  1954. return;
  1955. }
  1956. VOID
  1957. DbgpArmDecodeExtensionWithRotation (
  1958. PARM_DISASSEMBLY Context
  1959. )
  1960. /*++
  1961. Routine Description:
  1962. This routine decodes extension with rotation instructions.
  1963. Arguments:
  1964. Context - Supplies a pointer to the disassembly context.
  1965. Return Value:
  1966. None.
  1967. --*/
  1968. {
  1969. PSTR BaseMnemonic;
  1970. ULONG Instruction;
  1971. ULONG Op1;
  1972. ULONG Rd;
  1973. ULONG Rm;
  1974. PSTR RmString;
  1975. ULONG Rn;
  1976. ULONG Rotation;
  1977. PSTR RotationString;
  1978. BOOL TwoRegisters;
  1979. Instruction = Context->Instruction;
  1980. Rn = (Instruction & ARM_PACKING_RN_MASK) >> ARM_PACKING_RN_SHIFT;
  1981. Rd = (Instruction & ARM_PACKING_RD_MASK) >> ARM_PACKING_RD_SHIFT;
  1982. Rm = (Instruction & ARM_PACKING_RM_MASK) >> ARM_PACKING_RM_SHIFT;
  1983. Op1 = (Instruction & ARM_PACKING_OP1_MASK) >> ARM_PACKING_OP1_SHIFT;
  1984. TwoRegisters = FALSE;
  1985. if (Rn == 0xF) {
  1986. BaseMnemonic = DbgArmExtensionRotationMnemonics[1][Op1];
  1987. RmString = Context->Operand2;
  1988. RotationString = Context->Operand3;
  1989. TwoRegisters = TRUE;
  1990. } else {
  1991. BaseMnemonic = DbgArmExtensionRotationMnemonics[0][Op1];
  1992. RmString = Context->Operand3;
  1993. RotationString = Context->Operand4;
  1994. }
  1995. Rotation = (Instruction & ARM_PACKING_ROTATION_MASK) >>
  1996. ARM_PACKING_ROTATION_SHIFT;
  1997. Rotation <<= 3;
  1998. //
  1999. // If no mnemonic was found for the given op value, then the instruction is
  2000. // undefined.
  2001. //
  2002. if (BaseMnemonic == NULL) {
  2003. DbgpArmDecodeUndefined(Context);
  2004. return;
  2005. }
  2006. strcpy(Context->Mnemonic, BaseMnemonic);
  2007. strcpy(Context->Operand1, DbgArmRegisterNames[Rd]);
  2008. if (TwoRegisters == FALSE) {
  2009. strcpy(Context->Operand2, DbgArmRegisterNames[Rn]);
  2010. }
  2011. strcpy(RmString, DbgArmRegisterNames[Rm]);
  2012. if (Rotation != 0) {
  2013. sprintf(RotationString, "%s #%d", ARM_ROR_MNEMONIC, Rotation);
  2014. }
  2015. return;
  2016. }
  2017. VOID
  2018. DbgpArmDecodeSelectBytes (
  2019. PARM_DISASSEMBLY Context
  2020. )
  2021. /*++
  2022. Routine Description:
  2023. This routine decodes the select byte instruction.
  2024. Arguments:
  2025. Context - Supplies a pointer to the disassembly context.
  2026. Return Value:
  2027. None.
  2028. --*/
  2029. {
  2030. ULONG Instruction;
  2031. ULONG Rd;
  2032. ULONG Rm;
  2033. ULONG Rn;
  2034. Instruction = Context->Instruction;
  2035. Rn = (Instruction & ARM_PACKING_RN_MASK) >> ARM_PACKING_RN_SHIFT;
  2036. Rd = (Instruction & ARM_PACKING_RD_MASK) >> ARM_PACKING_RD_SHIFT;
  2037. Rm = (Instruction & ARM_PACKING_RM_MASK) >> ARM_PACKING_RM_SHIFT;
  2038. strcpy(Context->Mnemonic, ARM_SEL_MNEMONIC);
  2039. strcpy(Context->Operand1, DbgArmRegisterNames[Rd]);
  2040. strcpy(Context->Operand2, DbgArmRegisterNames[Rn]);
  2041. strcpy(Context->Operand3, DbgArmRegisterNames[Rm]);
  2042. return;
  2043. }
  2044. VOID
  2045. DbgpArmDecodePackHalfword (
  2046. PARM_DISASSEMBLY Context
  2047. )
  2048. /*++
  2049. Routine Description:
  2050. This routine decodes the pack halfword instructions.
  2051. Arguments:
  2052. Context - Supplies a pointer to the disassembly context.
  2053. Return Value:
  2054. None.
  2055. --*/
  2056. {
  2057. PSTR BaseMnemonic;
  2058. ULONG Immediate;
  2059. ULONG Instruction;
  2060. ULONG Rd;
  2061. ULONG Rm;
  2062. ULONG Rn;
  2063. PSTR ShiftMnemonic;
  2064. Instruction = Context->Instruction;
  2065. Rn = (Instruction & ARM_PACKING_RN_MASK) >> ARM_PACKING_RN_SHIFT;
  2066. Rd = (Instruction & ARM_PACKING_RD_MASK) >> ARM_PACKING_RD_SHIFT;
  2067. Rm = (Instruction & ARM_PACKING_RM_MASK) >> ARM_PACKING_RM_SHIFT;
  2068. Immediate = (Instruction & ARM_PACKING_IMMEDIATE5_MASK) >>
  2069. ARM_PACKING_IMMEDIATE5_SHIFT;
  2070. if ((Instruction & ARM_PACKING_TB_BIT) != 0) {
  2071. BaseMnemonic = ARM_PKHTB_MNEMONIC;
  2072. ShiftMnemonic = ARM_ASR_MNEMONIC;
  2073. if (Immediate == 0) {
  2074. Immediate = 32;
  2075. }
  2076. } else {
  2077. BaseMnemonic = ARM_PKHBT_MNEMONIC;
  2078. ShiftMnemonic = ARM_LSL_MNEMONIC;
  2079. }
  2080. strcpy(Context->Mnemonic, BaseMnemonic);
  2081. strcpy(Context->Operand1, DbgArmRegisterNames[Rd]);
  2082. strcpy(Context->Operand2, DbgArmRegisterNames[Rn]);
  2083. strcpy(Context->Operand3, DbgArmRegisterNames[Rm]);
  2084. if (Immediate != 0) {
  2085. sprintf(Context->Operand4, "%s #%d", ShiftMnemonic, Immediate);
  2086. }
  2087. return;
  2088. }
  2089. VOID
  2090. DbgpArmDecodeReverse (
  2091. PARM_DISASSEMBLY Context
  2092. )
  2093. /*++
  2094. Routine Description:
  2095. This routine decodes the reverse instructions.
  2096. Arguments:
  2097. Context - Supplies a pointer to the disassembly context.
  2098. Return Value:
  2099. None.
  2100. --*/
  2101. {
  2102. PSTR BaseMnemonic;
  2103. ULONG Instruction;
  2104. ULONG Op1;
  2105. ULONG Op2;
  2106. ULONG Rd;
  2107. ULONG ReverseIndex;
  2108. ULONG Rm;
  2109. Instruction = Context->Instruction;
  2110. Rd = (Instruction & ARM_PACKING_RD_MASK) >> ARM_PACKING_RD_SHIFT;
  2111. Rm = (Instruction & ARM_PACKING_RM_MASK) >> ARM_PACKING_RM_SHIFT;
  2112. Op1 = (Instruction & ARM_PACKING_OP1_MASK) >> ARM_PACKING_OP1_SHIFT;
  2113. Op2 = (Instruction & ARM_PACKING_OP2_MASK) >> ARM_PACKING_OP2_SHIFT;
  2114. ReverseIndex = (Op1 & ARM_PACKING_OP1_REV_MASK) >>
  2115. ARM_PACKING_OP1_REV_SHIFT;
  2116. ReverseIndex |= ((Op2 & ARM_PACKING_OP2_REV_MASK) >>
  2117. ARM_PACKING_OP2_REV_SHIFT) << 1;
  2118. BaseMnemonic = DbgArmReverseMnemonics[ReverseIndex];
  2119. strcpy(Context->Mnemonic, BaseMnemonic);
  2120. strcpy(Context->Operand1, DbgArmRegisterNames[Rd]);
  2121. strcpy(Context->Operand2, DbgArmRegisterNames[Rm]);
  2122. return;
  2123. }
  2124. VOID
  2125. DbgpArmDecodeSaturate (
  2126. PARM_DISASSEMBLY Context
  2127. )
  2128. /*++
  2129. Routine Description:
  2130. This routine decodes the saturate instructions.
  2131. Arguments:
  2132. Context - Supplies a pointer to the disassembly context.
  2133. Return Value:
  2134. None.
  2135. --*/
  2136. {
  2137. ULONG Instruction;
  2138. PSTR MnemonicPrefix;
  2139. PSTR MnemonicSuffix;
  2140. ULONG Rd;
  2141. ULONG Rm;
  2142. ULONG SaturateImmediate;
  2143. ULONG ShiftImmediate;
  2144. PSTR ShiftMnemonic;
  2145. Instruction = Context->Instruction;
  2146. Rd = (Instruction & ARM_PACKING_RD_MASK) >> ARM_PACKING_RD_SHIFT;
  2147. Rm = (Instruction & ARM_PACKING_RM_MASK) >> ARM_PACKING_RM_SHIFT;
  2148. SaturateImmediate = (Instruction & ARM_PACKING_SAT_IMMEDIATE_MASK) >>
  2149. ARM_PACKING_SAT_IMMEDIATE_SHIFT;
  2150. MnemonicPrefix = ARM_USAT_MNEMONIC;
  2151. if ((Instruction & ARM_PACKING_SAT_UNSIGNED) == 0) {
  2152. SaturateImmediate += 1;
  2153. MnemonicPrefix = ARM_SSAT_MNEMONIC;
  2154. }
  2155. //
  2156. // If this is a two 16-bit saturate, then there is no shift at the end.
  2157. //
  2158. ShiftImmediate = 0;
  2159. MnemonicSuffix = ARM_SAT16_MNEMONIC;
  2160. if ((Instruction & ARM_PACKING_SAT16_BIT) == 0) {
  2161. MnemonicSuffix = "";
  2162. ShiftImmediate = (Instruction & ARM_PACKING_IMMEDIATE5_MASK) >>
  2163. ARM_PACKING_IMMEDIATE5_SHIFT;
  2164. ShiftMnemonic = ARM_LSL_MNEMONIC;
  2165. if ((Instruction & ARM_PACKING_SHIFT_BIT) != 0) {
  2166. ShiftMnemonic = ARM_ASR_MNEMONIC;
  2167. if (ShiftImmediate == 0) {
  2168. ShiftImmediate = 32;
  2169. }
  2170. }
  2171. }
  2172. sprintf(Context->Mnemonic,
  2173. "%s%s%s",
  2174. MnemonicPrefix,
  2175. ARM_SAT_MNEMONIC,
  2176. MnemonicSuffix);
  2177. strcpy(Context->Operand1, DbgArmRegisterNames[Rd]);
  2178. sprintf(Context->Operand2, "#%d", SaturateImmediate);
  2179. strcpy(Context->Operand3, DbgArmRegisterNames[Rm]);
  2180. if (ShiftImmediate != 0) {
  2181. sprintf(Context->Operand4, "%s #%d", ShiftMnemonic, ShiftImmediate);
  2182. }
  2183. return;
  2184. }
  2185. VOID
  2186. DbgpArmDecodeSumofAbsoluteDifferences (
  2187. PARM_DISASSEMBLY Context
  2188. )
  2189. /*++
  2190. Routine Description:
  2191. This routine decodes the sum of absolute differences instruction.
  2192. Arguments:
  2193. Context - Supplies a pointer to the disassembly context.
  2194. Return Value:
  2195. None.
  2196. --*/
  2197. {
  2198. PSTR BaseMnemonic;
  2199. ULONG Instruction;
  2200. ULONG RegisterA;
  2201. ULONG RegisterD;
  2202. ULONG RegisterM;
  2203. ULONG RegisterN;
  2204. BOOL ThreeOperands;
  2205. Instruction = Context->Instruction;
  2206. RegisterA = (Instruction & ARM_USAD_RA_MASK) >> ARM_USAD_RA_SHIFT;
  2207. RegisterD = (Instruction & ARM_USAD_RD_MASK) >> ARM_USAD_RD_SHIFT;
  2208. RegisterM = (Instruction & ARM_USAD_RM_MASK) >> ARM_USAD_RM_SHIFT;
  2209. RegisterN = (Instruction & ARM_USAD_RN_MASK) >> ARM_USAD_RN_SHIFT;
  2210. if (RegisterD == 0xF) {
  2211. BaseMnemonic = ARM_USAD_MNEMONIC;
  2212. ThreeOperands = TRUE;
  2213. } else {
  2214. BaseMnemonic = ARM_USADA_MNEMONIC;
  2215. ThreeOperands = FALSE;
  2216. }
  2217. strcpy(Context->Mnemonic, BaseMnemonic);
  2218. strcpy(Context->Operand1, DbgArmRegisterNames[RegisterD]);
  2219. strcpy(Context->Operand2, DbgArmRegisterNames[RegisterN]);
  2220. strcpy(Context->Operand3, DbgArmRegisterNames[RegisterM]);
  2221. if (ThreeOperands == FALSE) {
  2222. strcpy(Context->Operand1, DbgArmRegisterNames[RegisterA]);
  2223. }
  2224. return;
  2225. }
  2226. VOID
  2227. DbgpArmDecodeBitFieldInstructions (
  2228. PARM_DISASSEMBLY Context
  2229. )
  2230. /*++
  2231. Routine Description:
  2232. This routine decodes the bit field instructions.
  2233. Arguments:
  2234. Context - Supplies a pointer to the disassembly context.
  2235. Return Value:
  2236. None.
  2237. --*/
  2238. {
  2239. PSTR BaseMnemonic;
  2240. ULONG Instruction;
  2241. ULONG Lsb;
  2242. PSTR LsbString;
  2243. BOOL OneRegister;
  2244. ULONG RegisterD;
  2245. ULONG RegisterN;
  2246. ULONG Width;
  2247. Instruction = Context->Instruction;
  2248. RegisterD = (Instruction & ARM_BIT_FIELD_RD_MASK) >> ARM_BIT_FIELD_RD_SHIFT;
  2249. RegisterN = (Instruction & ARM_BIT_FIELD_RN_MASK) >> ARM_BIT_FIELD_RN_SHIFT;
  2250. Lsb = (Instruction & ARM_BIT_FIELD_LSB_MASK) >> ARM_BIT_FIELD_LSB_SHIFT;
  2251. Width = (Instruction & ARM_BIT_FIELD_WIDTH_MINUS_1_MASK) >>
  2252. ARM_BIT_FIELD_WIDTH_MINUS_1_SHIFT;
  2253. Width += 1;
  2254. OneRegister = FALSE;
  2255. if ((Instruction & ARM_BIT_FIELD_EXTRACT_BIT) != 0) {
  2256. if ((Instruction & ARM_BIT_FIELD_UNSIGNED_BIT) != 0) {
  2257. BaseMnemonic = ARM_UBFX_MNEMONIC;
  2258. } else {
  2259. BaseMnemonic = ARM_SBFX_MNEMONIC;
  2260. }
  2261. } else {
  2262. if (RegisterN == 0xF) {
  2263. BaseMnemonic = ARM_BFC_MNEMONIC;
  2264. OneRegister = TRUE;
  2265. } else {
  2266. BaseMnemonic = ARM_BFI_MNEMONIC;
  2267. }
  2268. Width -= Lsb;
  2269. }
  2270. strcpy(Context->Mnemonic, BaseMnemonic);
  2271. strcpy(Context->Operand1, DbgArmRegisterNames[RegisterD]);
  2272. if (OneRegister == FALSE) {
  2273. strcpy(Context->Operand2, DbgArmRegisterNames[RegisterN]);
  2274. LsbString = Context->Operand3;
  2275. } else {
  2276. LsbString = Context->Operand2;
  2277. }
  2278. sprintf(LsbString, "#%d, #%d", Lsb, Width);
  2279. return;
  2280. }
  2281. VOID
  2282. DbgpArmDecodePermanentlyUndefined (
  2283. PARM_DISASSEMBLY Context
  2284. )
  2285. /*++
  2286. Routine Description:
  2287. This routine decodes the permanently undefined instruction.
  2288. Arguments:
  2289. Context - Supplies a pointer to the disassembly context.
  2290. Return Value:
  2291. None.
  2292. --*/
  2293. {
  2294. ULONG Value;
  2295. strcpy(Context->Mnemonic, ARM_UNDEFINED_INSTRUCTION_MNEMONIC);
  2296. Value = ARM_SERVICE_BUILD_IMMEDIATE12_4(Context->Instruction);
  2297. sprintf(Context->Operand1, "#%d ; 0x%x", Value, Value);
  2298. return;
  2299. }
  2300. VOID
  2301. DbgpArmDecodeLoadStore (
  2302. PARM_DISASSEMBLY Context
  2303. )
  2304. /*++
  2305. Routine Description:
  2306. This routine decodes a load/store to a word or single byte.
  2307. Arguments:
  2308. Context - Supplies a pointer to the disassembly context.
  2309. Return Value:
  2310. None.
  2311. --*/
  2312. {
  2313. PSTR BaseMnemonic;
  2314. UCHAR BaseRegister;
  2315. UCHAR DestinationRegister;
  2316. ULONG Instruction;
  2317. PSTR MnemonicSuffix;
  2318. ULONG Offset;
  2319. UCHAR OffsetRegister;
  2320. CHAR ShiftString[15];
  2321. UCHAR ShiftValue;
  2322. UCHAR Sign;
  2323. UCHAR WriteBack;
  2324. BaseMnemonic = "";
  2325. MnemonicSuffix = "";
  2326. Instruction = Context->Instruction;
  2327. //
  2328. // Get the destination register.
  2329. //
  2330. DestinationRegister = (Instruction & ARM_DESTINATION_REGISTER_MASK) >>
  2331. ARM_DESTINATION_REGISTER_SHIFT;
  2332. //
  2333. // Determine the mnemonic.
  2334. //
  2335. if ((Instruction & ARM_LOAD_BIT) != 0) {
  2336. BaseMnemonic = ARM_LOAD_MNEMONIC;
  2337. } else {
  2338. BaseMnemonic = ARM_STORE_MNEMONIC;
  2339. }
  2340. //
  2341. // Determine the suffix. The translate bit only applies if P == 0.
  2342. //
  2343. if ((Instruction & ARM_LOAD_STORE_BYTE_BIT) != 0) {
  2344. if (((Instruction & ARM_PREINDEX_BIT) == 0) &&
  2345. ((Instruction & ARM_LOAD_STORE_TRANSLATE_BIT) != 0)) {
  2346. MnemonicSuffix = ARM_TRANSLATE_BYTE_SUFFIX;
  2347. } else {
  2348. MnemonicSuffix = ARM_BYTE_TRANSFER_SUFFIX;
  2349. }
  2350. } else if (((Instruction & ARM_PREINDEX_BIT) == 0) &&
  2351. ((Instruction & ARM_LOAD_STORE_TRANSLATE_BIT) != 0)) {
  2352. MnemonicSuffix = ARM_TRANSLATE_SUFFIX;
  2353. }
  2354. sprintf(Context->Mnemonic, "%s%s", BaseMnemonic, MnemonicSuffix);
  2355. //
  2356. // For immediate and register offsets, determine the sign of the offset.
  2357. //
  2358. if ((Instruction & ARM_ADD_SUBTRACT_BIT) != 0) {
  2359. Sign = '+';
  2360. } else {
  2361. Sign = '-';
  2362. }
  2363. //
  2364. // For pre-index and offset modes, determine whether a writeback is
  2365. // performed.
  2366. //
  2367. WriteBack = 0;
  2368. if ((Instruction & ARM_WRITE_BACK_BIT) != 0) {
  2369. WriteBack = '!';
  2370. }
  2371. BaseRegister = (Instruction & ARM_LOAD_STORE_BASE_MASK) >>
  2372. ARM_LOAD_STORE_BASE_SHIFT;
  2373. //
  2374. // Print the operand in the correct addressing form. There are 9 unique
  2375. // forms. Start with the immediate bit, which when 0 means the immediate
  2376. // form is used.
  2377. //
  2378. if ((Instruction & ARM_IMMEDIATE_BIT) == 0) {
  2379. Offset = Instruction & 0x00000FFF;
  2380. //
  2381. // Post-Indexed addressing.
  2382. //
  2383. if ((Instruction & ARM_PREINDEX_BIT) == 0) {
  2384. if (Offset == 0) {
  2385. sprintf(Context->Operand2,
  2386. "[%s]",
  2387. DbgArmRegisterNames[BaseRegister]);
  2388. } else {
  2389. sprintf(Context->Operand2,
  2390. "[%s], #%c%d",
  2391. DbgArmRegisterNames[BaseRegister],
  2392. Sign,
  2393. Offset);
  2394. }
  2395. //
  2396. // Pre-indexed or offset addressing.
  2397. //
  2398. } else {
  2399. if (Offset == 0) {
  2400. sprintf(Context->Operand2,
  2401. "[%s]%c",
  2402. DbgArmRegisterNames[BaseRegister],
  2403. WriteBack);
  2404. } else {
  2405. sprintf(Context->Operand2,
  2406. "[%s, #%c%d]%c",
  2407. DbgArmRegisterNames[BaseRegister],
  2408. Sign,
  2409. Offset,
  2410. WriteBack);
  2411. }
  2412. }
  2413. //
  2414. // Register offset/index or scaled register offset/index.
  2415. //
  2416. } else {
  2417. //
  2418. // Decode the shifted register string.
  2419. //
  2420. OffsetRegister = Instruction & ARM_OFFSET_REGISTER;
  2421. ShiftValue = (Instruction & ARM_LOAD_STORE_SHIFT_VALUE_MASK) >>
  2422. ARM_LOAD_STORE_SHIFT_VALUE_SHIFT;
  2423. DbgpArmDecodeImmediateShift(ShiftString,
  2424. sizeof(ShiftString),
  2425. OffsetRegister,
  2426. (Instruction & ARM_SHIFT_TYPE),
  2427. ShiftValue);
  2428. //
  2429. // Check out the pre-index bit. If it's zero, the addressing mode is
  2430. // post-indexed.
  2431. //
  2432. if ((Instruction & ARM_PREINDEX_BIT) == 0) {
  2433. sprintf(Context->Operand2,
  2434. "[%s], %c%s",
  2435. DbgArmRegisterNames[BaseRegister],
  2436. Sign,
  2437. ShiftString);
  2438. //
  2439. // Pre-indexed or offset addressing.
  2440. //
  2441. } else {
  2442. sprintf(Context->Operand2,
  2443. "[%s, %c%s]%c",
  2444. DbgArmRegisterNames[BaseRegister],
  2445. Sign,
  2446. ShiftString,
  2447. WriteBack);
  2448. }
  2449. }
  2450. //
  2451. // Write the first operand.
  2452. //
  2453. strcpy(Context->Operand1, DbgArmRegisterNames[DestinationRegister]);
  2454. return;
  2455. }
  2456. VOID
  2457. DbgpArmDecodeExtraLoadStore (
  2458. PARM_DISASSEMBLY Context
  2459. )
  2460. /*++
  2461. Routine Description:
  2462. This routine decodes an "extra load/store" in both the register and
  2463. immediate forms.
  2464. Arguments:
  2465. Context - Supplies a pointer to the disassembly context.
  2466. Return Value:
  2467. None.
  2468. --*/
  2469. {
  2470. PSTR BaseMnemonic;
  2471. UCHAR BaseRegister;
  2472. UCHAR DestinationRegister;
  2473. ULONG Instruction;
  2474. PSTR MnemonicSuffix;
  2475. UCHAR Offset;
  2476. UCHAR OffsetRegister;
  2477. UCHAR Sign;
  2478. UCHAR WriteBack;
  2479. BaseMnemonic = "ERR";
  2480. MnemonicSuffix = "";
  2481. Instruction = Context->Instruction;
  2482. //
  2483. // Determine whether or not this is a load or store, and what data size it
  2484. // is.
  2485. //
  2486. switch (Instruction & ARM_HALF_WORD_TRANSFER_MASK) {
  2487. case ARM_STORE_HALF_WORD:
  2488. BaseMnemonic = ARM_STORE_MNEMONIC;
  2489. MnemonicSuffix = ARM_HALF_WORD_SUFFIX;
  2490. break;
  2491. case ARM_LOAD_DOUBLE_WORD:
  2492. BaseMnemonic = ARM_LOAD_MNEMONIC;
  2493. MnemonicSuffix = ARM_DOUBLE_WORD_SUFFIX;
  2494. break;
  2495. case ARM_STORE_DOUBLE_WORD:
  2496. BaseMnemonic = ARM_STORE_MNEMONIC;
  2497. MnemonicSuffix = ARM_DOUBLE_WORD_SUFFIX;
  2498. break;
  2499. case ARM_LOAD_UNSIGNED_HALF_WORD:
  2500. BaseMnemonic = ARM_LOAD_MNEMONIC;
  2501. MnemonicSuffix = ARM_HALF_WORD_SUFFIX;
  2502. break;
  2503. case ARM_LOAD_SIGNED_BYTE:
  2504. BaseMnemonic = ARM_LOAD_MNEMONIC;
  2505. MnemonicSuffix = ARM_SIGNED_BYTE_SUFFIX;
  2506. break;
  2507. case ARM_LOAD_SIGNED_HALF_WORD:
  2508. BaseMnemonic = ARM_LOAD_MNEMONIC;
  2509. MnemonicSuffix = ARM_SIGNED_HALF_WORD_SUFFIX;
  2510. break;
  2511. //
  2512. // Invalid configuration.
  2513. //
  2514. default:
  2515. return;
  2516. }
  2517. snprintf(Context->Mnemonic,
  2518. ARM_OPERAND_LENGTH,
  2519. "%s%s",
  2520. BaseMnemonic,
  2521. MnemonicSuffix);
  2522. //
  2523. // Determine whether to add or subtract the offset.
  2524. //
  2525. if ((Instruction & ARM_ADD_SUBTRACT_BIT) != 0) {
  2526. Sign = '+';
  2527. } else {
  2528. Sign = '-';
  2529. }
  2530. //
  2531. // For pre-indexed addressing modes, determine whether or not the calculated
  2532. // address is written back. (If it's not, that's called offset addressing).
  2533. //
  2534. WriteBack = 0;
  2535. if ((Instruction & ARM_WRITE_BACK_BIT) != 0) {
  2536. WriteBack = '!';
  2537. }
  2538. //
  2539. // Print the destination register in the first operand.
  2540. //
  2541. DestinationRegister = (Instruction & ARM_DESTINATION_REGISTER_MASK) >>
  2542. ARM_DESTINATION_REGISTER_SHIFT;
  2543. sprintf(Context->Operand1, "%s", DbgArmRegisterNames[DestinationRegister]);
  2544. BaseRegister = (Instruction & 0x000F0000) >> 16;
  2545. //
  2546. // Handle the register form.
  2547. //
  2548. if ((Instruction & ARM_HALF_WORD_REGISTER_MASK) ==
  2549. ARM_HALF_WORD_REGISTER_VALUE) {
  2550. OffsetRegister = Instruction & 0x0000000F;
  2551. //
  2552. // If P is 0, then it's post-indexed addressing. W had better be zero
  2553. // in this case. Post-indexed addressing means the base register is
  2554. // used as the address, then the offset register is added to the base
  2555. // and written back to the base. It takes the form of [Rn], +/-Rm.
  2556. //
  2557. if ((Instruction & ARM_PREINDEX_BIT) == 0) {
  2558. if ((Instruction & ARM_WRITE_BACK_BIT) != 0) {
  2559. return;
  2560. }
  2561. sprintf(Context->Operand2,
  2562. "[%s], %c%s",
  2563. DbgArmRegisterNames[BaseRegister],
  2564. Sign,
  2565. DbgArmRegisterNames[OffsetRegister]);
  2566. //
  2567. // P is 1, which means the addressing form is either pre-indexed or
  2568. // offset based. Pre-indexed means the offset register is added to the
  2569. // base to form the address, and is then written back. Offset addressing
  2570. // is the same but no writeback is performed.
  2571. //
  2572. } else {
  2573. sprintf(Context->Operand2,
  2574. "[%s, %c%s]%c",
  2575. DbgArmRegisterNames[BaseRegister],
  2576. Sign,
  2577. DbgArmRegisterNames[OffsetRegister],
  2578. WriteBack);
  2579. }
  2580. //
  2581. // Handle the immediate form.
  2582. //
  2583. } else {
  2584. Offset = ((Instruction & 0x00000F00) >> 4) | (Instruction & 0x0000000F);
  2585. //
  2586. // Like in the register form, P == 0 indicates post-indexed addressing.
  2587. // W must be zero (just don't print if it it's not).
  2588. //
  2589. if ((Instruction & ARM_PREINDEX_BIT) == 0) {
  2590. sprintf(Context->Operand2,
  2591. "[%s], #%c%d",
  2592. DbgArmRegisterNames[BaseRegister],
  2593. Sign,
  2594. Offset);
  2595. //
  2596. // Like the register case P == 1 means the addressing form is either
  2597. // pre-indexed or offset based, depending on the U bit. If it is
  2598. // offset based (i.e. no write-back) and the offset is zero, don't
  2599. // print the offset.
  2600. //
  2601. } else if ((WriteBack == 0) && (Offset == 0)) {
  2602. sprintf(Context->Operand2,
  2603. "[%s]",
  2604. DbgArmRegisterNames[BaseRegister]);
  2605. } else {
  2606. sprintf(Context->Operand2,
  2607. "[%s, #%c%d]%c",
  2608. DbgArmRegisterNames[BaseRegister],
  2609. Sign,
  2610. Offset,
  2611. WriteBack);
  2612. }
  2613. }
  2614. return;
  2615. }
  2616. VOID
  2617. DbgpArmDecodeLoadStoreMultiple (
  2618. PARM_DISASSEMBLY Context
  2619. )
  2620. /*++
  2621. Routine Description:
  2622. This routine decodes a block load or store of multiple registers.
  2623. Arguments:
  2624. Context - Supplies a pointer to the disassembly context.
  2625. Return Value:
  2626. None.
  2627. --*/
  2628. {
  2629. PSTR BaseMnemonic;
  2630. ULONG Instruction;
  2631. PSTR MnemonicSuffix;
  2632. ULONG Operation;
  2633. BOOL PushPop;
  2634. UCHAR Register;
  2635. ULONG RegisterList;
  2636. ULONG RegisterListCount;
  2637. PSTR RegisterListString;
  2638. Instruction = Context->Instruction;
  2639. PushPop = FALSE;
  2640. Operation = Instruction & ARM_LOAD_STORE_OP_MASK;
  2641. Register = (Instruction & ARM_LOAD_STORE_REGISTER_MASK) >>
  2642. ARM_LOAD_STORE_REGISTER_SHIFT;
  2643. RegisterList = Instruction & ARM_REGISTER_LIST_MASK;
  2644. RegisterListCount = RtlCountSetBits32(RegisterList);
  2645. //
  2646. // If the instruction is targeting the stack register, then it may be a
  2647. // push or a pop.
  2648. //
  2649. if ((Register == ARM_STACK_REGISTER) &&
  2650. (RegisterListCount > 1) &&
  2651. ((Operation == ARM_LOAD_STORE_OP_POP) ||
  2652. (Operation == ARM_LOAD_STORE_OP_PUSH))) {
  2653. if ((Instruction & ARM_LOAD_BIT) != 0) {
  2654. BaseMnemonic = ARM_LOAD_POP_MNEMONIC;
  2655. } else {
  2656. BaseMnemonic = ARM_STORE_PUSH_MNEMONIC;
  2657. }
  2658. MnemonicSuffix = "";
  2659. PushPop = TRUE;
  2660. //
  2661. // Otherwise determine if it is a load or a store and get the appropriate
  2662. // suffix.
  2663. //
  2664. } else {
  2665. if ((Instruction & ARM_LOAD_BIT) != 0) {
  2666. BaseMnemonic = ARM_LOAD_MULTIPLE_MNEMONIC;
  2667. } else {
  2668. BaseMnemonic = ARM_STORE_MULTIPLE_MNEMONIC;
  2669. }
  2670. MnemonicSuffix = DbgpArmGetLoadStoreTypeString(Instruction);
  2671. }
  2672. snprintf(Context->Mnemonic,
  2673. ARM_OPERAND_LENGTH,
  2674. "%s%s",
  2675. BaseMnemonic,
  2676. MnemonicSuffix);
  2677. //
  2678. // Write the register (the first operand). Add the ! if the operation does
  2679. // a write back. Push/pop operations are always write back.
  2680. //
  2681. if (PushPop == FALSE) {
  2682. if ((Instruction & ARM_WRITE_BACK_BIT) != 0) {
  2683. sprintf(Context->Operand1, "%s!", DbgArmRegisterNames[Register]);
  2684. } else {
  2685. sprintf(Context->Operand1, "%s", DbgArmRegisterNames[Register]);
  2686. }
  2687. RegisterListString = Context->Operand2;
  2688. } else {
  2689. RegisterListString = Context->Operand1;
  2690. }
  2691. //
  2692. // Get the list of registers to be loaded or stored.
  2693. //
  2694. DbgpArmDecodeRegisterList(RegisterListString,
  2695. ARM_OPERAND_LENGTH,
  2696. RegisterList);
  2697. //
  2698. // Indicate whether or not the saved PSR (SPSR) should be used instead of
  2699. // the current PSR (CPSR). This is typically only used for returning from
  2700. // exceptions.
  2701. //
  2702. if ((Instruction & ARM_USE_SAVED_PSR_BIT) != 0) {
  2703. strcat(RegisterListString, "^");
  2704. }
  2705. return;
  2706. }
  2707. VOID
  2708. DbgpArmDecodeDataProcessing (
  2709. PARM_DISASSEMBLY Context
  2710. )
  2711. /*++
  2712. Routine Description:
  2713. This routine decodes a standard data processing instruction.
  2714. Arguments:
  2715. Context - Supplies a pointer to the disassembly context.
  2716. Return Value:
  2717. None.
  2718. --*/
  2719. {
  2720. PSTR BaseMnemonic;
  2721. UCHAR DestinationRegister;
  2722. UCHAR ImmediateShift;
  2723. ULONG ImmediateValue;
  2724. ULONG Instruction;
  2725. PSTR MnemonicSuffix;
  2726. UCHAR Opcode;
  2727. UCHAR Operand2Register;
  2728. UCHAR OperandRegister;
  2729. UCHAR ShiftRegister;
  2730. CHAR ShiftString[35];
  2731. PSTR ShiftType;
  2732. Instruction = Context->Instruction;
  2733. MnemonicSuffix = "";
  2734. ShiftString[0] = '\0';
  2735. //
  2736. // Get the opcode.
  2737. //
  2738. Opcode = (Instruction & ARM_DATA_PROCESSING_OP_MASK) >>
  2739. ARM_DATA_PROCESSING_OP_SHIFT;
  2740. //
  2741. // Ignore the low bit.
  2742. //
  2743. Opcode >>= 1;
  2744. BaseMnemonic = DbgArmDataProcessingMnemonics[Opcode];
  2745. //
  2746. // Determine whether to add the S bit. Compare instructions don't need the
  2747. // S because it's assumed (it's the whole point of a compare to set the
  2748. // flags).
  2749. //
  2750. if (((Instruction & ARM_SET_FLAGS_BIT) != 0) &&
  2751. ((Opcode < ARM_DATA_PROCESSING_COMPARE_INSTRUCTION_MIN) ||
  2752. (Opcode > ARM_DATA_PROCESSING_COMPARE_INSTRUCTION_MAX))) {
  2753. MnemonicSuffix = ARM_SET_FLAGS_MNEMONIC;
  2754. }
  2755. //
  2756. // Build the shift operand string.
  2757. //
  2758. if ((Context->Instruction & ARM_IMMEDIATE_BIT) != 0) {
  2759. //
  2760. // The immediate form takes an 8-bit integer and shifts it by any even
  2761. // number in the shift_imm bits.
  2762. //
  2763. ImmediateValue = Instruction & ARM_DATA_PROCESSING_IMMEDIATE8_MASK;
  2764. ImmediateShift = ((Instruction &
  2765. ARM_DATA_PROCESSING_IMMEDIATE_ROTATE_MASK) >>
  2766. ARM_DATA_PROCESSING_IMMEDIATE_ROTATE_SHIFT) * 2;
  2767. //
  2768. // Rotate the value right by the specified number of bits.
  2769. //
  2770. while (ImmediateShift > 0) {
  2771. ImmediateShift -= 1;
  2772. if ((ImmediateValue & 0x1) != 0) {
  2773. ImmediateValue = (ImmediateValue >> 1) | 0x80000000;
  2774. } else {
  2775. ImmediateValue = ImmediateValue >> 1;
  2776. }
  2777. }
  2778. sprintf(ShiftString, "#%d ; 0x%x", ImmediateValue, ImmediateValue);
  2779. } else {
  2780. Operand2Register = Instruction &
  2781. ARM_DATA_PROCESSING_OPERAND2_REGISTER_MASK;
  2782. //
  2783. // The register form can be shifted, by either an immediate or another
  2784. // register. Handle the register shift case first.
  2785. //
  2786. if ((Instruction &
  2787. ARM_DATA_PROCESSING_REGISTER_REGISTER_SHIFT_BIT) != 0) {
  2788. ShiftRegister = (Instruction &
  2789. ARM_DATA_PROCESSING_SHIFT_REGISTER_MASK) >>
  2790. ARM_DATA_PROCESSING_SHIFT_REGISTER_SHIFT;
  2791. ShiftType = "ERR";
  2792. switch (Instruction & ARM_SHIFT_TYPE) {
  2793. case ARM_SHIFT_LSL:
  2794. ShiftType = ARM_LSL_MNEMONIC;
  2795. break;
  2796. case ARM_SHIFT_LSR:
  2797. ShiftType = ARM_LSR_MNEMONIC;
  2798. break;
  2799. case ARM_SHIFT_ASR:
  2800. ShiftType = ARM_ASR_MNEMONIC;
  2801. break;
  2802. case ARM_SHIFT_ROR:
  2803. ShiftType = ARM_ROR_MNEMONIC;
  2804. break;
  2805. //
  2806. // This case should never hit since all 4 bit combinations were
  2807. // handled.
  2808. //
  2809. default:
  2810. break;
  2811. }
  2812. //
  2813. // If this is the move instruction, then the canonical form
  2814. // actually uses the shift mnemonic for the instruction mnemonic.
  2815. //
  2816. if (Opcode == ARM_DATA_PROCESSING_MOVE_OPCODE) {
  2817. BaseMnemonic = ShiftType;
  2818. sprintf(ShiftString,
  2819. "%s, %s",
  2820. DbgArmRegisterNames[Operand2Register],
  2821. DbgArmRegisterNames[ShiftRegister]);
  2822. } else {
  2823. sprintf(ShiftString,
  2824. "%s, %s %s",
  2825. DbgArmRegisterNames[Operand2Register],
  2826. ShiftType,
  2827. DbgArmRegisterNames[ShiftRegister]);
  2828. }
  2829. //
  2830. // Shift by an immediate value.
  2831. //
  2832. } else {
  2833. ImmediateValue = (Instruction &
  2834. ARM_DATA_PROCESSING_SHIFT_IMMEDIATE_MASK) >>
  2835. ARM_DATA_PROCESSING_SHIFT_IMMEDIATE_SHIFT;
  2836. //
  2837. // If this is a move instruction, then it may have a canonical
  2838. // form.
  2839. //
  2840. if (Opcode == ARM_DATA_PROCESSING_MOVE_OPCODE) {
  2841. ShiftType = NULL;
  2842. switch (Instruction & ARM_SHIFT_TYPE) {
  2843. case ARM_SHIFT_LSL:
  2844. if (ImmediateValue != 0) {
  2845. ShiftType = ARM_LSL_MNEMONIC;
  2846. }
  2847. break;
  2848. case ARM_SHIFT_LSR:
  2849. if (ImmediateValue == 0) {
  2850. ImmediateValue = 32;
  2851. }
  2852. ShiftType = ARM_LSR_MNEMONIC;
  2853. break;
  2854. case ARM_SHIFT_ASR:
  2855. if (ImmediateValue == 0) {
  2856. ImmediateValue = 32;
  2857. }
  2858. ShiftType = ARM_ASR_MNEMONIC;
  2859. break;
  2860. case ARM_SHIFT_ROR:
  2861. if (ImmediateValue == 0) {
  2862. ShiftType = ARM_RRX_MNEMONIC;
  2863. } else {
  2864. ShiftType = ARM_ROR_MNEMONIC;
  2865. }
  2866. break;
  2867. //
  2868. // This case should never hit since all 4 bit combinations were
  2869. // handled.
  2870. //
  2871. default:
  2872. break;
  2873. }
  2874. //
  2875. // If a shift type was set, then use the canonical form and
  2876. // override the base mnemonic.
  2877. //
  2878. if (ShiftType != NULL) {
  2879. BaseMnemonic = ShiftType;
  2880. }
  2881. //
  2882. // A MOV with no shift and RRX do no print an immediate value.
  2883. // There are the only cases where the immediate value is 0.
  2884. //
  2885. if (ImmediateValue == 0) {
  2886. sprintf(ShiftString,
  2887. "%s",
  2888. DbgArmRegisterNames[Operand2Register]);
  2889. } else {
  2890. sprintf(ShiftString,
  2891. "%s, #%d",
  2892. DbgArmRegisterNames[Operand2Register],
  2893. ImmediateValue);
  2894. }
  2895. } else {
  2896. DbgpArmDecodeImmediateShift(ShiftString,
  2897. sizeof(ShiftString),
  2898. Operand2Register,
  2899. (Instruction & ARM_SHIFT_TYPE),
  2900. ImmediateValue);
  2901. }
  2902. }
  2903. }
  2904. //
  2905. // Print out the mnemonic, it may have been modified while computing the
  2906. // shift string.
  2907. //
  2908. snprintf(Context->Mnemonic,
  2909. ARM_OPERAND_LENGTH,
  2910. "%s%s",
  2911. BaseMnemonic,
  2912. MnemonicSuffix);
  2913. DestinationRegister = (Instruction & ARM_DESTINATION_REGISTER_MASK) >>
  2914. ARM_DESTINATION_REGISTER_SHIFT;
  2915. OperandRegister = (Instruction &
  2916. ARM_DATA_PROCESSING_OPERAND_REGISTER_MASK) >>
  2917. ARM_DATA_PROCESSING_OPERAND_REGISTER_SHIFT;
  2918. //
  2919. // Print the operands depending on the opcode. Compare instructions take
  2920. // the form Rn, <shifter_operand>
  2921. //
  2922. if ((Opcode >= ARM_DATA_PROCESSING_COMPARE_INSTRUCTION_MIN) &&
  2923. (Opcode <= ARM_DATA_PROCESSING_COMPARE_INSTRUCTION_MAX)) {
  2924. strcpy(Context->Operand1, DbgArmRegisterNames[OperandRegister]);
  2925. strcpy(Context->Operand2, ShiftString);
  2926. //
  2927. // Move instructions take the form Rd, <shift_operand>.
  2928. //
  2929. } else if ((Opcode == ARM_DATA_PROCESSING_MOVE_OPCODE) ||
  2930. (Opcode == ARM_DATA_PROCESSING_MOVE_NOT_OPCODE)) {
  2931. strcpy(Context->Operand1, DbgArmRegisterNames[DestinationRegister]);
  2932. strcpy(Context->Operand2, ShiftString);
  2933. //
  2934. // All normal data processing instructions take the form Rd, Rn,
  2935. // <shift_operand>.
  2936. //
  2937. } else {
  2938. strcpy(Context->Operand1, DbgArmRegisterNames[DestinationRegister]);
  2939. strcpy(Context->Operand2, DbgArmRegisterNames[OperandRegister]);
  2940. strcpy(Context->Operand3, ShiftString);
  2941. }
  2942. return;
  2943. }
  2944. VOID
  2945. DbgpArmDecodeLoadImmediate (
  2946. PARM_DISASSEMBLY Context
  2947. )
  2948. /*++
  2949. Routine Description:
  2950. This routine decodes a 16-bit immediate load instruction.
  2951. Arguments:
  2952. Context - Supplies a pointer to the disassembly context.
  2953. Return Value:
  2954. None.
  2955. --*/
  2956. {
  2957. PSTR BaseMnemonic;
  2958. UCHAR DestinationRegister;
  2959. ULONG ImmediateValue;
  2960. ULONG Instruction;
  2961. Instruction = Context->Instruction;
  2962. //
  2963. // Get the opcode.
  2964. //
  2965. switch (Instruction & ARM_IMMEDIATE_LOAD_OP_MASK) {
  2966. case ARM_IMMEDIATE_LOAD_OP_MOVW:
  2967. BaseMnemonic = ARM_MOVW_MNEMONIC;
  2968. break;
  2969. case ARM_IMMEDIATE_LOAD_OP_MOVT:
  2970. BaseMnemonic = ARM_MOVT_MNEMONIC;
  2971. break;
  2972. //
  2973. // Invalid configuration.
  2974. //
  2975. default:
  2976. return;
  2977. }
  2978. snprintf(Context->Mnemonic,
  2979. ARM_OPERAND_LENGTH,
  2980. "%s",
  2981. BaseMnemonic);
  2982. //
  2983. // Build the immediate value string.
  2984. //
  2985. ImmediateValue = (Instruction & ARM_IMMEDIATE_LOAD_IMMEDIATE4_MASK) >>
  2986. ARM_IMMEDIATE_LOAD_IMMEDIATE4_SHIFT;
  2987. ImmediateValue <<= 12;
  2988. ImmediateValue |= ((Instruction & ARM_IMMEDIATE_LOAD_IMMEDIATE12_MASK) >>
  2989. ARM_IMMEDIATE_LOAD_IMMEDIATE12_SHIFT);
  2990. //
  2991. // Determine the destination register.
  2992. //
  2993. DestinationRegister = (Instruction & ARM_DESTINATION_REGISTER_MASK) >>
  2994. ARM_DESTINATION_REGISTER_SHIFT;
  2995. //
  2996. // The 16 immediate load instructions take the form Rn, <immediate_operand>
  2997. //
  2998. strcpy(Context->Operand1, DbgArmRegisterNames[DestinationRegister]);
  2999. sprintf(Context->Operand2, "#%d ; 0x%x", ImmediateValue, ImmediateValue);
  3000. return;
  3001. }
  3002. VOID
  3003. DbgpArmDecodeMiscellaneous (
  3004. PARM_DISASSEMBLY Context
  3005. )
  3006. /*++
  3007. Routine Description:
  3008. This routine decodes a miscellaneous instruction.
  3009. Arguments:
  3010. Context - Supplies a pointer to the disassembly context.
  3011. Return Value:
  3012. None.
  3013. --*/
  3014. {
  3015. ULONG Instruction;
  3016. PSTR Mnemonic;
  3017. ULONG Op;
  3018. ULONG Op2;
  3019. ULONG R0;
  3020. ULONG Rd;
  3021. LONG Value;
  3022. Mnemonic = "ERR";
  3023. Instruction = Context->Instruction;
  3024. Op2 = (Instruction & ARM_MISCELLANEOUS1_OP2_MASK) >>
  3025. ARM_MISCELLANEOUS1_OP2_SHIFT;
  3026. Op = (Instruction & ARM_MISCELLANEOUS1_OP_MASK) >>
  3027. ARM_MISCELLANEOUS1_OP_SHIFT;
  3028. R0 = Instruction & ARM_MOVE_STATUS_R0_MASK;
  3029. //
  3030. // Handle an MSR or MRS instruction.
  3031. //
  3032. if (Op2 == ARM_MISCELLANEOUS1_OP2_STATUS) {
  3033. Rd = (Instruction & ARM_MOVE_STATUS_RD_MASK) >>
  3034. ARM_MOVE_STATUS_RD_SHIFT;
  3035. //
  3036. // Handle an MSR.
  3037. //
  3038. if ((Op & ARM_MISCELLANEOUS1_OP_MSR) != 0) {
  3039. Mnemonic = ARM_MSR_MNEMONIC;
  3040. strcpy(Context->Operand2, DbgArmRegisterNames[R0]);
  3041. //
  3042. // Handle banked MSR vs non-banked.
  3043. //
  3044. if ((Instruction & ARM_MOVE_STATUS_BANKED) != 0) {
  3045. strcpy(Context->Operand1,
  3046. DbgpArmGetBankedRegisterString(Instruction));
  3047. } else {
  3048. DbgpArmPrintStatusRegister(Context->Operand1, Instruction);
  3049. }
  3050. //
  3051. // This is an MRS instruction.
  3052. //
  3053. } else {
  3054. Mnemonic = ARM_MRS_MNEMONIC;
  3055. strcpy(Context->Operand1, DbgArmRegisterNames[Rd]);
  3056. if ((Instruction & ARM_MOVE_STATUS_BANKED) != 0) {
  3057. strcpy(Context->Operand2,
  3058. DbgpArmGetBankedRegisterString(Instruction));
  3059. } else {
  3060. DbgpArmPrintStatusRegister(Context->Operand2, Instruction);
  3061. }
  3062. }
  3063. //
  3064. // Handle either a BX or CLZ.
  3065. //
  3066. } else if (Op2 == ARM_MISCELLANEOUS1_OP2_BX_CLZ) {
  3067. if (Op == ARM_MISCELLANEOUS1_OP_BX) {
  3068. Mnemonic = ARM_BX_MNEMONIC;
  3069. } else if (Op == ARM_MISCELLANEOUS1_OP_CLZ) {
  3070. Mnemonic = ARM_CLZ_MNEMONIC;
  3071. }
  3072. strcpy(Context->Operand1, DbgArmRegisterNames[R0]);
  3073. //
  3074. // Handle a BXJ (register).
  3075. //
  3076. } else if (Op2 == ARM_MISCELLANEOUS1_OP2_BXJ) {
  3077. Mnemonic = ARM_BXJ_MNEMONIC;
  3078. strcpy(Context->Operand1, DbgArmRegisterNames[R0]);
  3079. //
  3080. // Handle a BLX (register).
  3081. //
  3082. } else if (Op2 == ARM_MISCELLANEOUS1_OP2_BLX) {
  3083. Mnemonic = ARM_BLX_MNEMONIC;
  3084. strcpy(Context->Operand1, DbgArmRegisterNames[R0]);
  3085. //
  3086. // Handle (or don't) saturating addition or subtraction.
  3087. //
  3088. } else if (Op2 == ARM_MISCELLANEOUS1_OP2_SATURATING_ADDITION) {
  3089. //
  3090. // Handle a simple ERET.
  3091. //
  3092. } else if (Op2 == ARM_MISCELLANEOUS1_OP2_ERET) {
  3093. Mnemonic = ARM_ERET_MNEMONIC;
  3094. //
  3095. // Handle a service call: BKPT, HVC, or SMC.
  3096. //
  3097. } else if (Op2 == ARM_MISCELLANEOUS1_OP2_SERVICE) {
  3098. Value = ARM_SERVICE_BUILD_IMMEDIATE12_4(Instruction);
  3099. if ((Value & 0x00008000) != 0) {
  3100. Value |= 0xFFFF0000;
  3101. }
  3102. if (Op == ARM_MISCELLANEOUS1_OP_BKPT) {
  3103. Mnemonic = ARM_BKPT_MNEMONIC;
  3104. sprintf(Context->Operand1, "#%d", Value);
  3105. } else if (Op == ARM_MISCELLANEOUS1_OP_HVC) {
  3106. Mnemonic = ARM_HVC_MNEMONIC;
  3107. sprintf(Context->Operand1, "#%d", Value);
  3108. } else if (Op == ARM_MISCELLANEOUS1_OP_SMC) {
  3109. Mnemonic = ARM_SMC_MNEMONIC;
  3110. sprintf(Context->Operand1, "#%d", Value & 0xF);
  3111. }
  3112. }
  3113. strcpy(Context->Mnemonic, Mnemonic);
  3114. return;
  3115. }
  3116. VOID
  3117. DbgpArmDecodeMsrImmediateAndHints (
  3118. PARM_DISASSEMBLY Context
  3119. )
  3120. /*++
  3121. Routine Description:
  3122. This routine decodes an MSR immediate instruction or memory hints.
  3123. Arguments:
  3124. Context - Supplies a pointer to the disassembly context.
  3125. Return Value:
  3126. None.
  3127. --*/
  3128. {
  3129. LONG Immediate;
  3130. ULONG Instruction;
  3131. PSTR Mnemonic;
  3132. ULONG Op1;
  3133. ULONG Op2;
  3134. Mnemonic = "";
  3135. Instruction = Context->Instruction;
  3136. Op1 = (Instruction & ARM_HINTS_OP1_MASK) >> ARM_HINTS_OP1_SHIFT;
  3137. Op2 = Instruction & ARM_HINTS_OP2_MASK;
  3138. if (Op1 == ARM_HINTS_OP1_HINTS) {
  3139. if (Op2 == ARM_HINTS_OP2_NOP) {
  3140. Mnemonic = ARM_NOP_MNEMONIC;
  3141. } else if (Op2 == ARM_HINTS_OP2_YIELD) {
  3142. Mnemonic = ARM_YIELD_MNEMONIC;
  3143. } else if (Op2 == ARM_HINTS_OP2_WFE) {
  3144. Mnemonic = ARM_WFE_MNEMONIC;
  3145. } else if (Op2 == ARM_HINTS_OP2_WFI) {
  3146. Mnemonic = ARM_WFI_MNEMONIC;
  3147. } else if (Op2 == ARM_HINTS_OP2_SEV) {
  3148. Mnemonic = ARM_SEV_MNEMONIC;
  3149. } else if ((Op2 & ARM_HINTS_OP2_DBG_MASK) == ARM_HINTS_OP2_DBG_VALUE) {
  3150. Mnemonic = ARM_DBG_MNEMONIC;
  3151. sprintf(Context->Operand1,
  3152. "#%d",
  3153. Op2 & ARM_HINTS_OP2_DBG_OPTION_MASK);
  3154. }
  3155. //
  3156. // If not hints, then this is an MSR (immediate) instruction.
  3157. //
  3158. } else {
  3159. Mnemonic = ARM_MSR_MNEMONIC;
  3160. DbgpArmPrintStatusRegister(Context->Operand1, Instruction);
  3161. Immediate = Instruction & ARM_MSR_IMMEDIATE12_MASK;
  3162. if ((Immediate & 0x00001000) != 0) {
  3163. Immediate |= 0xFFFFF000;
  3164. }
  3165. sprintf(Context->Operand2, "#%d ; 0x%x", Immediate, Immediate);
  3166. }
  3167. strcpy(Context->Mnemonic, Mnemonic);
  3168. return;
  3169. }
  3170. VOID
  3171. DbgpArmDecodeMultiply (
  3172. PARM_DISASSEMBLY Context
  3173. )
  3174. /*++
  3175. Routine Description:
  3176. This routine decodes a multiply or long multiply instruction. This function
  3177. assumes that the instruction is in fact a multiply instruction.
  3178. Arguments:
  3179. Context - Supplies a pointer to the disassembly context.
  3180. Return Value:
  3181. None.
  3182. --*/
  3183. {
  3184. PSTR BaseMnemonic;
  3185. ULONG Instruction;
  3186. BOOL LongMultiply;
  3187. PSTR MnemonicSuffix;
  3188. PSTR MultiplyHalves;
  3189. PSTR PreConditionMnemonicSuffix;
  3190. UCHAR Rd;
  3191. UCHAR RdHigh;
  3192. UCHAR RdLow;
  3193. UCHAR Rm;
  3194. UCHAR Rn;
  3195. PSTR Rounded;
  3196. UCHAR Rs;
  3197. BOOL ThreeOperands;
  3198. PSTR XBit;
  3199. MultiplyHalves = NULL;
  3200. LongMultiply = FALSE;
  3201. Rounded = NULL;
  3202. ThreeOperands = FALSE;
  3203. XBit = NULL;
  3204. Instruction = Context->Instruction;
  3205. BaseMnemonic = "ERR";
  3206. PreConditionMnemonicSuffix = "";
  3207. MnemonicSuffix = "";
  3208. //
  3209. // Get the top and bottom bits. These bits aren't actually defined for all
  3210. // multiply instructions, so they'll get ignored in some cases.
  3211. //
  3212. if ((Instruction & ARM_MULTIPLY_SOURCE_HIGH) != 0) {
  3213. if ((Instruction & ARM_MULTIPLY_DESTINATION_HIGH) != 0) {
  3214. MultiplyHalves = ARM_MULTIPLY_TOP_TOP;
  3215. } else {
  3216. MultiplyHalves = ARM_MULTIPLY_TOP_BOTTOM;
  3217. }
  3218. } else {
  3219. if ((Instruction & ARM_MULTIPLY_DESTINATION_HIGH) != 0) {
  3220. MultiplyHalves = ARM_MULTIPLY_BOTTOM_TOP;
  3221. } else {
  3222. MultiplyHalves = ARM_MULTIPLY_BOTTOM_BOTTOM;
  3223. }
  3224. }
  3225. //
  3226. // Get the X bit, which indicates that the multiplications are
  3227. // bottom * top and top * bottom. If X is cleared, the multiplications are
  3228. // bottom * bottom and top * top.
  3229. //
  3230. if ((Instruction & ARM_MULTIPLY_X_BIT) != 0) {
  3231. XBit = ARM_MULTIPLY_X_MNEMONIC;
  3232. }
  3233. //
  3234. // Get the rounding bit, which indicates for a couple of instructions that
  3235. // the multiplication is rounded.
  3236. //
  3237. if ((Instruction & ARM_MULTIPLY_ROUND_BIT) != 0) {
  3238. Rounded = ARM_MULTIPLY_ROUND_MNEMONIC;
  3239. }
  3240. //
  3241. // For a non-long multiply, get the 4 registers.
  3242. //
  3243. Rd = (Instruction & ARM_MULTIPLY_RD_MASK) >> ARM_MULTIPLY_RD_SHIFT;
  3244. Rm = (Instruction & ARM_MULTIPLY_RM_MASK) >> ARM_MULTIPLY_RM_SHIFT;
  3245. Rn = (Instruction & ARM_MULTIPLY_RN_MASK) >> ARM_MULTIPLY_RN_SHIFT;
  3246. Rs = (Instruction & ARM_MULTIPLY_RS_MASK) >> ARM_MULTIPLY_RS_SHIFT;
  3247. //
  3248. // For long multiplies, get the high and low destination registers. Rs and
  3249. // Rm are the same as for non-long multiplies.
  3250. //
  3251. RdHigh = (Instruction & ARM_MULTIPLY_RD_HIGH_MASK) >>
  3252. ARM_MULTIPLY_RD_HIGH_SHIFT;
  3253. RdLow = (Instruction & ARM_MULTIPLY_RD_LOW_MASK) >>
  3254. ARM_MULTIPLY_RD_LOW_SHIFT;
  3255. //
  3256. // Get the mnemonic and characteristics of the instruction.
  3257. //
  3258. switch (Instruction & ARM_MULTIPLY_OPCODE_MASK) {
  3259. //
  3260. // Standard Multiply and accumulate.
  3261. //
  3262. case ARM_MLA_MASK | ARM_SET_FLAGS_BIT:
  3263. MnemonicSuffix = ARM_SET_FLAGS_MNEMONIC;
  3264. //
  3265. // Fall through.
  3266. //
  3267. case ARM_MLA_MASK:
  3268. BaseMnemonic = ARM_MLA_MNEMONIC;
  3269. break;
  3270. //
  3271. // Standard Multiply.
  3272. //
  3273. case ARM_MUL_MASK | ARM_SET_FLAGS_BIT:
  3274. MnemonicSuffix = ARM_SET_FLAGS_MNEMONIC;
  3275. //
  3276. // Fall through.
  3277. //
  3278. case ARM_MUL_MASK:
  3279. BaseMnemonic =ARM_MUL_MNEMONIC;
  3280. ThreeOperands = TRUE;
  3281. break;
  3282. //
  3283. // Signed half word multiply and accumulate.
  3284. //
  3285. case ARM_SMLA_MASK:
  3286. BaseMnemonic = ARM_SMLA_MNEMONIC;
  3287. PreConditionMnemonicSuffix = MultiplyHalves;
  3288. break;
  3289. //
  3290. // Signed half word multiply accumulate, dual,
  3291. // Signed half word multiply subtract, dual,
  3292. // Signed dual multiply add, and
  3293. // Signed dual multiply subtract.
  3294. //
  3295. case ARM_SMLXD_MASK:
  3296. if ((Instruction & ARM_SMLXD_OPCODE2_MASK) == ARM_SMLAD_OPCODE2_VALUE) {
  3297. if (Rn == 0xF) {
  3298. BaseMnemonic = ARM_SMUAD_MNEMONIC;
  3299. ThreeOperands = TRUE;
  3300. } else {
  3301. BaseMnemonic = ARM_SMLAD_MNEMONIC;
  3302. }
  3303. } else if ((Instruction & ARM_SMLXD_OPCODE2_MASK) ==
  3304. ARM_SMLSD_OPCODE2_VALUE) {
  3305. if (Rn == 0xF) {
  3306. BaseMnemonic = ARM_SMUSD_MNEMONIC;
  3307. ThreeOperands = TRUE;
  3308. } else {
  3309. BaseMnemonic = ARM_SMLSD_MNEMONIC;
  3310. }
  3311. } else {
  3312. return;
  3313. }
  3314. PreConditionMnemonicSuffix = XBit;
  3315. break;
  3316. //
  3317. // Signed half word by word, accumulate, and
  3318. // Signed multiply word B and T.
  3319. //
  3320. case ARM_SMLAW_SMULW_MASK:
  3321. if ((Instruction & ARM_SMULW_DIFFERENT_BIT) != 0) {
  3322. BaseMnemonic = ARM_SMULW_MNEMONIC;
  3323. ThreeOperands = TRUE;
  3324. } else {
  3325. BaseMnemonic = ARM_SMLAW_MNEMONIC;
  3326. }
  3327. if ((Instruction & ARM_MULTIPLY_DESTINATION_HIGH) != 0) {
  3328. PreConditionMnemonicSuffix = ARM_MULTIPLY_TOP;
  3329. } else {
  3330. PreConditionMnemonicSuffix = ARM_MULTIPLY_BOTTOM;
  3331. }
  3332. break;
  3333. //
  3334. // Signed multiply accumulate, long.
  3335. //
  3336. case ARM_SMLAL_MASK | ARM_SET_FLAGS_BIT:
  3337. PreConditionMnemonicSuffix = ARM_SET_FLAGS_MNEMONIC;
  3338. //
  3339. // Fall through.
  3340. //
  3341. case ARM_SMLAL_MASK:
  3342. BaseMnemonic = ARM_SMLAL_MNEMONIC;
  3343. LongMultiply = TRUE;
  3344. break;
  3345. //
  3346. // Signed halfword multiply accumulate, long.
  3347. //
  3348. case ARM_SMLAL_XY_MASK:
  3349. BaseMnemonic = ARM_SMLAL_MNEMONIC;
  3350. PreConditionMnemonicSuffix = MultiplyHalves;
  3351. LongMultiply = TRUE;
  3352. break;
  3353. //
  3354. // Signed divide.
  3355. //
  3356. case ARM_SDIV_MASK:
  3357. BaseMnemonic = ARM_SDIV_MNEMONIC;
  3358. ThreeOperands = TRUE;
  3359. break;
  3360. //
  3361. // Unsigned divide.
  3362. //
  3363. case ARM_UDIV_MASK:
  3364. BaseMnemonic = ARM_UDIV_MNEMONIC;
  3365. ThreeOperands = TRUE;
  3366. break;
  3367. //
  3368. // Signed half word multiply accumulate, long dual, and
  3369. // Signed half word multiply subtract, long dual.
  3370. //
  3371. case ARM_SMLXLD_MASK:
  3372. if ((Instruction & ARM_SMLXLD_OPCODE2_MASK) ==
  3373. ARM_SMLALD_OPCODE2_VALUE) {
  3374. BaseMnemonic = ARM_SMLALD_MNEMONIC;
  3375. } else if ((Instruction & ARM_SMLXLD_OPCODE2_MASK) ==
  3376. ARM_SMLSLD_OPCODE2_VALUE) {
  3377. BaseMnemonic = ARM_SMLSLD_MNEMONIC;
  3378. } else {
  3379. return;
  3380. }
  3381. PreConditionMnemonicSuffix = XBit;
  3382. LongMultiply = TRUE;
  3383. break;
  3384. //
  3385. // Signed most significant word multiply accumulate, and
  3386. // Signed most significant word multiply subtract, and
  3387. // Signed most significant word multiply.
  3388. //
  3389. case ARM_SMMLX_MASK:
  3390. if ((Instruction & ARM_SMMLX_OPCODE2_MASK) == ARM_SMMLA_OPCODE2_VALUE) {
  3391. if (Rn == 0xF) {
  3392. BaseMnemonic = ARM_SMMUL_MNEMONIC;
  3393. ThreeOperands = TRUE;
  3394. } else {
  3395. BaseMnemonic = ARM_SMMLA_MNEMONIC;
  3396. }
  3397. } else if ((Instruction & ARM_SMMLX_OPCODE2_MASK) ==
  3398. ARM_SMMLS_OPCODE2_VALUE) {
  3399. BaseMnemonic = ARM_SMMLS_MNEMONIC;
  3400. } else {
  3401. return;
  3402. }
  3403. PreConditionMnemonicSuffix = Rounded;
  3404. break;
  3405. //
  3406. // Signed multiply.
  3407. //
  3408. case ARM_SMUL_MASK:
  3409. BaseMnemonic = ARM_SMUL_MNEMONIC;
  3410. PreConditionMnemonicSuffix = MultiplyHalves;
  3411. ThreeOperands = TRUE;
  3412. break;
  3413. //
  3414. // Signed multiply, long.
  3415. //
  3416. case ARM_SMULL_MASK | ARM_SET_FLAGS_BIT:
  3417. MnemonicSuffix = ARM_SET_FLAGS_MNEMONIC;
  3418. //
  3419. // Fall through.
  3420. //
  3421. case ARM_SMULL_MASK:
  3422. BaseMnemonic = ARM_SMULL_MNEMONIC;
  3423. LongMultiply = TRUE;
  3424. break;
  3425. //
  3426. // Unsigned multiply accumulate accumulate long.
  3427. //
  3428. case ARM_UMAAL_MASK:
  3429. BaseMnemonic = ARM_UMAAL_MNEMONIC;
  3430. LongMultiply = TRUE;
  3431. break;
  3432. //
  3433. // Unsigned multiply accumulate long.
  3434. //
  3435. case ARM_UMLAL_MASK | ARM_SET_FLAGS_BIT:
  3436. MnemonicSuffix = ARM_SET_FLAGS_MNEMONIC;
  3437. //
  3438. // Fall through.
  3439. //
  3440. case ARM_UMLAL_MASK:
  3441. BaseMnemonic = ARM_UMLAL_MNEMONIC;
  3442. LongMultiply = TRUE;
  3443. break;
  3444. //
  3445. // Unsigned multiply long.
  3446. //
  3447. case ARM_UMULL_MASK | ARM_SET_FLAGS_BIT:
  3448. MnemonicSuffix = ARM_SET_FLAGS_MNEMONIC;
  3449. //
  3450. // Fall through.
  3451. //
  3452. case ARM_UMULL_MASK:
  3453. BaseMnemonic = ARM_UMULL_MNEMONIC;
  3454. LongMultiply = TRUE;
  3455. break;
  3456. default:
  3457. return;
  3458. }
  3459. snprintf(Context->Mnemonic,
  3460. ARM_OPERAND_LENGTH,
  3461. "%s%s%s",
  3462. BaseMnemonic,
  3463. PreConditionMnemonicSuffix,
  3464. MnemonicSuffix);
  3465. //
  3466. // Create the operands, depending on whether the instruction was a long
  3467. // multiply or not.
  3468. //
  3469. if (LongMultiply != FALSE) {
  3470. strcpy(Context->Operand1, DbgArmRegisterNames[RdLow]);
  3471. strcpy(Context->Operand2, DbgArmRegisterNames[RdHigh]);
  3472. strcpy(Context->Operand3, DbgArmRegisterNames[Rm]);
  3473. strcpy(Context->Operand4, DbgArmRegisterNames[Rs]);
  3474. } else {
  3475. strcpy(Context->Operand1, DbgArmRegisterNames[Rd]);
  3476. strcpy(Context->Operand2, DbgArmRegisterNames[Rm]);
  3477. strcpy(Context->Operand3, DbgArmRegisterNames[Rs]);
  3478. if (ThreeOperands == FALSE) {
  3479. strcpy(Context->Operand4, DbgArmRegisterNames[Rn]);
  3480. }
  3481. }
  3482. return;
  3483. }
  3484. VOID
  3485. DbgpArmDecodeSynchronization (
  3486. PARM_DISASSEMBLY Context
  3487. )
  3488. /*++
  3489. Routine Description:
  3490. This routine decodes a synchronization primitive instruction.
  3491. Arguments:
  3492. Context - Supplies a pointer to the disassembly context.
  3493. Return Value:
  3494. None.
  3495. --*/
  3496. {
  3497. ULONG Instruction;
  3498. PSTR Mnemonic;
  3499. ULONG Op;
  3500. ULONG R0;
  3501. ULONG R12;
  3502. ULONG Rn;
  3503. Instruction = Context->Instruction;
  3504. Op = (Instruction & ARM_SYNCHRONIZATION_OPCODE_MASK) >>
  3505. ARM_SYNCHRONIZATION_OPCODE_SHIFT;
  3506. Rn = (Instruction & ARM_SYNCHRONIZATION_RN_MASK) >>
  3507. ARM_SYNCHRONIZATION_RN_SHIFT;
  3508. R0 = Instruction & ARM_SYNCHRONIZATION_R0_MASK;
  3509. R12 = (Instruction & ARM_SYNCHRONIZATION_R12_MASK) >>
  3510. ARM_SYNCHRONIZATION_R12_SHIFT;
  3511. //
  3512. // If the high bit of the op field is not set, then it's a swap instruction.
  3513. //
  3514. if ((Op & ARM_SYNCHRONIZATION_OPCODE_EXCLUSIVE) == 0) {
  3515. if ((Instruction & ARM_SYNCHRONIZATION_SWAP_BYTE) != 0) {
  3516. Mnemonic = ARM_SWPB_MNEMONIC;
  3517. } else {
  3518. Mnemonic = ARM_SWP_MNEMONIC;
  3519. }
  3520. strcpy(Context->Operand1, DbgArmRegisterNames[R12]);
  3521. strcpy(Context->Operand2, DbgArmRegisterNames[R0]);
  3522. sprintf(Context->Operand3, "[%s]", DbgArmRegisterNames[Rn]);
  3523. //
  3524. // It's an ldrex or strex instruction of some kind.
  3525. //
  3526. } else {
  3527. Op &= ~ARM_SYNCHRONIZATION_OPCODE_EXCLUSIVE;
  3528. Mnemonic = DbgArmSynchronizationMnemonics[Op];
  3529. //
  3530. // If the lowest bit of the op region is set, it's an ldrex{b,h,d}.
  3531. //
  3532. if ((Op & ARM_SYNCHRONIZATION_OPCODE_LOAD) != 0) {
  3533. strcpy(Context->Operand1, DbgArmRegisterNames[R12]);
  3534. sprintf(Context->Operand2, "[%s]", DbgArmRegisterNames[Rn]);
  3535. } else {
  3536. strcpy(Context->Operand1, DbgArmRegisterNames[R12]);
  3537. strcpy(Context->Operand2, DbgArmRegisterNames[R0]);
  3538. sprintf(Context->Operand3, "[%s]", DbgArmRegisterNames[Rn]);
  3539. }
  3540. }
  3541. strcpy(Context->Mnemonic, Mnemonic);
  3542. return;
  3543. }
  3544. VOID
  3545. DbgpArmDecodeSupervisorCall (
  3546. PARM_DISASSEMBLY Context
  3547. )
  3548. /*++
  3549. Routine Description:
  3550. This routine decodes a supervisor call instruction.
  3551. Arguments:
  3552. Context - Supplies a pointer to the disassembly context.
  3553. Return Value:
  3554. None.
  3555. --*/
  3556. {
  3557. ULONG Immediate;
  3558. ULONG Instruction;
  3559. Instruction = Context->Instruction;
  3560. Immediate = Instruction & ARM_IMMEDIATE24_MASK;
  3561. strcpy(Context->Mnemonic, ARM_SVC_MNEMONIC);
  3562. sprintf(Context->Operand1, "#%d ; 0x%x", Immediate, Immediate);
  3563. return;
  3564. }
  3565. VOID
  3566. DbgpArmDecodeFloatingPointTwoRegisters (
  3567. PARM_DISASSEMBLY Context
  3568. )
  3569. /*++
  3570. Routine Description:
  3571. This routine decodes a two-register floating point data processing
  3572. instruction.
  3573. Arguments:
  3574. Context - Supplies a pointer to the disassembly context.
  3575. Return Value:
  3576. None.
  3577. --*/
  3578. {
  3579. PSTR BaseMnemonic;
  3580. ARM_IMMEDIATE_DOUBLE Double;
  3581. ARM_IMMEDIATE_FLOAT Float;
  3582. ULONG Immediate8;
  3583. ULONG Instruction;
  3584. ULONG Mask;
  3585. PSTR MnemonicSuffix;
  3586. BOOL TwoRegisters;
  3587. ULONG VectorD;
  3588. ULONG VectorM;
  3589. PSTR VectorTypeString;
  3590. Instruction = Context->Instruction;
  3591. //
  3592. // Collect the vector values. If the double-precision (SZ) bit is set, then
  3593. // the extra bit for each vector is the high bit. If the double-precision
  3594. // bit is not set, then the extra bit is the low bit.
  3595. //
  3596. VectorD = (Instruction & ARM_FLOATING_POINT_VD_MASK) >>
  3597. ARM_FLOATING_POINT_VD_SHIFT;
  3598. VectorM = (Instruction & ARM_FLOATING_POINT_VM_MASK) >>
  3599. ARM_FLOATING_POINT_VM_SHIFT;
  3600. if ((Instruction & ARM_FLOATING_POINT_SZ_BIT) != 0) {
  3601. if ((Instruction & ARM_FLOATING_POINT_D_BIT) != 0) {
  3602. VectorD |= (1 << 4);
  3603. }
  3604. if ((Instruction & ARM_FLOATING_POINT_M_BIT) != 0) {
  3605. VectorM |= (1 << 4);
  3606. }
  3607. MnemonicSuffix = ARM_FLOATING_POINT_DOUBLE_PRECISION_SUFFIX;
  3608. VectorTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  3609. } else {
  3610. VectorD <<= 1;
  3611. if ((Instruction & ARM_FLOATING_POINT_D_BIT) != 0) {
  3612. VectorD |= 1;
  3613. }
  3614. VectorM <<= 1;
  3615. if ((Instruction & ARM_FLOATING_POINT_M_BIT) != 0) {
  3616. VectorM |= 1;
  3617. }
  3618. MnemonicSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  3619. VectorTypeString = ARM_FLOATING_POINT_SINGLE_PRECISION_VECTOR;
  3620. }
  3621. //
  3622. // If the op bit is not set, then this is actually a VMOV immediate and not
  3623. // a two register instruction.
  3624. //
  3625. if ((Instruction & ARM_FLOATING_POINT_OP_BIT) == 0) {
  3626. BaseMnemonic = ARM_VMOV_MNEMONIC;
  3627. Immediate8 = ARM_FLOATING_POINT_BUILD_IMMEDIATE8(Instruction);
  3628. if ((Instruction & ARM_FLOATING_POINT_SZ_BIT) != 0) {
  3629. Double.Immediate = ARM_FLOATING_POINT_BUILD_IMMEDIATE64(Immediate8);
  3630. sprintf(Context->Operand2,
  3631. "#%d ; 0x%llx %g",
  3632. Immediate8,
  3633. Double.Immediate,
  3634. Double.Double);
  3635. } else {
  3636. Float.Immediate= ARM_FLOATING_POINT_BUILD_IMMEDIATE32(Immediate8);
  3637. sprintf(Context->Operand2,
  3638. "#%d ; 0x%x %g",
  3639. Immediate8,
  3640. Float.Immediate,
  3641. Float.Float);
  3642. }
  3643. TwoRegisters = FALSE;
  3644. } else {
  3645. Mask = Instruction & ARM_FLOATING_POINT_TWO_REGISTER_INSTRUCTION_MASK;
  3646. switch (Mask) {
  3647. case ARM_FLOATING_POINT_TWO_REGISTER_INSTRUCTION_VMOV:
  3648. BaseMnemonic = ARM_VMOV_MNEMONIC;
  3649. break;
  3650. case ARM_FLOATING_POINT_TWO_REGISTER_INSTRUCTION_VABS:
  3651. BaseMnemonic = ARM_VABS_MNEMONIC;
  3652. break;
  3653. case ARM_FLOATING_POINT_TWO_REGISTER_INSTRUCTION_VNEG:
  3654. BaseMnemonic = ARM_VNEG_MNEMONIC;
  3655. break;
  3656. case ARM_FLOATING_POINT_TWO_REGISTER_INSTRUCTION_VSQRT:
  3657. BaseMnemonic = ARM_VSQRT_MNEMONIC;
  3658. break;
  3659. default:
  3660. return;
  3661. }
  3662. TwoRegisters = TRUE;
  3663. }
  3664. strcpy(Context->Mnemonic, BaseMnemonic);
  3665. strcpy(Context->PostConditionMnemonicSuffix, MnemonicSuffix);
  3666. sprintf(Context->Operand1, "%s%d", VectorTypeString, VectorD);
  3667. if (TwoRegisters != FALSE) {
  3668. sprintf(Context->Operand2, "%s%d", VectorTypeString, VectorM);
  3669. }
  3670. return;
  3671. }
  3672. VOID
  3673. DbgpArmDecodeFloatingPointThreeRegisters (
  3674. PARM_DISASSEMBLY Context
  3675. )
  3676. /*++
  3677. Routine Description:
  3678. This routine decodes a three-register floating point data processing
  3679. instruction.
  3680. Arguments:
  3681. Context - Supplies a pointer to the disassembly context.
  3682. Return Value:
  3683. None.
  3684. --*/
  3685. {
  3686. PSTR BaseMnemonic;
  3687. ULONG Instruction;
  3688. PSTR MnemonicSuffix;
  3689. ULONG VectorD;
  3690. ULONG VectorM;
  3691. ULONG VectorN;
  3692. PSTR VectorTypeString;
  3693. Instruction = Context->Instruction;
  3694. //
  3695. // Collect the vector values. If the double-precision (SZ) bit is set, then
  3696. // the extra bit for each vector is the high bit. If the double-precision
  3697. // bit is not set, then the extra bit is the low bit.
  3698. //
  3699. VectorD = (Instruction & ARM_FLOATING_POINT_VD_MASK) >>
  3700. ARM_FLOATING_POINT_VD_SHIFT;
  3701. VectorM = (Instruction & ARM_FLOATING_POINT_VM_MASK) >>
  3702. ARM_FLOATING_POINT_VM_SHIFT;
  3703. VectorN = (Instruction & ARM_FLOATING_POINT_VN_MASK) >>
  3704. ARM_FLOATING_POINT_VN_SHIFT;
  3705. if ((Instruction & ARM_FLOATING_POINT_SZ_BIT) != 0) {
  3706. if ((Instruction & ARM_FLOATING_POINT_D_BIT) != 0) {
  3707. VectorD |= (1 << 4);
  3708. }
  3709. if ((Instruction & ARM_FLOATING_POINT_M_BIT) != 0) {
  3710. VectorM |= (1 << 4);
  3711. }
  3712. if ((Instruction & ARM_FLOATING_POINT_N_BIT) != 0) {
  3713. VectorN |= (1 << 4);
  3714. }
  3715. MnemonicSuffix = ARM_FLOATING_POINT_DOUBLE_PRECISION_SUFFIX;
  3716. VectorTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  3717. } else {
  3718. VectorD <<= 1;
  3719. if ((Instruction & ARM_FLOATING_POINT_D_BIT) != 0) {
  3720. VectorD |= 1;
  3721. }
  3722. VectorM <<= 1;
  3723. if ((Instruction & ARM_FLOATING_POINT_M_BIT) != 0) {
  3724. VectorM |= 1;
  3725. }
  3726. VectorN <<= 1;
  3727. if ((Instruction & ARM_FLOATING_POINT_N_BIT) != 0) {
  3728. VectorN |= 1;
  3729. }
  3730. MnemonicSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  3731. VectorTypeString = ARM_FLOATING_POINT_SINGLE_PRECISION_VECTOR;
  3732. }
  3733. //
  3734. // Get the instruction based on the value of opcode 1 and the op bit.
  3735. //
  3736. BaseMnemonic = "ERR";
  3737. switch (Instruction & ARM_FLOATING_POINT_INSTRUCTION_MASK) {
  3738. case ARM_FLOATING_POINT_INSTRUCTION_VMLA_VMLS:
  3739. if ((Instruction & ARM_FLOATING_POINT_OP_BIT) != 0) {
  3740. BaseMnemonic = ARM_VMLS_MNEMONIC;
  3741. } else {
  3742. BaseMnemonic = ARM_VMLA_MNEMONIC;
  3743. }
  3744. break;
  3745. case ARM_FLOATING_POINT_INSTRUCTION_VNMLA_VNMLS:
  3746. if ((Instruction & ARM_FLOATING_POINT_OP_BIT) != 0) {
  3747. BaseMnemonic = ARM_VNMLS_MNEMONIC;
  3748. } else {
  3749. BaseMnemonic = ARM_VNMLA_MNEMONIC;
  3750. }
  3751. break;
  3752. case ARM_FLOATING_POINT_INSTRUCTION_VMUL_VNMUL:
  3753. if ((Instruction & ARM_FLOATING_POINT_OP_BIT) != 0) {
  3754. BaseMnemonic = ARM_VNMUL_MNEMONIC;
  3755. } else {
  3756. BaseMnemonic = ARM_VMUL_MNEMONIC;
  3757. }
  3758. break;
  3759. case ARM_FLOATING_POINT_INSTRUCTION_VADD_VSUB:
  3760. if ((Instruction & ARM_FLOATING_POINT_OP_BIT) != 0) {
  3761. BaseMnemonic = ARM_VSUB_MNEMONIC;
  3762. } else {
  3763. BaseMnemonic = ARM_VADD_MNEMONIC;
  3764. }
  3765. break;
  3766. case ARM_FLOATING_POINT_INSTRUCTION_VDIV:
  3767. if ((Instruction & ARM_FLOATING_POINT_OP_BIT) != 0) {
  3768. return;
  3769. }
  3770. BaseMnemonic = ARM_VDIV_MNEMONIC;
  3771. break;
  3772. case ARM_FLOATING_POINT_INSTRUCTION_VFNMA_VFNMS:
  3773. if ((Instruction & ARM_FLOATING_POINT_OP_BIT) != 0) {
  3774. BaseMnemonic = ARM_VFNMA_MNEMONIC;
  3775. } else {
  3776. BaseMnemonic = ARM_VFNMS_MNEMONIC;
  3777. }
  3778. break;
  3779. case ARM_FLOATING_POINT_INSTRUCTION_VFMA_VFMS:
  3780. if ((Instruction & ARM_FLOATING_POINT_OP_BIT) != 0) {
  3781. BaseMnemonic = ARM_VFMS_MNEMONIC;
  3782. } else {
  3783. BaseMnemonic = ARM_VFMA_MNEMONIC;
  3784. }
  3785. break;
  3786. default:
  3787. break;
  3788. }
  3789. strcpy(Context->Mnemonic, BaseMnemonic);
  3790. strcpy(Context->PostConditionMnemonicSuffix, MnemonicSuffix);
  3791. sprintf(Context->Operand1, "%s%d", VectorTypeString, VectorD);
  3792. sprintf(Context->Operand2, "%s%d", VectorTypeString, VectorN);
  3793. sprintf(Context->Operand3, "%s%d", VectorTypeString, VectorM);
  3794. return;
  3795. }
  3796. VOID
  3797. DbgpArmDecodeFloatingPointVectorConvert (
  3798. PARM_DISASSEMBLY Context
  3799. )
  3800. /*++
  3801. Routine Description:
  3802. This routine decodes a floating point vector convert instruction.
  3803. Arguments:
  3804. Context - Supplies a pointer to the disassembly context.
  3805. Return Value:
  3806. None.
  3807. --*/
  3808. {
  3809. PSTR DestinationHalfSuffix;
  3810. PSTR DestinationSuffix;
  3811. PSTR FixedSuffix;
  3812. ULONG FractionBits;
  3813. ULONG Instruction;
  3814. PSTR PreConditionMnemonicSuffix;
  3815. BOOL RepeatVectorD;
  3816. PSTR SourceHalfSuffix;
  3817. PSTR SourceSuffix;
  3818. ULONG VectorD;
  3819. BOOL VectorDDouble;
  3820. PSTR VectorDTypeString;
  3821. ULONG VectorM;
  3822. BOOL VectorMDouble;
  3823. PSTR VectorMTypeString;
  3824. //
  3825. // Save somem values that are common to most instructions.
  3826. //
  3827. Instruction = Context->Instruction;
  3828. RepeatVectorD = FALSE;
  3829. VectorDDouble = FALSE;
  3830. VectorD = (Instruction & ARM_FLOATING_POINT_VD_MASK) >>
  3831. ARM_FLOATING_POINT_VD_SHIFT;
  3832. VectorMDouble = FALSE;
  3833. VectorM = (Instruction & ARM_FLOATING_POINT_VM_MASK) >>
  3834. ARM_FLOATING_POINT_VM_SHIFT;
  3835. DestinationHalfSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  3836. SourceHalfSuffix = ARM_FLOATING_POINT_HALF_PRECISION_SUFFIX;
  3837. DestinationSuffix = "";
  3838. PreConditionMnemonicSuffix = "";
  3839. SourceSuffix = "";
  3840. //
  3841. // Compute the fraction bits and suffix for the fixed point instructions.
  3842. // The fixed 32-bit and unsigned bit are the same for float to fixed as
  3843. // they are for fixed to float.
  3844. //
  3845. FractionBits = (Instruction & ARM_FLOATING_POINT_IMMEDIATE4_LOW_MASK) >>
  3846. ARM_FLOATING_POINT_IMMEDIATE4_LOW_SHIFT;
  3847. FractionBits <<= 1;
  3848. if ((Instruction & ARM_FLOATING_POINT_I_BIT) != 0) {
  3849. FractionBits |= 1;
  3850. }
  3851. if ((Instruction & ARM_VCVT_FIXED_32_TO_FLOAT) != 0) {
  3852. if ((Instruction & ARM_VCVT_FIXED_UNSIGNED_TO_FLOAT) != 0) {
  3853. FixedSuffix = ARM_FLOATING_POINT_UNSIGNED_INTEGER_SUFFIX;
  3854. } else {
  3855. FixedSuffix = ARM_FLOATING_POINT_SIGNED_INTEGER_SUFFIX;
  3856. }
  3857. FractionBits = 32 - FractionBits;
  3858. } else {
  3859. if ((Instruction & ARM_VCVT_FIXED_UNSIGNED_TO_FLOAT) != 0) {
  3860. FixedSuffix = ARM_FLOATING_POINT_UNSIGNED_HALF_SUFFIX;
  3861. } else {
  3862. FixedSuffix = ARM_FLOATING_POINT_SIGNED_HALF_SUFFIX;
  3863. }
  3864. FractionBits = 16 - FractionBits;
  3865. }
  3866. //
  3867. // Determine the suffices and vector sizes baced on the instruction mask.
  3868. //
  3869. switch (Instruction & ARM_VCVT_MASK) {
  3870. //
  3871. // Handle VCVTT single to half.
  3872. //
  3873. case ARM_VCVT_TOP | ARM_VCVT_SINGLE_TO_HALF:
  3874. DestinationHalfSuffix = ARM_FLOATING_POINT_HALF_PRECISION_SUFFIX;
  3875. SourceHalfSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  3876. //
  3877. // Fall through.
  3878. //
  3879. //
  3880. // Handle VCVTT half to single.
  3881. //
  3882. case ARM_VCVT_TOP | ARM_VCVT_HALF_TO_SINGLE:
  3883. PreConditionMnemonicSuffix = ARM_FLOATING_POINT_TOP;
  3884. DestinationSuffix = DestinationHalfSuffix;
  3885. SourceSuffix = SourceHalfSuffix;
  3886. break;
  3887. //
  3888. // Handle VCVTB single to half.
  3889. //
  3890. case ARM_VCVT_BOTTOM | ARM_VCVT_SINGLE_TO_HALF:
  3891. DestinationHalfSuffix = ARM_FLOATING_POINT_HALF_PRECISION_SUFFIX;
  3892. SourceHalfSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  3893. //
  3894. // Fall through.
  3895. //
  3896. //
  3897. // Handle VCVTB half to single.
  3898. //
  3899. case ARM_VCVT_BOTTOM | ARM_VCVT_HALF_TO_SINGLE:
  3900. PreConditionMnemonicSuffix = ARM_FLOATING_POINT_BOTTOM;
  3901. DestinationSuffix = DestinationHalfSuffix;
  3902. SourceSuffix = SourceHalfSuffix;
  3903. break;
  3904. //
  3905. // Handle VCVT single-precision to double-precision conversions and
  3906. // double-precision to single-precision conversion.
  3907. //
  3908. case ARM_VCVT_FLOAT_TO_FLOAT:
  3909. //
  3910. // Here the double bit indicates that the conversion is from a double.
  3911. //
  3912. if ((Instruction & ARM_VCVT_DOUBLE) != 0) {
  3913. VectorMDouble = TRUE;
  3914. SourceSuffix = ARM_FLOATING_POINT_DOUBLE_PRECISION_SUFFIX;
  3915. DestinationSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  3916. } else {
  3917. VectorDDouble = TRUE;
  3918. SourceSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  3919. DestinationSuffix = ARM_FLOATING_POINT_DOUBLE_PRECISION_SUFFIX;
  3920. }
  3921. break;
  3922. //
  3923. // Handle conversions from floats to integers.
  3924. //
  3925. case ARM_VCVT_FLOAT_TO_INTEGER:
  3926. case ARM_VCVT_FLOAT_TO_INTEGER | ARM_VCVT_FLOAT_TO_INTEGER_SIGNED:
  3927. case ARM_VCVT_FLOAT_TO_INTEGER | ARM_VCVT_FLOAT_TO_INTEGER_ROUND_TO_ZERO:
  3928. case (ARM_VCVT_FLOAT_TO_INTEGER |
  3929. ARM_VCVT_FLOAT_TO_INTEGER_SIGNED |
  3930. ARM_VCVT_FLOAT_TO_INTEGER_ROUND_TO_ZERO):
  3931. if ((Instruction & ARM_VCVT_DOUBLE) != 0) {
  3932. VectorMDouble = TRUE;
  3933. SourceSuffix = ARM_FLOATING_POINT_DOUBLE_PRECISION_SUFFIX;
  3934. } else {
  3935. SourceSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  3936. }
  3937. if ((Instruction & ARM_VCVT_FLOAT_TO_INTEGER_SIGNED) != 0) {
  3938. DestinationSuffix = ARM_FLOATING_POINT_SIGNED_INTEGER_SUFFIX;
  3939. } else {
  3940. DestinationSuffix = ARM_FLOATING_POINT_UNSIGNED_INTEGER_SUFFIX;
  3941. }
  3942. if ((Instruction & ARM_VCVT_FLOAT_TO_INTEGER_ROUND_TO_ZERO) == 0) {
  3943. PreConditionMnemonicSuffix = ARM_FLOATING_POINT_ROUNDING;
  3944. }
  3945. break;
  3946. //
  3947. // Handle conversions from integers to floats.
  3948. //
  3949. case ARM_VCVT_INTEGER_TO_FLOAT:
  3950. case ARM_VCVT_INTEGER_TO_FLOAT | ARM_VCVT_INTEGER_TO_FLOAT_SIGNED:
  3951. if ((Instruction & ARM_VCVT_DOUBLE) != 0) {
  3952. VectorDDouble = TRUE;
  3953. DestinationSuffix = ARM_FLOATING_POINT_DOUBLE_PRECISION_SUFFIX;
  3954. } else {
  3955. DestinationSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  3956. }
  3957. if ((Instruction & ARM_VCVT_INTEGER_TO_FLOAT_SIGNED) != 0) {
  3958. SourceSuffix = ARM_FLOATING_POINT_SIGNED_INTEGER_SUFFIX;
  3959. } else {
  3960. SourceSuffix = ARM_FLOATING_POINT_UNSIGNED_INTEGER_SUFFIX;
  3961. }
  3962. break;
  3963. //
  3964. // Handle conversions from floats to fixed point.
  3965. //
  3966. case ARM_VCVT_FLOAT_TO_FIXED:
  3967. case ARM_VCVT_FLOAT_TO_FIXED | ARM_VCVT_FLOAT_TO_FIXED_UNSIGNED:
  3968. case ARM_VCVT_FLOAT_TO_FIXED | ARM_VCVT_FLOAT_TO_FIXED_32:
  3969. case (ARM_VCVT_FLOAT_TO_FIXED |
  3970. ARM_VCVT_FLOAT_TO_FIXED_UNSIGNED |
  3971. ARM_VCVT_FLOAT_TO_FIXED_32):
  3972. if ((Instruction & ARM_VCVT_DOUBLE) != 0) {
  3973. VectorDDouble = TRUE;
  3974. SourceSuffix = ARM_FLOATING_POINT_DOUBLE_PRECISION_SUFFIX;
  3975. } else {
  3976. SourceSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  3977. }
  3978. DestinationSuffix = FixedSuffix;
  3979. RepeatVectorD = TRUE;
  3980. break;
  3981. //
  3982. // Handle conversions from fixed point to floats.
  3983. //
  3984. case ARM_VCVT_FIXED_TO_FLOAT:
  3985. case ARM_VCVT_FIXED_TO_FLOAT | ARM_VCVT_FIXED_UNSIGNED_TO_FLOAT:
  3986. case ARM_VCVT_FIXED_TO_FLOAT | ARM_VCVT_FIXED_32_TO_FLOAT:
  3987. case (ARM_VCVT_FIXED_TO_FLOAT |
  3988. ARM_VCVT_FIXED_UNSIGNED_TO_FLOAT |
  3989. ARM_VCVT_FIXED_32_TO_FLOAT):
  3990. if ((Instruction & ARM_VCVT_DOUBLE) != 0) {
  3991. VectorDDouble = TRUE;
  3992. DestinationSuffix = ARM_FLOATING_POINT_DOUBLE_PRECISION_SUFFIX;
  3993. } else {
  3994. DestinationSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  3995. }
  3996. SourceSuffix = FixedSuffix;
  3997. RepeatVectorD = TRUE;
  3998. break;
  3999. default:
  4000. break;
  4001. }
  4002. //
  4003. // Convert the vectors into the correct double-precision or
  4004. // single-precision values.
  4005. //
  4006. if (VectorDDouble != FALSE) {
  4007. VectorDTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  4008. if ((Instruction & ARM_FLOATING_POINT_D_BIT) != 0) {
  4009. VectorD |= (1 << 4);
  4010. }
  4011. } else {
  4012. VectorDTypeString = ARM_FLOATING_POINT_SINGLE_PRECISION_VECTOR;
  4013. VectorD <<= 1;
  4014. if ((Instruction & ARM_FLOATING_POINT_D_BIT) != 0) {
  4015. VectorD |= 1;
  4016. }
  4017. }
  4018. if (VectorMDouble != FALSE) {
  4019. VectorMTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  4020. if ((Instruction & ARM_FLOATING_POINT_M_BIT) != 0) {
  4021. VectorM |= (1 << 4);
  4022. }
  4023. } else {
  4024. VectorMTypeString = ARM_FLOATING_POINT_SINGLE_PRECISION_VECTOR;
  4025. VectorM <<= 1;
  4026. if ((Instruction & ARM_FLOATING_POINT_M_BIT) != 0) {
  4027. VectorM |= 1;
  4028. }
  4029. }
  4030. sprintf(Context->Mnemonic,
  4031. "%s%s",
  4032. ARM_VCVT_MNEMONIC,
  4033. PreConditionMnemonicSuffix);
  4034. sprintf(Context->PostConditionMnemonicSuffix,
  4035. "%s%s",
  4036. DestinationSuffix,
  4037. SourceSuffix);
  4038. sprintf(Context->Operand1, "%s%d", VectorDTypeString, VectorD);
  4039. if (RepeatVectorD != FALSE) {
  4040. sprintf(Context->Operand2, "%s%d", VectorDTypeString, VectorD);
  4041. } else {
  4042. sprintf(Context->Operand2, "%s%d", VectorMTypeString, VectorM);
  4043. }
  4044. return;
  4045. }
  4046. VOID
  4047. DbgpArmDecodeFloatingPointVectorCompare (
  4048. PARM_DISASSEMBLY Context
  4049. )
  4050. /*++
  4051. Routine Description:
  4052. This routine decodes a floating point vector compare instruction.
  4053. Arguments:
  4054. Context - Supplies a pointer to the disassembly context.
  4055. Return Value:
  4056. None.
  4057. --*/
  4058. {
  4059. PSTR BaseMnemonic;
  4060. ULONG Instruction;
  4061. PSTR MnemonicSuffix;
  4062. ULONG VectorD;
  4063. ULONG VectorM;
  4064. PSTR VectorTypeString;
  4065. Instruction = Context->Instruction;
  4066. //
  4067. // Collect the vector values. If the double-precision (SZ) bit is set, then
  4068. // the extra bit for each vector is the high bit. If the double-precision
  4069. // bit is not set, then the extra bit is the low bit.
  4070. //
  4071. VectorD = (Instruction & ARM_FLOATING_POINT_VD_MASK) >>
  4072. ARM_FLOATING_POINT_VD_SHIFT;
  4073. VectorM = (Instruction & ARM_FLOATING_POINT_VM_MASK) >>
  4074. ARM_FLOATING_POINT_VM_SHIFT;
  4075. if ((Instruction & ARM_FLOATING_POINT_SZ_BIT) != 0) {
  4076. if ((Instruction & ARM_FLOATING_POINT_D_BIT) != 0) {
  4077. VectorD |= (1 << 4);
  4078. }
  4079. if ((Instruction & ARM_FLOATING_POINT_M_BIT) != 0) {
  4080. VectorM |= (1 << 4);
  4081. }
  4082. MnemonicSuffix = ARM_FLOATING_POINT_DOUBLE_PRECISION_SUFFIX;
  4083. VectorTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  4084. } else {
  4085. VectorD <<= 1;
  4086. if ((Instruction & ARM_FLOATING_POINT_D_BIT) != 0) {
  4087. VectorD |= 1;
  4088. }
  4089. VectorM <<= 1;
  4090. if ((Instruction & ARM_FLOATING_POINT_M_BIT) != 0) {
  4091. VectorM |= 1;
  4092. }
  4093. MnemonicSuffix = ARM_FLOATING_POINT_SINGLE_PRECISION_SUFFIX;
  4094. VectorTypeString = ARM_FLOATING_POINT_SINGLE_PRECISION_VECTOR;
  4095. }
  4096. //
  4097. // Get the base mnemonic and fill out the context.
  4098. //
  4099. if ((Instruction & ARM_FLOATING_POINT_VCMP_E_BIT) != 0) {
  4100. BaseMnemonic = ARM_VCMPE_MNEMONIC;
  4101. } else {
  4102. BaseMnemonic = ARM_VCMP_MNEMONIC;
  4103. }
  4104. strcpy(Context->Mnemonic, BaseMnemonic);
  4105. strcpy(Context->PostConditionMnemonicSuffix, MnemonicSuffix);
  4106. sprintf(Context->Operand1, "%s%d", VectorTypeString, VectorD);
  4107. if ((Instruction & ARM_FLOATING_POINT_VCMP_ZERO) != 0) {
  4108. sprintf(Context->Operand2, "#0.0");
  4109. } else {
  4110. sprintf(Context->Operand2, "%s%d", VectorTypeString, VectorM);
  4111. }
  4112. return;
  4113. }
  4114. VOID
  4115. DbgpArmDecodeSimdSmallMove (
  4116. PARM_DISASSEMBLY Context
  4117. )
  4118. /*++
  4119. Routine Description:
  4120. This routine decodes a floating point to ARM register move instruction.
  4121. Arguments:
  4122. Context - Supplies a pointer to the disassembly context.
  4123. Return Value:
  4124. None.
  4125. --*/
  4126. {
  4127. ULONG Instruction;
  4128. ULONG Register;
  4129. PSTR RegisterString;
  4130. ULONG Size;
  4131. PSTR SizeTypeSuffix;
  4132. PSTR SizeValueSuffix;
  4133. ULONG Vector;
  4134. BOOL VectorDouble;
  4135. ULONG VectorIndex;
  4136. PSTR VectorString;
  4137. PSTR VectorTypeString;
  4138. Instruction = Context->Instruction;
  4139. Register = (Instruction & ARM_SIMD_TRANSFER_REGISTER_MASK) >>
  4140. ARM_SIMD_TRANSFER_REGISTER_SHIFT;
  4141. VectorDouble = FALSE;
  4142. Vector = (Instruction & ARM_SIMD_TRANSFER_VECTOR_MASK) >>
  4143. ARM_SIMD_TRANSFER_VECTOR_SHIFT;
  4144. //
  4145. // Determine the mnemonic suffices and vector index for the to/from scalar
  4146. // instructions.
  4147. //
  4148. SizeTypeSuffix = "";
  4149. SizeValueSuffix = "";
  4150. VectorIndex = 0;
  4151. if ((Instruction & ARM_SIMD_TRANSFER_MOVE_SCALAR) != 0) {
  4152. VectorDouble = TRUE;
  4153. Size = ARM_SIMD_TRANSFER_SCALAR_BUILD_SIZE_ENCODING(Instruction);
  4154. if ((Size & ARM_SIMD_TRANSFER_SCALAR_SIZE_8_MASK) ==
  4155. ARM_SIMD_TRANSFER_SCALAR_SIZE_8_VALUE) {
  4156. VectorIndex = (Size & ~ARM_SIMD_TRANSFER_SCALAR_SIZE_8_MASK) >>
  4157. ARM_SIMD_TRANSFER_SCALAR_SIZE_8_SHIFT;
  4158. SizeValueSuffix = ARM_SIMD_DATA_SIZE_8;
  4159. } else if ((Size & ARM_SIMD_TRANSFER_SCALAR_SIZE_16_MASK) ==
  4160. ARM_SIMD_TRANSFER_SCALAR_SIZE_16_VALUE) {
  4161. VectorIndex = (Size & ~ARM_SIMD_TRANSFER_SCALAR_SIZE_16_MASK) >>
  4162. ARM_SIMD_TRANSFER_SCALAR_SIZE_16_SHIFT;
  4163. SizeValueSuffix = ARM_SIMD_DATA_SIZE_16;
  4164. } else if ((Size & ARM_SIMD_TRANSFER_SCALAR_SIZE_32_MASK) ==
  4165. ARM_SIMD_TRANSFER_SCALAR_SIZE_32_VALUE) {
  4166. VectorIndex = (Size & ~ARM_SIMD_TRANSFER_SCALAR_SIZE_32_MASK) >>
  4167. ARM_SIMD_TRANSFER_SCALAR_SIZE_32_SHIFT;
  4168. if (((Instruction & ARM_SIMD_TRANSFER_TO_REGISTER) != 0) &&
  4169. ((Instruction & ARM_SIMD_TRANSFER_SCALAR_UNSIGNED) != 0)) {
  4170. DbgpArmDecodeUndefined(Context);
  4171. return;
  4172. }
  4173. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  4174. } else {
  4175. DbgpArmDecodeUndefined(Context);
  4176. return;
  4177. }
  4178. if ((Instruction & ARM_SIMD_TRANSFER_TO_REGISTER) != 0) {
  4179. if ((Instruction & ARM_SIMD_TRANSFER_SCALAR_UNSIGNED) != 0) {
  4180. SizeTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  4181. } else {
  4182. SizeTypeSuffix = ARM_SIMD_DATA_SIGNED;
  4183. }
  4184. } else {
  4185. SizeTypeSuffix = ARM_SIMD_DATA_DEFAULT;
  4186. }
  4187. }
  4188. //
  4189. // Finalize the vector and get its type string.
  4190. //
  4191. if (VectorDouble != FALSE) {
  4192. VectorTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  4193. if ((Instruction & ARM_SIMD_TRANSFER_VECTOR_BIT) != 0) {
  4194. Vector |= (1 << 4);
  4195. }
  4196. } else {
  4197. VectorTypeString = ARM_FLOATING_POINT_SINGLE_PRECISION_VECTOR;
  4198. Vector <<= 1;
  4199. if ((Instruction & ARM_SIMD_TRANSFER_VECTOR_BIT) != 0) {
  4200. Vector |= 1;
  4201. }
  4202. }
  4203. if ((Instruction & ARM_SIMD_TRANSFER_TO_REGISTER) != 0) {
  4204. RegisterString = Context->Operand1;
  4205. VectorString = Context->Operand2;
  4206. } else {
  4207. VectorString = Context->Operand1;
  4208. RegisterString = Context->Operand2;
  4209. }
  4210. strcpy(Context->Mnemonic, ARM_VMOV_MNEMONIC);
  4211. sprintf(Context->PostConditionMnemonicSuffix,
  4212. "%s%s",
  4213. SizeTypeSuffix,
  4214. SizeValueSuffix);
  4215. strcpy(RegisterString, DbgArmRegisterNames[Register]);
  4216. if ((Instruction & ARM_SIMD_TRANSFER_MOVE_SCALAR) != 0) {
  4217. sprintf(VectorString,
  4218. "%s%d[%d]",
  4219. VectorTypeString,
  4220. Vector,
  4221. VectorIndex);
  4222. } else {
  4223. sprintf(VectorString, "%s%d", VectorTypeString, Vector);
  4224. }
  4225. return;
  4226. }
  4227. VOID
  4228. DbgpArmDecodeSimdSpecialMove (
  4229. PARM_DISASSEMBLY Context
  4230. )
  4231. /*++
  4232. Routine Description:
  4233. This routine decodes an ARM register to special register move instruction.
  4234. Arguments:
  4235. Context - Supplies a pointer to the disassembly context.
  4236. Return Value:
  4237. None.
  4238. --*/
  4239. {
  4240. PSTR BaseMnemonic;
  4241. ULONG Instruction;
  4242. ULONG Register;
  4243. PSTR RegisterName;
  4244. ULONG SpecialRegister;
  4245. Instruction = Context->Instruction;
  4246. Register = (Instruction & ARM_SIMD_TRANSFER_REGISTER_MASK) >>
  4247. ARM_SIMD_TRANSFER_REGISTER_SHIFT;
  4248. SpecialRegister = (Instruction & ARM_SIMD_TRANSFER_SPECIAL_MASK) >>
  4249. ARM_SIMD_TRANSFER_SPECIAL_SHIFT;
  4250. if ((Instruction & ARM_SIMD_TRANSFER_TO_REGISTER) != 0) {
  4251. BaseMnemonic = ARM_VMRS_MNEMONIC;
  4252. if ((Register == 0xF) && (SpecialRegister == 1)) {
  4253. RegisterName = ARM_SIMD_APSR_REGISTER;
  4254. } else {
  4255. RegisterName = DbgArmRegisterNames[Register];
  4256. }
  4257. strcpy(Context->Operand1, RegisterName);
  4258. strcpy(Context->Operand2, DbgArmSpecialRegisterNames[SpecialRegister]);
  4259. } else {
  4260. BaseMnemonic = ARM_VMSR_MNEMONIC;
  4261. strcpy(Context->Operand1, DbgArmSpecialRegisterNames[SpecialRegister]);
  4262. strcpy(Context->Operand2, DbgArmRegisterNames[Register]);
  4263. }
  4264. strcpy(Context->Mnemonic, BaseMnemonic);
  4265. return;
  4266. }
  4267. VOID
  4268. DbgpArmDecodeSimdDuplicate (
  4269. PARM_DISASSEMBLY Context
  4270. )
  4271. /*++
  4272. Routine Description:
  4273. This routine decodes an ARM register to floating point duplicate
  4274. instruction.
  4275. Arguments:
  4276. Context - Supplies a pointer to the disassembly context.
  4277. Return Value:
  4278. None.
  4279. --*/
  4280. {
  4281. ULONG Instruction;
  4282. PSTR MnemonicSuffix;
  4283. ULONG Register;
  4284. ULONG Size;
  4285. ULONG Vector;
  4286. PSTR VectorTypeString;
  4287. Instruction = Context->Instruction;
  4288. Register = (Instruction & ARM_SIMD_TRANSFER_REGISTER_MASK) >>
  4289. ARM_SIMD_TRANSFER_REGISTER_SHIFT;
  4290. Vector = (Instruction & ARM_SIMD_TRANSFER_VECTOR_MASK) >>
  4291. ARM_SIMD_TRANSFER_VECTOR_SHIFT;
  4292. if ((Instruction & ARM_SIMD_TRANSFER_VECTOR_BIT) != 0) {
  4293. Vector |= (1 << 4);
  4294. }
  4295. //
  4296. // Determine the size of the transfers.
  4297. //
  4298. Size = ARM_SIMD_TRANSFER_DUP_BUILD_SIZE_ENCODING(Instruction);
  4299. switch (Size) {
  4300. case ARM_SIMD_TRANSFER_DUP_SIZE_8:
  4301. MnemonicSuffix = ARM_SIMD_DATA_SIZE_8;
  4302. break;
  4303. case ARM_SIMD_TRANSFER_DUP_SIZE_16:
  4304. MnemonicSuffix = ARM_SIMD_DATA_SIZE_16;
  4305. break;
  4306. case ARM_SIMD_TRANSFER_DUP_SIZE_32:
  4307. MnemonicSuffix = ARM_SIMD_DATA_SIZE_32;
  4308. break;
  4309. default:
  4310. DbgpArmDecodeUndefined(Context);
  4311. return;
  4312. }
  4313. //
  4314. // Get the vector type.
  4315. //
  4316. if ((Instruction & ARM_SIMD_TRANSFER_DUP_QUADWORD) != 0) {
  4317. VectorTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  4318. } else {
  4319. VectorTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  4320. }
  4321. strcpy(Context->Mnemonic, ARM_VDUP_MNEMONIC);
  4322. strcpy(Context->PostConditionMnemonicSuffix, MnemonicSuffix);
  4323. sprintf(Context->Operand1, "%s%d", VectorTypeString, Vector);
  4324. strcpy(Context->Operand2, DbgArmRegisterNames[Register]);
  4325. return;
  4326. }
  4327. VOID
  4328. DbgpArmDecodeSimdLoadStoreRegister (
  4329. PARM_DISASSEMBLY Context
  4330. )
  4331. /*++
  4332. Routine Description:
  4333. This routine decodes an SIMD and floating point register load/store
  4334. instruction.
  4335. Arguments:
  4336. Context - Supplies a pointer to the disassembly context.
  4337. Return Value:
  4338. None.
  4339. --*/
  4340. {
  4341. PSTR BaseMnemonic;
  4342. ULONG Instruction;
  4343. ULONG Offset;
  4344. ULONG Register;
  4345. CHAR Sign;
  4346. ULONG Vector;
  4347. PSTR VectorTypeString;
  4348. Instruction = Context->Instruction;
  4349. Register = (Instruction & ARM_SIMD_LOAD_STORE_REGISTER_MASK) >>
  4350. ARM_SIMD_LOAD_STORE_REGISTER_SHIFT;
  4351. if ((Instruction & ARM_LOAD_BIT) != 0) {
  4352. BaseMnemonic = ARM_VLD_MNEMONIC;
  4353. } else {
  4354. BaseMnemonic = ARM_VST_MNEMONIC;
  4355. }
  4356. //
  4357. // Get the correct vector value based on whether it is single or double
  4358. // precision.
  4359. //
  4360. Vector = (Instruction & ARM_SIMD_LOAD_STORE_VECTOR_MASK) >>
  4361. ARM_SIMD_LOAD_STORE_VECTOR_SHIFT;
  4362. if ((Instruction & ARM_SIMD_LOAD_STORE_DOUBLE) != 0) {
  4363. if ((Instruction & ARM_SIMD_LOAD_STORE_VECTOR_BIT) != 0) {
  4364. Vector |= (1 << 4);
  4365. }
  4366. VectorTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  4367. } else {
  4368. Vector <<= 1;
  4369. if ((Instruction & ARM_SIMD_LOAD_STORE_VECTOR_BIT) != 0) {
  4370. Vector |= 1;
  4371. }
  4372. VectorTypeString = ARM_FLOATING_POINT_SINGLE_PRECISION_VECTOR;
  4373. }
  4374. //
  4375. // Get the immediate offset and its sign.
  4376. //
  4377. Offset = (Instruction & ARM_SIMD_LOAD_STORE_IMMEDIATE8_MASK) >>
  4378. ARM_SIMD_LOAD_STORE_IMMEDIATE8_SHIFT;
  4379. Offset <<= 2;
  4380. if ((Instruction & ARM_SIMD_LOAD_STORE_ADD_BIT) != 0) {
  4381. Sign = '+';
  4382. } else {
  4383. Sign = '-';
  4384. }
  4385. sprintf(Context->Mnemonic,
  4386. "%s%s",
  4387. BaseMnemonic,
  4388. ARM_FLOATING_POINT_REGISTER);
  4389. sprintf(Context->Operand1, "%s%d", VectorTypeString, Vector);
  4390. if (Offset == 0) {
  4391. sprintf(Context->Operand2, "[%s]", DbgArmRegisterNames[Register]);
  4392. } else {
  4393. sprintf(Context->Operand2,
  4394. "[%s, #%c%d]",
  4395. DbgArmRegisterNames[Register],
  4396. Sign,
  4397. Offset);
  4398. }
  4399. return;
  4400. }
  4401. VOID
  4402. DbgpArmDecodeSimdLoadStoreMultiple (
  4403. PARM_DISASSEMBLY Context
  4404. )
  4405. /*++
  4406. Routine Description:
  4407. This routine decodes an SIMD and floating point multiple register
  4408. load/store instruction.
  4409. Arguments:
  4410. Context - Supplies a pointer to the disassembly context.
  4411. Return Value:
  4412. None.
  4413. --*/
  4414. {
  4415. PSTR BaseMnemonic;
  4416. ULONG Instruction;
  4417. PSTR MnemonicSuffix;
  4418. ULONG Operation;
  4419. PSTR PreConditionMnemonicSuffix;
  4420. BOOL PushPop;
  4421. ULONG Register;
  4422. ULONG Vector;
  4423. ULONG VectorCount;
  4424. PSTR VectorListString;
  4425. ULONG VectorListStringSize;
  4426. PSTR VectorTypeString;
  4427. PSTR WriteBack;
  4428. Instruction = Context->Instruction;
  4429. Operation = Instruction & ARM_SIMD_LOAD_STORE_OP_MASK;
  4430. Register = (Instruction & ARM_SIMD_LOAD_STORE_REGISTER_MASK) >>
  4431. ARM_SIMD_LOAD_STORE_REGISTER_SHIFT;
  4432. //
  4433. // Determine if this is a load, store, push or pop.
  4434. //
  4435. PushPop = FALSE;
  4436. if ((Register == ARM_STACK_REGISTER) &&
  4437. ((Operation == ARM_SIMD_LOAD_STORE_OP_VPOP) ||
  4438. (Operation == ARM_SIMD_LOAD_STORE_OP_VPUSH))) {
  4439. if ((Instruction & ARM_LOAD_BIT) != 0) {
  4440. BaseMnemonic = ARM_VPOP_MNEMONIC;
  4441. } else {
  4442. BaseMnemonic = ARM_VPUSH_MNEMONIC;
  4443. }
  4444. PreConditionMnemonicSuffix = "";
  4445. MnemonicSuffix = "";
  4446. PushPop = TRUE;
  4447. } else {
  4448. if ((Instruction & ARM_LOAD_BIT) != 0) {
  4449. BaseMnemonic = ARM_VLD_MNEMONIC;
  4450. } else {
  4451. BaseMnemonic = ARM_VST_MNEMONIC;
  4452. }
  4453. PreConditionMnemonicSuffix = ARM_FLOATING_POINT_MULTIPLE;
  4454. MnemonicSuffix = DbgpArmGetLoadStoreTypeString(Instruction);
  4455. }
  4456. sprintf(Context->Mnemonic,
  4457. "%s%s%s",
  4458. BaseMnemonic,
  4459. PreConditionMnemonicSuffix,
  4460. MnemonicSuffix);
  4461. //
  4462. // Gather the starting vector and the vector count.
  4463. //
  4464. VectorCount = (Instruction & ARM_SIMD_LOAD_STORE_IMMEDIATE8_MASK) >>
  4465. ARM_SIMD_LOAD_STORE_IMMEDIATE8_SHIFT;
  4466. Vector = (Instruction & ARM_SIMD_LOAD_STORE_VECTOR_MASK) >>
  4467. ARM_SIMD_LOAD_STORE_VECTOR_SHIFT;
  4468. if ((Instruction & ARM_SIMD_LOAD_STORE_DOUBLE) != 0) {
  4469. if ((Instruction & ARM_SIMD_LOAD_STORE_VECTOR_BIT) != 0) {
  4470. Vector |= (1 << 4);
  4471. }
  4472. VectorCount >>= 1;
  4473. VectorTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  4474. } else {
  4475. Vector <<= 1;
  4476. if ((Instruction & ARM_SIMD_LOAD_STORE_VECTOR_BIT) != 0) {
  4477. Vector |= 1;
  4478. }
  4479. VectorTypeString = ARM_FLOATING_POINT_SINGLE_PRECISION_VECTOR;
  4480. }
  4481. //
  4482. // Write the register (the first operand) nad add the ! if the operation
  4483. // does a write back. Push/pop operations are always write back.
  4484. //
  4485. if (PushPop == FALSE) {
  4486. WriteBack = "";
  4487. if ((Instruction & ARM_WRITE_BACK_BIT) != 0) {
  4488. WriteBack = "!";
  4489. }
  4490. sprintf(Context->Operand1,
  4491. "%s%s",
  4492. DbgArmRegisterNames[Register],
  4493. WriteBack);
  4494. VectorListString = Context->Operand2;
  4495. VectorListStringSize = sizeof(Context->Operand2);
  4496. } else {
  4497. VectorListString = Context->Operand1;
  4498. VectorListStringSize = sizeof(Context->Operand1);
  4499. }
  4500. //
  4501. // Now print the vector list.
  4502. //
  4503. DbgpArmPrintVectorList(VectorListString,
  4504. VectorListStringSize,
  4505. Vector,
  4506. VectorCount,
  4507. 1,
  4508. VectorTypeString,
  4509. 0,
  4510. 0);
  4511. return;
  4512. }
  4513. VOID
  4514. DbgpArmDecodeSimdElementLoadAllLanes (
  4515. PARM_DISASSEMBLY Context
  4516. )
  4517. /*++
  4518. Routine Description:
  4519. This routine decodes an SIMD element load to all lanes instruction.
  4520. Arguments:
  4521. Context - Supplies a pointer to the disassembly context.
  4522. Return Value:
  4523. None.
  4524. --*/
  4525. {
  4526. PSTR AlignString;
  4527. PSTR ElementSuffix;
  4528. ULONG Instruction;
  4529. ULONG Rm;
  4530. ULONG Rn;
  4531. PSTR SizeTypeSuffix;
  4532. PSTR SizeValueSuffix;
  4533. ULONG Vector;
  4534. ULONG VectorCount;
  4535. ULONG VectorIncrement;
  4536. PSTR WriteBack;
  4537. Instruction = Context->Instruction;
  4538. Rm = (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_RM_MASK) >>
  4539. ARM_SIMD_ELEMENT_LOAD_STORE_RM_SHIFT;
  4540. Rn = (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_RN_MASK) >>
  4541. ARM_SIMD_ELEMENT_LOAD_STORE_RN_SHIFT;
  4542. Vector = (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_VECTOR_MASK) >>
  4543. ARM_SIMD_ELEMENT_LOAD_STORE_VECTOR_SHIFT;
  4544. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_VECTOR_BIT) != 0) {
  4545. Vector |= (1 << 4);
  4546. }
  4547. //
  4548. // Determine the number of elements in the structure being loaded and the
  4549. // number and spacing of the vectors. Also collect the alignment string,
  4550. // which depends on the size and the element count.
  4551. //
  4552. VectorIncrement = 1;
  4553. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_TWO_BIT) != 0) {
  4554. VectorIncrement = 2;
  4555. }
  4556. AlignString = "";
  4557. ElementSuffix = "";
  4558. VectorCount = 0;
  4559. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_ELEMENT_MASK) {
  4560. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_ELEMENT_1:
  4561. ElementSuffix = ARM_SIMD_ELEMENT_LOAD_STORE_1_ELEMENT_SUFFIX;
  4562. VectorCount = 1;
  4563. VectorIncrement = 1;
  4564. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_TWO_BIT) != 0) {
  4565. VectorCount = 2;
  4566. }
  4567. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_MASK) {
  4568. case ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_16:
  4569. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_ALIGN) != 0) {
  4570. AlignString = ARM_SIMD_ALIGN_16;
  4571. }
  4572. break;
  4573. case ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_32:
  4574. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_ALIGN) != 0) {
  4575. AlignString = ARM_SIMD_ALIGN_32;
  4576. }
  4577. break;
  4578. default:
  4579. break;
  4580. }
  4581. break;
  4582. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_ELEMENT_2:
  4583. ElementSuffix = ARM_SIMD_ELEMENT_LOAD_STORE_2_ELEMENT_SUFFIX;
  4584. VectorCount = 2;
  4585. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_MASK) {
  4586. case ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_8:
  4587. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_ALIGN) != 0) {
  4588. AlignString = ARM_SIMD_ALIGN_16;
  4589. }
  4590. break;
  4591. case ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_16:
  4592. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_ALIGN) != 0) {
  4593. AlignString = ARM_SIMD_ALIGN_32;
  4594. }
  4595. break;
  4596. case ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_32:
  4597. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_ALIGN) != 0) {
  4598. AlignString = ARM_SIMD_ALIGN_64;
  4599. }
  4600. break;
  4601. default:
  4602. break;
  4603. }
  4604. break;
  4605. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_ELEMENT_3:
  4606. ElementSuffix = ARM_SIMD_ELEMENT_LOAD_STORE_3_ELEMENT_SUFFIX;
  4607. VectorCount = 3;
  4608. break;
  4609. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_ELEMENT_4:
  4610. ElementSuffix = ARM_SIMD_ELEMENT_LOAD_STORE_4_ELEMENT_SUFFIX;
  4611. VectorCount = 4;
  4612. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_MASK) {
  4613. case ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_8:
  4614. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_ALIGN) != 0) {
  4615. AlignString = ARM_SIMD_ALIGN_32;
  4616. }
  4617. break;
  4618. case ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_16:
  4619. case ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_32:
  4620. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_ALIGN) != 0) {
  4621. AlignString = ARM_SIMD_ALIGN_64;
  4622. }
  4623. break;
  4624. default:
  4625. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_ALIGN) != 0) {
  4626. AlignString = ARM_SIMD_ALIGN_128;
  4627. }
  4628. break;
  4629. }
  4630. break;
  4631. //
  4632. // This should never hit as all values are accounted for above.
  4633. //
  4634. default:
  4635. break;
  4636. }
  4637. //
  4638. // Get the size suffix.
  4639. //
  4640. SizeValueSuffix = "";
  4641. SizeTypeSuffix = ARM_SIMD_DATA_DEFAULT;
  4642. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_MASK) {
  4643. case ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_8:
  4644. SizeValueSuffix = ARM_SIMD_DATA_SIZE_8;
  4645. break;
  4646. case ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_16:
  4647. SizeValueSuffix = ARM_SIMD_DATA_SIZE_16;
  4648. break;
  4649. case ARM_SIMD_ELEMENT_LOAD_ALL_LANES_SIZE_32:
  4650. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  4651. break;
  4652. default:
  4653. SizeTypeSuffix = "";
  4654. break;
  4655. }
  4656. sprintf(Context->Mnemonic, "%s%s", ARM_VLD_MNEMONIC, ElementSuffix);
  4657. sprintf(Context->PostConditionMnemonicSuffix,
  4658. "%s%s",
  4659. SizeTypeSuffix,
  4660. SizeValueSuffix);
  4661. //
  4662. // Assemble the vector list.
  4663. //
  4664. DbgpArmPrintVectorList(Context->Operand1,
  4665. sizeof(Context->Operand1),
  4666. Vector,
  4667. VectorCount,
  4668. VectorIncrement,
  4669. ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR,
  4670. 0,
  4671. DBG_ARM_VECTOR_LIST_FLAG_INDEX |
  4672. DBG_ARM_VECTOR_LIST_FLAG_ALL_LANES);
  4673. //
  4674. // Assemble the register operands.
  4675. //
  4676. WriteBack = "";
  4677. if (Rm == ARM_STACK_REGISTER) {
  4678. WriteBack = "!";
  4679. }
  4680. sprintf(Context->Operand2,
  4681. "[%s%s]%s",
  4682. DbgArmRegisterNames[Rn],
  4683. AlignString,
  4684. WriteBack);
  4685. if ((Rm != ARM_STACK_REGISTER) && (Rm != ARM_PC_REGISTER)) {
  4686. strcpy(Context->Operand3, DbgArmRegisterNames[Rm]);
  4687. }
  4688. return;
  4689. }
  4690. VOID
  4691. DbgpArmDecodeSimdElementLoadStoreSingle (
  4692. PARM_DISASSEMBLY Context
  4693. )
  4694. /*++
  4695. Routine Description:
  4696. This routine decodes an SIMD element load/store from/to a single structure.
  4697. Arguments:
  4698. Context - Supplies a pointer to the disassembly context.
  4699. Return Value:
  4700. None.
  4701. --*/
  4702. {
  4703. PSTR AlignString;
  4704. ULONG AlignValue;
  4705. PSTR BaseMnemonic;
  4706. PSTR ElementSuffix;
  4707. ULONG Instruction;
  4708. ULONG Rm;
  4709. ULONG Rn;
  4710. PSTR SizeTypeSuffix;
  4711. PSTR SizeValueSuffix;
  4712. ULONG Vector;
  4713. ULONG VectorCount;
  4714. ULONG VectorIncrement;
  4715. ULONG VectorIndex;
  4716. PSTR WriteBack;
  4717. AlignString = "";
  4718. ElementSuffix = "";
  4719. SizeValueSuffix = "";
  4720. SizeTypeSuffix = ARM_SIMD_DATA_DEFAULT;
  4721. //
  4722. // The base mnemonic is either vector load or vector store.
  4723. //
  4724. Instruction = Context->Instruction;
  4725. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_BIT) != 0) {
  4726. BaseMnemonic = ARM_VLD_MNEMONIC;
  4727. } else {
  4728. BaseMnemonic = ARM_VST_MNEMONIC;
  4729. }
  4730. Rm = (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_RM_MASK) >>
  4731. ARM_SIMD_ELEMENT_LOAD_STORE_RM_SHIFT;
  4732. Rn = (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_RN_MASK) >>
  4733. ARM_SIMD_ELEMENT_LOAD_STORE_RN_SHIFT;
  4734. Vector = (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_VECTOR_MASK) >>
  4735. ARM_SIMD_ELEMENT_LOAD_STORE_VECTOR_SHIFT;
  4736. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_VECTOR_BIT) != 0) {
  4737. Vector |= (1 << 4);
  4738. }
  4739. //
  4740. // Get the size suffix, vector index, vector increment, and alignment value.
  4741. //
  4742. AlignValue = 0;
  4743. VectorIndex = 0;
  4744. VectorIncrement = 1;
  4745. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_MASK) {
  4746. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_8:
  4747. SizeValueSuffix = ARM_SIMD_DATA_SIZE_8;
  4748. VectorIndex = (Instruction &
  4749. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_8_INDEX_MASK) >>
  4750. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_8_INDEX_SHIFT;
  4751. AlignValue = (Instruction &
  4752. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_8_ALIGN_MASK) >>
  4753. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_8_ALIGN_SHIFT;
  4754. break;
  4755. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_16:
  4756. SizeValueSuffix = ARM_SIMD_DATA_SIZE_16;
  4757. VectorIndex = (Instruction &
  4758. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_16_INDEX_MASK) >>
  4759. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_16_INDEX_SHIFT;
  4760. if ((Instruction &
  4761. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_16_INCREMENT) != 0) {
  4762. VectorIncrement = 2;
  4763. }
  4764. AlignValue = (Instruction &
  4765. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_16_ALIGN_MASK) >>
  4766. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_16_ALIGN_SHIFT;
  4767. break;
  4768. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_32:
  4769. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  4770. VectorIndex = (Instruction &
  4771. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_32_INDEX_MASK) >>
  4772. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_32_INDEX_SHIFT;
  4773. if ((Instruction &
  4774. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_32_INCREMENT) != 0) {
  4775. VectorIncrement = 2;
  4776. }
  4777. AlignValue = (Instruction &
  4778. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_32_ALIGN_MASK) >>
  4779. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_32_ALIGN_SHIFT;
  4780. break;
  4781. default:
  4782. SizeTypeSuffix = "";
  4783. break;
  4784. }
  4785. //
  4786. // Determine the number of elements being loaded/stored and the alignment
  4787. // string.
  4788. //
  4789. VectorCount = 0;
  4790. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_ELEMENT_MASK) {
  4791. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_ELEMENT_1:
  4792. ElementSuffix = ARM_SIMD_ELEMENT_LOAD_STORE_1_ELEMENT_SUFFIX;
  4793. VectorCount = 1;
  4794. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_MASK) {
  4795. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_16:
  4796. if (AlignValue != 0) {
  4797. AlignString = ARM_SIMD_ALIGN_16;
  4798. }
  4799. break;
  4800. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_32:
  4801. if (AlignValue != 0) {
  4802. AlignString = ARM_SIMD_ALIGN_32;
  4803. }
  4804. break;
  4805. default:
  4806. break;
  4807. }
  4808. break;
  4809. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_ELEMENT_2:
  4810. ElementSuffix = ARM_SIMD_ELEMENT_LOAD_STORE_2_ELEMENT_SUFFIX;
  4811. VectorCount = 2;
  4812. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_MASK) {
  4813. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_8:
  4814. if (AlignValue != 0) {
  4815. AlignString = ARM_SIMD_ALIGN_16;
  4816. }
  4817. break;
  4818. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_16:
  4819. if (AlignValue != 0) {
  4820. AlignString = ARM_SIMD_ALIGN_32;
  4821. }
  4822. break;
  4823. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_32:
  4824. if (AlignValue != 0) {
  4825. AlignString = ARM_SIMD_ALIGN_64;
  4826. }
  4827. break;
  4828. default:
  4829. break;
  4830. }
  4831. break;
  4832. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_ELEMENT_3:
  4833. ElementSuffix = ARM_SIMD_ELEMENT_LOAD_STORE_3_ELEMENT_SUFFIX;
  4834. VectorCount = 3;
  4835. break;
  4836. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_ELEMENT_4:
  4837. ElementSuffix = ARM_SIMD_ELEMENT_LOAD_STORE_4_ELEMENT_SUFFIX;
  4838. VectorCount = 4;
  4839. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_MASK) {
  4840. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_8:
  4841. if (AlignValue != 0) {
  4842. AlignString = ARM_SIMD_ALIGN_32;
  4843. }
  4844. break;
  4845. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_16:
  4846. if (AlignValue != 0) {
  4847. AlignString = ARM_SIMD_ALIGN_64;
  4848. }
  4849. break;
  4850. case ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_32:
  4851. if (AlignValue ==
  4852. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_32_ALIGN_64) {
  4853. AlignString = ARM_SIMD_ALIGN_64;
  4854. } else if (AlignValue ==
  4855. ARM_SIMD_ELEMENT_LOAD_STORE_SINGLE_SIZE_32_ALIGN_128) {
  4856. AlignString = ARM_SIMD_ALIGN_128;
  4857. }
  4858. break;
  4859. default:
  4860. break;
  4861. }
  4862. break;
  4863. //
  4864. // This should never hit as all values are accounted for above.
  4865. //
  4866. default:
  4867. break;
  4868. }
  4869. sprintf(Context->Mnemonic, "%s%s", BaseMnemonic, ElementSuffix);
  4870. sprintf(Context->PostConditionMnemonicSuffix,
  4871. "%s%s",
  4872. SizeTypeSuffix,
  4873. SizeValueSuffix);
  4874. //
  4875. // Assemble the vector list.
  4876. //
  4877. DbgpArmPrintVectorList(Context->Operand1,
  4878. sizeof(Context->Operand1),
  4879. Vector,
  4880. VectorCount,
  4881. VectorIncrement,
  4882. ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR,
  4883. VectorIndex,
  4884. DBG_ARM_VECTOR_LIST_FLAG_INDEX);
  4885. //
  4886. // Assemble the register operands.
  4887. //
  4888. WriteBack = "";
  4889. if (Rm == ARM_STACK_REGISTER) {
  4890. WriteBack = "!";
  4891. }
  4892. sprintf(Context->Operand2,
  4893. "[%s%s]%s",
  4894. DbgArmRegisterNames[Rn],
  4895. AlignString,
  4896. WriteBack);
  4897. if ((Rm != ARM_STACK_REGISTER) && (Rm != ARM_PC_REGISTER)) {
  4898. strcpy(Context->Operand3, DbgArmRegisterNames[Rm]);
  4899. }
  4900. return;
  4901. }
  4902. VOID
  4903. DbgpArmDecodeSimdElementLoadStoreMultiple (
  4904. PARM_DISASSEMBLY Context
  4905. )
  4906. /*++
  4907. Routine Description:
  4908. This routine decodes an SIMD element load/store from/to multiple structures.
  4909. Arguments:
  4910. Context - Supplies a pointer to the disassembly context.
  4911. Return Value:
  4912. None.
  4913. --*/
  4914. {
  4915. PSTR AlignString;
  4916. PSTR BaseMnemonic;
  4917. PSTR ElementSuffix;
  4918. ULONG Instruction;
  4919. ULONG Rm;
  4920. ULONG Rn;
  4921. PSTR SizeTypeSuffix;
  4922. PSTR SizeValueSuffix;
  4923. ULONG Type;
  4924. ULONG Vector;
  4925. ULONG VectorCount;
  4926. ULONG VectorIncrement;
  4927. PSTR WriteBack;
  4928. //
  4929. // The base mnemonic is either vector load or vector store.
  4930. //
  4931. Instruction = Context->Instruction;
  4932. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_BIT) != 0) {
  4933. BaseMnemonic = ARM_VLD_MNEMONIC;
  4934. } else {
  4935. BaseMnemonic = ARM_VST_MNEMONIC;
  4936. }
  4937. Rm = (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_RM_MASK) >>
  4938. ARM_SIMD_ELEMENT_LOAD_STORE_RM_SHIFT;
  4939. Rn = (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_RN_MASK) >>
  4940. ARM_SIMD_ELEMENT_LOAD_STORE_RN_SHIFT;
  4941. Vector = (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_VECTOR_MASK) >>
  4942. ARM_SIMD_ELEMENT_LOAD_STORE_VECTOR_SHIFT;
  4943. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_VECTOR_BIT) != 0) {
  4944. Vector |= (1 << 4);
  4945. }
  4946. //
  4947. // Get the size suffix.
  4948. //
  4949. SizeTypeSuffix = ARM_SIMD_DATA_DEFAULT;
  4950. SizeValueSuffix = "";
  4951. VectorIncrement = 1;
  4952. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_SIZE_MASK) {
  4953. case ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_SIZE_8:
  4954. SizeValueSuffix = ARM_SIMD_DATA_SIZE_8;
  4955. break;
  4956. case ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_SIZE_16:
  4957. SizeValueSuffix = ARM_SIMD_DATA_SIZE_16;
  4958. break;
  4959. case ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_SIZE_32:
  4960. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  4961. break;
  4962. case ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_SIZE_64:
  4963. SizeValueSuffix = ARM_SIMD_DATA_SIZE_64;
  4964. break;
  4965. default:
  4966. break;
  4967. }
  4968. //
  4969. // Get the alignment string.
  4970. //
  4971. AlignString = "";
  4972. switch (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_ALIGN_MASK) {
  4973. case ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_ALIGN_64:
  4974. AlignString = ARM_SIMD_ALIGN_64;
  4975. break;
  4976. case ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_ALIGN_128:
  4977. AlignString = ARM_SIMD_ALIGN_128;
  4978. break;
  4979. case ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_ALIGN_256:
  4980. AlignString = ARM_SIMD_ALIGN_256;
  4981. break;
  4982. default:
  4983. break;
  4984. }
  4985. //
  4986. // Determine the number of elements being loaded/stored, the vector count,
  4987. // vector increment based on the type field.
  4988. //
  4989. VectorIncrement = 1;
  4990. if ((Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_INCREMENT) != 0) {
  4991. VectorIncrement = 2;
  4992. }
  4993. Type = (Instruction & ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_TYPE_MASK) >>
  4994. ARM_SIMD_ELEMENT_LOAD_STORE_MULTIPLE_TYPE_SHIFT;
  4995. ElementSuffix = DbgArmSimdElementLoadStoreMultipleElementSuffix[Type];
  4996. VectorCount = DbgArmSimdElementLoadStoreMultipleVectorCount[Type];
  4997. sprintf(Context->Mnemonic, "%s%s", BaseMnemonic, ElementSuffix);
  4998. sprintf(Context->PostConditionMnemonicSuffix,
  4999. "%s%s",
  5000. SizeTypeSuffix,
  5001. SizeValueSuffix);
  5002. //
  5003. // Assemble the vector list.
  5004. //
  5005. DbgpArmPrintVectorList(Context->Operand1,
  5006. sizeof(Context->Operand1),
  5007. Vector,
  5008. VectorCount,
  5009. VectorIncrement,
  5010. ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR,
  5011. 0,
  5012. 0);
  5013. //
  5014. // Assemble the register operands.
  5015. //
  5016. WriteBack = "";
  5017. if (Rm == ARM_STACK_REGISTER) {
  5018. WriteBack = "!";
  5019. }
  5020. sprintf(Context->Operand2,
  5021. "[%s%s]%s",
  5022. DbgArmRegisterNames[Rn],
  5023. AlignString,
  5024. WriteBack);
  5025. if ((Rm != ARM_STACK_REGISTER) && (Rm != ARM_PC_REGISTER)) {
  5026. strcpy(Context->Operand3, DbgArmRegisterNames[Rm]);
  5027. }
  5028. return;
  5029. }
  5030. VOID
  5031. DbgpArmDecodeSimdThreeRegistersSameLength (
  5032. PARM_DISASSEMBLY Context
  5033. )
  5034. /*++
  5035. Routine Description:
  5036. This routine decodes an SIMD data processing instructions with three
  5037. registers of the same length.
  5038. Arguments:
  5039. Context - Supplies a pointer to the disassembly context.
  5040. Return Value:
  5041. None.
  5042. --*/
  5043. {
  5044. PSTR BaseMnemonic;
  5045. BOOL FloatSize;
  5046. ULONG Instruction;
  5047. BOOL IntegerSize;
  5048. BOOL NoSizeSuffix;
  5049. BOOL PolynomialSize;
  5050. BOOL SignedSize;
  5051. PSTR SizeTypeSuffix;
  5052. PSTR SizeValueSuffix;
  5053. BOOL TwoVectors;
  5054. ULONG VectorD;
  5055. PSTR VectorDString;
  5056. ULONG VectorM;
  5057. PSTR VectorMString;
  5058. ULONG VectorN;
  5059. PSTR VectorNString;
  5060. PSTR VectorTypeString;
  5061. FloatSize = FALSE;
  5062. IntegerSize = FALSE;
  5063. NoSizeSuffix = FALSE;
  5064. PolynomialSize = FALSE;
  5065. SignedSize = TRUE;
  5066. TwoVectors = FALSE;
  5067. Instruction = Context->Instruction;
  5068. VectorDString = Context->Operand1;
  5069. VectorD = (Instruction & ARM_SIMD_DATA_PROCESSING_VD_MASK) >>
  5070. ARM_SIMD_DATA_PROCESSING_VD_SHIFT;
  5071. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VD_BIT) != 0) {
  5072. VectorD |= (1 << 4);
  5073. }
  5074. VectorMString = Context->Operand3;
  5075. VectorM = (Instruction & ARM_SIMD_DATA_PROCESSING_VM_MASK) >>
  5076. ARM_SIMD_DATA_PROCESSING_VM_SHIFT;
  5077. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VM_BIT) != 0) {
  5078. VectorM |= (1 << 4);
  5079. }
  5080. VectorNString = Context->Operand2;
  5081. VectorN = (Instruction & ARM_SIMD_DATA_PROCESSING_VN_MASK) >>
  5082. ARM_SIMD_DATA_PROCESSING_VN_SHIFT;
  5083. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VN_BIT) != 0) {
  5084. VectorN |= (1 << 4);
  5085. }
  5086. VectorTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5087. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  5088. VectorTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5089. }
  5090. //
  5091. // Determine the base mnemonic. Some instructions ignore the size encodings
  5092. // and others have integer or float encodings rather than the default
  5093. // signed/unsigned. Take note so that the correct size suffix can be
  5094. // calculated.
  5095. //
  5096. BaseMnemonic = NULL;
  5097. switch (Instruction & ARM_SIMD_DATA_PROCESSING_3_SAME_OPERATION_MASK) {
  5098. case ARM_SIMD_VHADD_MASK:
  5099. BaseMnemonic = ARM_VHADD_MNEMONIC;
  5100. break;
  5101. case ARM_SIMD_VQADD_MASK:
  5102. BaseMnemonic = ARM_VQADD_MNEMONIC;
  5103. break;
  5104. case ARM_SIMD_VRHADD_MASK:
  5105. BaseMnemonic = ARM_VRHADD_MNEMONIC;
  5106. break;
  5107. case ARM_SIMD_BITWISE_MASK:
  5108. switch (Instruction & ARM_SIMD_BITWISE_OP_MASK) {
  5109. case ARM_SIMD_BITWISE_VAND_VALUE:
  5110. BaseMnemonic = ARM_VAND_MNEMONIC;
  5111. break;
  5112. case ARM_SIMD_BITWISE_VBIC_VALUE:
  5113. BaseMnemonic = ARM_VBIC_MNEMONIC;
  5114. break;
  5115. case ARM_SIMD_BITWISE_VORR_VALUE:
  5116. if (VectorM == VectorN) {
  5117. BaseMnemonic = ARM_VMOV_MNEMONIC;
  5118. TwoVectors = TRUE;
  5119. } else {
  5120. BaseMnemonic = ARM_VORR_MNEMONIC;
  5121. }
  5122. break;
  5123. case ARM_SIMD_BITWISE_VORN_VALUE:
  5124. BaseMnemonic = ARM_VORN_MNEMONIC;
  5125. break;
  5126. case ARM_SIMD_BITWISE_VEOR_VALUE:
  5127. BaseMnemonic = ARM_VEOR_MNEMONIC;
  5128. break;
  5129. case ARM_SIMD_BITWISE_VBSL_VALUE:
  5130. BaseMnemonic = ARM_VBSL_MNEMONIC;
  5131. break;
  5132. case ARM_SIMD_BITWISE_VBIT_VALUE:
  5133. BaseMnemonic = ARM_VBIT_MNEMONIC;
  5134. break;
  5135. case ARM_SIMD_BITWISE_VBIF_VALUE:
  5136. BaseMnemonic = ARM_VBIF_MNEMONIC;
  5137. break;
  5138. default:
  5139. break;
  5140. }
  5141. NoSizeSuffix = TRUE;
  5142. break;
  5143. case ARM_SIMD_VHSUB_MASK:
  5144. BaseMnemonic = ARM_VHSUB_MNEMONIC;
  5145. break;
  5146. case ARM_SIMD_VQSUB_MASK:
  5147. BaseMnemonic = ARM_VQSUB_MNEMONIC;
  5148. break;
  5149. case ARM_SIMD_VCGT_MASK:
  5150. BaseMnemonic = ARM_VCGT_MNEMONIC;
  5151. break;
  5152. case ARM_SIMD_VCGE_MASK:
  5153. BaseMnemonic = ARM_VCGE_MNEMONIC;
  5154. break;
  5155. case ARM_SIMD_VSHL_REG_MASK:
  5156. BaseMnemonic = ARM_VSHL_MNEMONIC;
  5157. VectorMString = Context->Operand2;
  5158. VectorNString = Context->Operand3;
  5159. break;
  5160. case ARM_SIMD_VQSHL_REG_MASK:
  5161. BaseMnemonic = ARM_VQSHL_MNEMONIC;
  5162. VectorMString = Context->Operand2;
  5163. VectorNString = Context->Operand3;
  5164. break;
  5165. case ARM_SIMD_VRSHL_MASK:
  5166. BaseMnemonic = ARM_VRSHL_MNEMONIC;
  5167. VectorMString = Context->Operand2;
  5168. VectorNString = Context->Operand3;
  5169. break;
  5170. case ARM_SIMD_VQRSHL_MASK:
  5171. BaseMnemonic = ARM_VQRSHL_MNEMONIC;
  5172. VectorMString = Context->Operand2;
  5173. VectorNString = Context->Operand3;
  5174. break;
  5175. case ARM_SIMD_VMAX_INT_MASK:
  5176. BaseMnemonic = ARM_VMAX_MNEMONIC;
  5177. break;
  5178. case ARM_SIMD_VMIN_INT_MASK:
  5179. BaseMnemonic = ARM_VMIN_MNEMONIC;
  5180. break;
  5181. case ARM_SIMD_VABD_MASK:
  5182. BaseMnemonic = ARM_VABD_MNEMONIC;
  5183. break;
  5184. case ARM_SIMD_VABA_MASK:
  5185. BaseMnemonic = ARM_VABA_MNEMONIC;
  5186. break;
  5187. case ARM_SIMD_VADD_INT_MASK:
  5188. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5189. BaseMnemonic = ARM_VSUB_MNEMONIC;
  5190. } else {
  5191. BaseMnemonic = ARM_VADD_MNEMONIC;
  5192. }
  5193. IntegerSize = TRUE;
  5194. break;
  5195. case ARM_SIMD_VTST_MASK:
  5196. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5197. BaseMnemonic = ARM_VCEQ_MNEMONIC;
  5198. IntegerSize = TRUE;
  5199. } else {
  5200. BaseMnemonic = ARM_VTST_MNEMONIC;
  5201. SignedSize = FALSE;
  5202. }
  5203. break;
  5204. case ARM_SIMD_VMLA_MASK:
  5205. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5206. BaseMnemonic = ARM_VMLS_MNEMONIC;
  5207. } else {
  5208. BaseMnemonic = ARM_VMLA_MNEMONIC;
  5209. }
  5210. IntegerSize = TRUE;
  5211. break;
  5212. case ARM_SIMD_VMUL_MASK:
  5213. BaseMnemonic = ARM_VMUL_MNEMONIC;
  5214. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5215. PolynomialSize = TRUE;
  5216. }
  5217. break;
  5218. case ARM_SIMD_VPMAX_INT_MASK:
  5219. BaseMnemonic = ARM_VPMAX_MNEMONIC;
  5220. break;
  5221. case ARM_SIMD_VPMIN_INT_MASK:
  5222. BaseMnemonic = ARM_VPMIN_MNEMONIC;
  5223. break;
  5224. case ARM_SIMD_VQDMULH_MASK:
  5225. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5226. BaseMnemonic = ARM_VQRDMULH_MNEMONIC;
  5227. } else {
  5228. BaseMnemonic = ARM_VQDMULH_MNEMONIC;
  5229. }
  5230. Instruction &= ~ARM_SIMD_DATA_PROCESSING_UNSIGNED;
  5231. break;
  5232. case ARM_SIMD_VPADD_INT_MASK:
  5233. BaseMnemonic = ARM_VPADD_MNEMONIC;
  5234. IntegerSize = TRUE;
  5235. break;
  5236. case ARM_SIMD_VFMA_MASK:
  5237. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VFM_SUBTRACT) != 0) {
  5238. BaseMnemonic = ARM_VFMS_MNEMONIC;
  5239. } else {
  5240. BaseMnemonic = ARM_VFMA_MNEMONIC;
  5241. }
  5242. FloatSize = TRUE;
  5243. break;
  5244. case ARM_SIMD_FP_MATH_MASK:
  5245. case ARM_SIMD_FP_MATH_MASK | ARM_SIMD_FP_MULT:
  5246. switch (Instruction & ARM_SIMD_FP_MATH_OP_MASK) {
  5247. case ARM_SIMD_FP_MATH_VADD_VALUE:
  5248. BaseMnemonic = ARM_VADD_MNEMONIC;
  5249. break;
  5250. case ARM_SIMD_FP_MATH_VSUB_VALUE:
  5251. BaseMnemonic = ARM_VSUB_MNEMONIC;
  5252. break;
  5253. case ARM_SIMD_FP_MATH_VPADD_VALUE:
  5254. BaseMnemonic = ARM_VPADD_MNEMONIC;
  5255. break;
  5256. case ARM_SIMD_FP_MATH_VABD_VALUE:
  5257. BaseMnemonic = ARM_VABD_MNEMONIC;
  5258. break;
  5259. case ARM_SIMD_FP_MATH_VMLA_VALUE:
  5260. BaseMnemonic = ARM_VMLA_MNEMONIC;
  5261. break;
  5262. case ARM_SIMD_FP_MATH_VMLS_VALUE:
  5263. BaseMnemonic = ARM_VMLS_MNEMONIC;
  5264. break;
  5265. case ARM_SIMD_FP_MATH_VMUL_VALUE:
  5266. BaseMnemonic = ARM_VMUL_MNEMONIC;
  5267. break;
  5268. default:
  5269. break;
  5270. }
  5271. FloatSize = TRUE;
  5272. break;
  5273. case ARM_SIMD_COMPARE_MASK:
  5274. case ARM_SIMD_COMPARE_MASK | ARM_SIMD_ABSOLUTE:
  5275. switch (Instruction & ARM_SIMD_COMPARE_OP_MASK) {
  5276. case ARM_SIMD_COMPARE_VCEQ_VALUE:
  5277. BaseMnemonic = ARM_VCEQ_MNEMONIC;
  5278. break;
  5279. case ARM_SIMD_COMPARE_VCGE_VALUE:
  5280. BaseMnemonic = ARM_VCGE_MNEMONIC;
  5281. break;
  5282. case ARM_SIMD_COMPARE_VCGT_VALUE:
  5283. BaseMnemonic = ARM_VCGT_MNEMONIC;
  5284. break;
  5285. case ARM_SIMD_COMPARE_VACGE_VALUE:
  5286. BaseMnemonic = ARM_VACGE_MNEMONIC;
  5287. break;
  5288. case ARM_SIMD_COMPARE_VACGT_VALUE:
  5289. BaseMnemonic = ARM_VACGT_MNEMONIC;
  5290. break;
  5291. default:
  5292. break;
  5293. }
  5294. FloatSize = TRUE;
  5295. break;
  5296. case ARM_SIMD_MIN_MAX_FLOAT_MASK:
  5297. switch (Instruction & ARM_SIMD_MIN_MAX_FLOAT_OP_MASK) {
  5298. case ARM_SIMD_MIN_MAX_FLOAT_VMAX_VALUE:
  5299. BaseMnemonic = ARM_VMAX_MNEMONIC;
  5300. break;
  5301. case ARM_SIMD_MIN_MAX_FLOAT_VMIN_VALUE:
  5302. BaseMnemonic = ARM_VMIN_MNEMONIC;
  5303. break;
  5304. case ARM_SIMD_MIN_MAX_FLOAT_VPMAX_VALUE:
  5305. BaseMnemonic = ARM_VPMAX_MNEMONIC;
  5306. break;
  5307. case ARM_SIMD_MIN_MAX_FLOAT_VPMIN_VALUE:
  5308. BaseMnemonic = ARM_VPMIN_MNEMONIC;
  5309. break;
  5310. default:
  5311. break;
  5312. }
  5313. FloatSize = TRUE;
  5314. break;
  5315. case ARM_SIMD_RECIPROCOL_MASK:
  5316. switch (Instruction & ARM_SIMD_RECIPROCOL_OP_MASK) {
  5317. case ARM_SIMD_RECIPROCOL_VRECPS_VALUE:
  5318. BaseMnemonic = ARM_VRECPS_MNEMONIC;
  5319. break;
  5320. case ARM_SIMD_RECIPROCOL_VRSQRTS_VALUE:
  5321. BaseMnemonic = ARM_VRSQRTS_MNEMONIC;
  5322. break;
  5323. default:
  5324. break;
  5325. }
  5326. FloatSize = TRUE;
  5327. break;
  5328. default:
  5329. break;
  5330. }
  5331. if (BaseMnemonic == NULL) {
  5332. DbgpArmDecodeUndefined(Context);
  5333. return;
  5334. }
  5335. //
  5336. // Parse the instruction assuming it uses the default size suffix.
  5337. //
  5338. SizeTypeSuffix = "";
  5339. SizeValueSuffix = "";
  5340. if (NoSizeSuffix == FALSE) {
  5341. if (FloatSize != FALSE) {
  5342. SizeTypeSuffix = ARM_SIMD_DATA_FLOAT;
  5343. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  5344. } else if (IntegerSize != FALSE) {
  5345. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5346. } else if (PolynomialSize != FALSE) {
  5347. SizeTypeSuffix = ARM_SIMD_DATA_POLYNOMIAL;
  5348. } else if (SignedSize == FALSE) {
  5349. SizeTypeSuffix = ARM_SIMD_DATA_DEFAULT;
  5350. } else if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5351. SizeTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  5352. } else {
  5353. SizeTypeSuffix = ARM_SIMD_DATA_SIGNED;
  5354. }
  5355. }
  5356. if ((NoSizeSuffix == FALSE) && (FloatSize == FALSE)) {
  5357. switch (Instruction & ARM_SIMD_DATA_PROCESSING_3_SAME_SIZE_MASK) {
  5358. case ARM_SIMD_DATA_PROCESSING_3_SAME_SIZE_8:
  5359. SizeValueSuffix = ARM_SIMD_DATA_SIZE_8;
  5360. break;
  5361. case ARM_SIMD_DATA_PROCESSING_3_SAME_SIZE_16:
  5362. SizeValueSuffix = ARM_SIMD_DATA_SIZE_16;
  5363. break;
  5364. case ARM_SIMD_DATA_PROCESSING_3_SAME_SIZE_32:
  5365. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  5366. break;
  5367. case ARM_SIMD_DATA_PROCESSING_3_SAME_SIZE_64:
  5368. SizeValueSuffix = ARM_SIMD_DATA_SIZE_64;
  5369. break;
  5370. default:
  5371. break;
  5372. }
  5373. }
  5374. strcpy(Context->Mnemonic, BaseMnemonic);
  5375. sprintf(Context->PostConditionMnemonicSuffix,
  5376. "%s%s",
  5377. SizeTypeSuffix,
  5378. SizeValueSuffix);
  5379. sprintf(VectorDString, "%s%d", VectorTypeString, VectorD);
  5380. sprintf(VectorNString, "%s%d", VectorTypeString, VectorN);
  5381. if (TwoVectors == FALSE) {
  5382. sprintf(VectorMString, "%s%d", VectorTypeString, VectorM);
  5383. }
  5384. return;
  5385. }
  5386. VOID
  5387. DbgpArmDecodeSimdOneRegister (
  5388. PARM_DISASSEMBLY Context
  5389. )
  5390. /*++
  5391. Routine Description:
  5392. This routine decodes an SIMD data processing instrution that uses one
  5393. register and a modified immediate value.
  5394. Arguments:
  5395. Context - Supplies a pointer to the disassembly context.
  5396. Return Value:
  5397. None.
  5398. --*/
  5399. {
  5400. PSTR BaseMnemonic;
  5401. ULONG Cmode;
  5402. ARM_IMMEDIATE_FLOAT Float;
  5403. ULONGLONG Immediate;
  5404. ULONG Immediate8;
  5405. ULONG Instruction;
  5406. BOOL PrintFloat;
  5407. PSTR SizeTypeSuffix;
  5408. PSTR SizeValueSuffix;
  5409. ULONG Vector;
  5410. PSTR VectorTypeString;
  5411. PrintFloat = FALSE;
  5412. Float.Immediate = 0;
  5413. Instruction = Context->Instruction;
  5414. //
  5415. // Decode the immediate value and the size suffix using the cmode value and
  5416. // the op bit.
  5417. //
  5418. Immediate8 = ARM_SIMD_BUILD_IMMEDIATE8(Instruction);
  5419. Cmode = (Instruction & ARM_SIMD_DATA_PROCESSING_1_REGISTER_CMODE_MASK) >>
  5420. ARM_SIMD_DATA_PROCESSING_1_REGISTER_CMODE_SHIFT;
  5421. switch (Cmode & ARM_SIMD_CMODE_TYPE_MASK) {
  5422. case ARM_SIMD_CMODE_TYPE_I32_NO_SHIFT:
  5423. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5424. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  5425. Immediate = Immediate8;
  5426. break;
  5427. case ARM_SIMD_CMODE_TYPE_I32_SHIFT_8:
  5428. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5429. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  5430. Immediate = Immediate8 << 8;
  5431. break;
  5432. case ARM_SIMD_CMODE_TYPE_I32_SHIFT_16:
  5433. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5434. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  5435. Immediate = Immediate8 << 16;
  5436. break;
  5437. case ARM_SIMD_CMODE_TYPE_I32_SHIFT_24:
  5438. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5439. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  5440. Immediate = Immediate8 << 24;
  5441. break;
  5442. case ARM_SIMD_CMODE_TYPE_I16_NO_SHIFT:
  5443. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5444. SizeValueSuffix = ARM_SIMD_DATA_SIZE_16;
  5445. Immediate = Immediate8;
  5446. break;
  5447. case ARM_SIMD_CMODE_TYPE_I16_SHIFT_8:
  5448. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5449. SizeValueSuffix = ARM_SIMD_DATA_SIZE_16;
  5450. Immediate = Immediate8 << 8;
  5451. break;
  5452. case ARM_SIMD_CMODE_TYPE_I32_SHIFT_ONES:
  5453. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5454. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  5455. if ((Cmode & ARM_SIMD_CMODE_SHIFT_ONES_16) != 0) {
  5456. Immediate = Immediate8 << 16;
  5457. Immediate |= 0xFFFF;
  5458. } else {
  5459. Immediate = Immediate8 << 8;
  5460. Immediate |= 0xFF;
  5461. }
  5462. break;
  5463. default:
  5464. if ((Instruction & ARM_SIMD_DATA_PROCESSING_1_REGISTER_OP_BIT) != 0) {
  5465. if ((Cmode & ARM_SIMD_CMODE_UNDEFINED) != 0) {
  5466. DbgpArmDecodeUndefined(Context);
  5467. return;
  5468. }
  5469. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5470. SizeValueSuffix = ARM_SIMD_DATA_SIZE_64;
  5471. Immediate = ARM_SIMD_BUILD_IMMEDIATE64(Instruction);
  5472. } else {
  5473. if ((Cmode & ARM_SIMD_CMODE_FLOAT_32) != 0) {
  5474. SizeTypeSuffix = ARM_SIMD_DATA_FLOAT;
  5475. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  5476. Float.Immediate = ARM_SIMD_BUILD_IMMEDIATE32(Instruction);
  5477. PrintFloat = TRUE;
  5478. } else {
  5479. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5480. SizeValueSuffix = ARM_SIMD_DATA_SIZE_8;
  5481. Immediate = Immediate8;
  5482. }
  5483. }
  5484. break;
  5485. }
  5486. //
  5487. // Get the mnemonic based on the cmode value and the op bit.
  5488. //
  5489. if ((Instruction & ARM_SIMD_DATA_PROCESSING_1_REGISTER_OP_BIT) == 0) {
  5490. //
  5491. // For all modes less than 12, the even modes are vmov and the odds are
  5492. // vorr.
  5493. //
  5494. if ((Cmode < ARM_SIMD_CMODE_NO_OP_VORR_MAX) &&
  5495. ((Cmode & ARM_SIMD_CMODE_NO_OP_VORR_BIT) != 0)) {
  5496. BaseMnemonic = ARM_VORR_MNEMONIC;
  5497. } else {
  5498. BaseMnemonic = ARM_VMOV_MNEMONIC;
  5499. }
  5500. } else {
  5501. //
  5502. // With the two exceptions of cmodes 14 and 15, the odd modes are vbic
  5503. // and the even modes are vmvn.
  5504. //
  5505. if ((Cmode < ARM_SIMD_CMODE_OP_VBIC_MAX) &&
  5506. ((Cmode & ARM_SIMD_CMODE_OP_VBIC_BIT) != 0)) {
  5507. BaseMnemonic = ARM_VBIC_MNEMONIC;
  5508. } else if (Cmode == ARM_SIMD_CMODE_OP_VMOV) {
  5509. BaseMnemonic = ARM_VMOV_MNEMONIC;
  5510. } else if (Cmode == ARM_SIMD_CMODE_OP_UNDEFINED) {
  5511. DbgpArmDecodeUndefined(Context);
  5512. return;
  5513. } else {
  5514. BaseMnemonic = ARM_VMVN_MNEMONIC;
  5515. }
  5516. }
  5517. Vector = (Instruction & ARM_SIMD_DATA_PROCESSING_VD_MASK) >>
  5518. ARM_SIMD_DATA_PROCESSING_VD_SHIFT;
  5519. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VD_BIT) != 0) {
  5520. Vector |= (1 << 4);
  5521. }
  5522. VectorTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5523. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  5524. VectorTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5525. }
  5526. strcpy(Context->Mnemonic, BaseMnemonic);
  5527. sprintf(Context->PostConditionMnemonicSuffix,
  5528. "%s%s",
  5529. SizeTypeSuffix,
  5530. SizeValueSuffix);
  5531. sprintf(Context->Operand1, "%s%d", VectorTypeString, Vector);
  5532. if (PrintFloat == FALSE) {
  5533. sprintf(Context->Operand2, "#%lld ; 0x%lld", Immediate, Immediate);
  5534. } else {
  5535. sprintf(Context->Operand2,
  5536. "#%d ; 0x%x %g",
  5537. Immediate8,
  5538. Float.Immediate,
  5539. Float.Float);
  5540. }
  5541. return;
  5542. }
  5543. VOID
  5544. DbgpArmDecodeSimdTwoRegistersWithShift (
  5545. PARM_DISASSEMBLY Context
  5546. )
  5547. /*++
  5548. Routine Description:
  5549. This routine decodes an SIMD data instruction with two registers and a
  5550. shift amount.
  5551. Arguments:
  5552. Context - Supplies a pointer to the disassembly context.
  5553. Return Value:
  5554. None.
  5555. --*/
  5556. {
  5557. PSTR BaseMnemonic;
  5558. PSTR DestinationSizeSuffix;
  5559. PSTR DestinationTypeSuffix;
  5560. ULONG Immediate;
  5561. ULONG Immediate6;
  5562. ULONG Instruction;
  5563. PSTR SourceSizeSuffix;
  5564. PSTR SourceTypeSuffix;
  5565. ULONG VectorD;
  5566. PSTR VectorDTypeString;
  5567. ULONG VectorM;
  5568. PSTR VectorMTypeString;
  5569. SourceSizeSuffix = "";
  5570. //
  5571. // Gather the information that is shared by most of the two register shift
  5572. // instructions.
  5573. //
  5574. Instruction = Context->Instruction;
  5575. VectorD = (Instruction & ARM_SIMD_DATA_PROCESSING_VD_MASK) >>
  5576. ARM_SIMD_DATA_PROCESSING_VD_SHIFT;
  5577. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VD_BIT) != 0) {
  5578. VectorD |= (1 << 4);
  5579. }
  5580. VectorM = (Instruction & ARM_SIMD_DATA_PROCESSING_VM_MASK) >>
  5581. ARM_SIMD_DATA_PROCESSING_VM_SHIFT;
  5582. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VM_BIT) != 0) {
  5583. VectorM |= (1 << 4);
  5584. }
  5585. VectorDTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5586. VectorMTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5587. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  5588. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5589. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5590. }
  5591. SourceTypeSuffix = "";
  5592. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  5593. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5594. DestinationTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  5595. }
  5596. DestinationSizeSuffix = "";
  5597. Immediate6 = (Instruction & ARM_SIMD_2_REGISTER_SHIFT_IMMEDIATE6_MASK) >>
  5598. ARM_SIMD_2_REGISTER_SHIFT_IMMEDIATE6_SHIFT;
  5599. if ((Instruction & ARM_SIMD_2_REGISTER_SHIFT_64) == 0) {
  5600. if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_32) != 0) {
  5601. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  5602. Immediate = 32;
  5603. Immediate -= (Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_32_MASK);
  5604. } else if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_16) != 0) {
  5605. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_16;
  5606. Immediate = 16;
  5607. Immediate -= (Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_16_MASK);
  5608. } else if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_8) != 0) {
  5609. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_8;
  5610. Immediate = 8;
  5611. Immediate -= (Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_8_MASK);
  5612. } else {
  5613. DbgpArmDecodeUndefined(Context);
  5614. return;
  5615. }
  5616. } else {
  5617. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_64;
  5618. Immediate = 64 - Immediate6;
  5619. }
  5620. //
  5621. // Determine the base mnemonic and override any of the size or type
  5622. // information collected above.
  5623. //
  5624. BaseMnemonic = NULL;
  5625. switch (Instruction & ARM_SIMD_2_REGISTER_SHIFT_OPERATION_MASK) {
  5626. case ARM_SIMD_VSHR_MASK:
  5627. BaseMnemonic = ARM_VSHR_MNEMONIC;
  5628. break;
  5629. case ARM_SIMD_VSRA_MASK:
  5630. BaseMnemonic = ARM_VSRA_MNEMONIC;
  5631. break;
  5632. case ARM_SIMD_VRSHR_MASK:
  5633. BaseMnemonic = ARM_VRSHR_MNEMONIC;
  5634. break;
  5635. case ARM_SIMD_VRSRA_MASK:
  5636. BaseMnemonic = ARM_VRSRA_MNEMONIC;
  5637. break;
  5638. case ARM_SIMD_VSRI_MASK:
  5639. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5640. BaseMnemonic = ARM_VSRI_MNEMONIC;
  5641. }
  5642. break;
  5643. case ARM_SIMD_VSHL_MASK:
  5644. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5645. BaseMnemonic = ARM_VSLI_MNEMONIC;
  5646. DestinationTypeSuffix = "";
  5647. } else {
  5648. BaseMnemonic = ARM_VSHL_MNEMONIC;
  5649. DestinationTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5650. }
  5651. break;
  5652. case ARM_SIMD_VQSHLU_MASK:
  5653. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5654. BaseMnemonic = ARM_VQSHLU_MNEMONIC;
  5655. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  5656. }
  5657. break;
  5658. case ARM_SIMD_VQSHL_IMM_MASK:
  5659. BaseMnemonic = ARM_VQSHL_MNEMONIC;
  5660. break;
  5661. case ARM_SIMD_VSHRN_MASK:
  5662. switch (Instruction & ARM_SIMD_VSHRN_OP_MASK) {
  5663. case ARM_SIMD_VSHRN_OP_VALUE:
  5664. BaseMnemonic = ARM_VSHRN_MNEMONIC;
  5665. DestinationTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5666. break;
  5667. case ARM_SIMD_VRSHRN_OP_VALUE:
  5668. BaseMnemonic = ARM_VRSHRN_MNEMONIC;
  5669. DestinationTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5670. break;
  5671. case ARM_SIMD_VQSHRUN_OP_VALUE:
  5672. BaseMnemonic = ARM_VQSHRUN_MNEMONIC;
  5673. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  5674. break;
  5675. case ARM_SIMD_VQRSHRUN_OP_VALUE:
  5676. BaseMnemonic = ARM_VQRSHRUN_MNEMONIC;
  5677. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  5678. break;
  5679. default:
  5680. break;
  5681. }
  5682. //
  5683. // The size suffix is twice that of the normal encoding.
  5684. //
  5685. if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_32) != 0) {
  5686. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_64;
  5687. } else if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_16) != 0) {
  5688. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  5689. } else if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_8) != 0) {
  5690. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_16;
  5691. }
  5692. VectorDTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5693. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5694. break;
  5695. case ARM_SIMD_VQSHRN_MASK:
  5696. switch (Instruction & ARM_SIMD_VQSHRN_OP_MASK) {
  5697. case ARM_SIMD_VQSHRN_OP_VALUE:
  5698. BaseMnemonic = ARM_VQSHRN_MNEMONIC;
  5699. break;
  5700. case ARM_SIMD_VQRSHRN_OP_VALUE:
  5701. BaseMnemonic = ARM_VQRSHRN_MNEMONIC;
  5702. break;
  5703. default:
  5704. break;
  5705. }
  5706. //
  5707. // The size suffix is twice that of the normal encoding.
  5708. //
  5709. if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_32) != 0) {
  5710. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_64;
  5711. } else if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_16) != 0) {
  5712. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  5713. } else if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_8) != 0) {
  5714. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_16;
  5715. }
  5716. VectorDTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5717. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5718. break;
  5719. case ARM_SIMD_VSHLL_MASK:
  5720. if ((Instruction & ARM_SIMD_VSHLL_OP_MASK) != ARM_SIMD_VSHLL_OP_VALUE) {
  5721. break;
  5722. }
  5723. //
  5724. // The size suffix is twice that of the normal encoding.
  5725. //
  5726. if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_32) != 0) {
  5727. Immediate = Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_32_MASK;
  5728. } else if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_16) != 0) {
  5729. Immediate = Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_16_MASK;
  5730. } else if ((Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_8) != 0) {
  5731. Immediate = Immediate6 & ARM_SIMD_2_REGISTER_SHIFT_SIZE_8_MASK;
  5732. }
  5733. if (Immediate == 0) {
  5734. BaseMnemonic = ARM_VMOVL_MNEMONIC;
  5735. } else {
  5736. BaseMnemonic = ARM_VSHLL_MNEMONIC;
  5737. }
  5738. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5739. VectorMTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5740. break;
  5741. case ARM_SIMD_VCVT_TO_FLOAT_MASK:
  5742. BaseMnemonic = ARM_VCVT_MNEMONIC;
  5743. SourceSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  5744. DestinationTypeSuffix = ARM_SIMD_DATA_FLOAT;
  5745. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  5746. Immediate = 64 - Immediate6;
  5747. break;
  5748. case ARM_SIMD_VCVT_TO_FIXED_MASK:
  5749. BaseMnemonic = ARM_VCVT_MNEMONIC;
  5750. SourceTypeSuffix = ARM_SIMD_DATA_FLOAT;
  5751. SourceSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  5752. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  5753. Immediate = 64 - Immediate6;
  5754. break;
  5755. default:
  5756. break;
  5757. }
  5758. if (BaseMnemonic == NULL) {
  5759. DbgpArmDecodeUndefined(Context);
  5760. return;
  5761. }
  5762. strcpy(Context->Mnemonic, BaseMnemonic);
  5763. sprintf(Context->PostConditionMnemonicSuffix,
  5764. "%s%s%s%s",
  5765. DestinationTypeSuffix,
  5766. DestinationSizeSuffix,
  5767. SourceTypeSuffix,
  5768. SourceSizeSuffix);
  5769. sprintf(Context->Operand1, "%s%d", VectorDTypeString, VectorD);
  5770. sprintf(Context->Operand2, "%s%d", VectorMTypeString, VectorM);
  5771. sprintf(Context->Operand3, "#%d ; 0x%x", Immediate, Immediate);
  5772. return;
  5773. }
  5774. VOID
  5775. DbgpArmDecodeSimdThreeRegistersDifferentLength (
  5776. PARM_DISASSEMBLY Context
  5777. )
  5778. /*++
  5779. Routine Description:
  5780. This routine decodes an SIMD data instruction with three registers of
  5781. different lengths.
  5782. Arguments:
  5783. Context - Supplies a pointer to the disassembly context.
  5784. Return Value:
  5785. None.
  5786. --*/
  5787. {
  5788. PSTR BaseMnemonic;
  5789. ULONG Instruction;
  5790. ULONG Size;
  5791. PSTR SizeTypeSuffix;
  5792. PSTR SizeValueSuffix;
  5793. ULONG VectorD;
  5794. PSTR VectorDTypeString;
  5795. ULONG VectorM;
  5796. PSTR VectorMTypeString;
  5797. ULONG VectorN;
  5798. PSTR VectorNTypeString;
  5799. //
  5800. // Gather the values that are common to most of the instructions.
  5801. //
  5802. Instruction = Context->Instruction;
  5803. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5804. VectorD = (Instruction & ARM_SIMD_DATA_PROCESSING_VD_MASK) >>
  5805. ARM_SIMD_DATA_PROCESSING_VD_SHIFT;
  5806. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VD_BIT) != 0) {
  5807. VectorD |= (1 << 4);
  5808. }
  5809. VectorMTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5810. VectorM = (Instruction & ARM_SIMD_DATA_PROCESSING_VM_MASK) >>
  5811. ARM_SIMD_DATA_PROCESSING_VM_SHIFT;
  5812. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VM_BIT) != 0) {
  5813. VectorM |= (1 << 4);
  5814. }
  5815. VectorNTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5816. VectorN = (Instruction & ARM_SIMD_DATA_PROCESSING_VN_MASK) >>
  5817. ARM_SIMD_DATA_PROCESSING_VN_SHIFT;
  5818. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VN_BIT) != 0) {
  5819. VectorN |= (1 << 4);
  5820. }
  5821. SizeTypeSuffix = ARM_SIMD_DATA_SIGNED;
  5822. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5823. SizeTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  5824. }
  5825. Size = (Instruction & ARM_SIMD_3_DIFF_SIZE_MASK) >>
  5826. ARM_SIMD_3_DIFF_SIZE_SHIFT;
  5827. //
  5828. // Sort out which instruction is actually being decoded and modify the
  5829. // common values as necessary.
  5830. //
  5831. BaseMnemonic = NULL;
  5832. switch (Instruction & ARM_SIMD_3_DIFF_OPERATION_MASK) {
  5833. case ARM_SIMD_VADDL_MASK:
  5834. BaseMnemonic = ARM_VADDL_MNEMONIC;
  5835. break;
  5836. case ARM_SIMD_VADDW_MASK:
  5837. BaseMnemonic = ARM_VADDW_MNEMONIC;
  5838. VectorNTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5839. break;
  5840. case ARM_SIMD_VSUBL_MASK:
  5841. BaseMnemonic = ARM_VSUBL_MNEMONIC;
  5842. break;
  5843. case ARM_SIMD_VSUBW_MASK:
  5844. BaseMnemonic = ARM_VSUBW_MNEMONIC;
  5845. VectorNTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5846. break;
  5847. case ARM_SIMD_VADDHN_MASK:
  5848. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5849. BaseMnemonic = ARM_VRADDHN_MNEMONIC;
  5850. } else {
  5851. BaseMnemonic = ARM_VADDHN_MNEMONIC;
  5852. }
  5853. //
  5854. // The size is double the normal encoding, so add 1 to the encoding.
  5855. //
  5856. Size += 1;
  5857. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5858. VectorDTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5859. VectorNTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5860. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5861. break;
  5862. case ARM_SIMD_VABAL_MASK:
  5863. BaseMnemonic = ARM_VABAL_MNEMONIC;
  5864. break;
  5865. case ARM_SIMD_VSUBHN_MASK:
  5866. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  5867. BaseMnemonic = ARM_VRSUBHN_MNEMONIC;
  5868. } else {
  5869. BaseMnemonic = ARM_VSUBHN_MNEMONIC;
  5870. }
  5871. //
  5872. // The size is double the normal encoding, so add 1 to the encoding.
  5873. //
  5874. Size += 1;
  5875. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  5876. VectorDTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5877. VectorNTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5878. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5879. break;
  5880. case ARM_SIMD_VABDL_MASK:
  5881. BaseMnemonic = ARM_VABDL_MNEMONIC;
  5882. break;
  5883. case ARM_SIMD_VMLAL_MASK:
  5884. BaseMnemonic = ARM_VMLAL_MNEMONIC;
  5885. break;
  5886. case ARM_SIMD_VMLSL_MASK:
  5887. BaseMnemonic = ARM_VMLSL_MNEMONIC;
  5888. break;
  5889. case ARM_SIMD_VQDMLAL_MASK:
  5890. BaseMnemonic = ARM_VQDMLAL_MNEMONIC;
  5891. break;
  5892. case ARM_SIMD_VQDMLSL_MASK:
  5893. BaseMnemonic = ARM_VQDMLSL_MNEMONIC;
  5894. break;
  5895. case ARM_SIMD_VMULL_INT_MASK:
  5896. BaseMnemonic = ARM_VMULL_MNEMONIC;
  5897. break;
  5898. case ARM_SIMD_VQDMULL_MASK:
  5899. BaseMnemonic = ARM_VQDMULL_MNEMONIC;
  5900. break;
  5901. case ARM_SIMD_VMULL_POLY_MASK:
  5902. BaseMnemonic = ARM_VMULL_MNEMONIC;
  5903. SizeTypeSuffix = ARM_SIMD_DATA_POLYNOMIAL;
  5904. break;
  5905. default:
  5906. break;
  5907. }
  5908. if (BaseMnemonic == NULL) {
  5909. DbgpArmDecodeUndefined(Context);
  5910. return;
  5911. }
  5912. //
  5913. // Get the size suffix now that it has been adjusted for the particular
  5914. // instruction being decoded.
  5915. //
  5916. switch (Size) {
  5917. case ARM_SIMD_3_DIFF_SIZE_8:
  5918. SizeValueSuffix = ARM_SIMD_DATA_SIZE_8;
  5919. break;
  5920. case ARM_SIMD_3_DIFF_SIZE_16:
  5921. SizeValueSuffix = ARM_SIMD_DATA_SIZE_16;
  5922. break;
  5923. case ARM_SIMD_3_DIFF_SIZE_32:
  5924. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  5925. break;
  5926. case ARM_SIMD_3_DIFF_SIZE_64:
  5927. SizeValueSuffix = ARM_SIMD_DATA_SIZE_64;
  5928. break;
  5929. //
  5930. // This should never hit as all possible values are accounted for.
  5931. //
  5932. default:
  5933. SizeValueSuffix = "";
  5934. break;
  5935. }
  5936. strcpy(Context->Mnemonic, BaseMnemonic);
  5937. sprintf(Context->PostConditionMnemonicSuffix,
  5938. "%s%s",
  5939. SizeTypeSuffix,
  5940. SizeValueSuffix);
  5941. sprintf(Context->Operand1, "%s%d", VectorDTypeString, VectorD);
  5942. sprintf(Context->Operand2, "%s%d", VectorNTypeString, VectorN);
  5943. sprintf(Context->Operand3, "%s%d", VectorMTypeString, VectorM);
  5944. return;
  5945. }
  5946. VOID
  5947. DbgpArmDecodeSimdTwoRegistersWithScalar (
  5948. PARM_DISASSEMBLY Context
  5949. )
  5950. /*++
  5951. Routine Description:
  5952. This routine decodes an SIMD data instruction with two registers and a
  5953. scalar.
  5954. Arguments:
  5955. Context - Supplies a pointer to the disassembly context.
  5956. Return Value:
  5957. None.
  5958. --*/
  5959. {
  5960. PSTR BaseMnemonic;
  5961. BOOL FloatValid;
  5962. ULONG Instruction;
  5963. BOOL QuadwordValid;
  5964. PSTR SizeTypeSuffix;
  5965. PSTR SizeValueSuffix;
  5966. ULONG VectorD;
  5967. PSTR VectorDTypeString;
  5968. ULONG VectorM;
  5969. ULONG VectorMIndex;
  5970. ULONG VectorN;
  5971. PSTR VectorNTypeString;
  5972. Instruction = Context->Instruction;
  5973. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  5974. VectorD = (Instruction & ARM_SIMD_DATA_PROCESSING_VD_MASK) >>
  5975. ARM_SIMD_DATA_PROCESSING_VD_SHIFT;
  5976. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VD_BIT) != 0) {
  5977. VectorD |= (1 << 4);
  5978. }
  5979. VectorNTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  5980. VectorN = (Instruction & ARM_SIMD_DATA_PROCESSING_VN_MASK) >>
  5981. ARM_SIMD_DATA_PROCESSING_VN_SHIFT;
  5982. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VN_BIT) != 0) {
  5983. VectorN |= (1 << 4);
  5984. }
  5985. //
  5986. // Vector M stores both the vector and the index. The division of the bits
  5987. // depend on the instruction's encoded size.
  5988. //
  5989. VectorM = (Instruction & ARM_SIMD_DATA_PROCESSING_VM_MASK) >>
  5990. ARM_SIMD_DATA_PROCESSING_VM_SHIFT;
  5991. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VM_BIT) != 0) {
  5992. VectorM |= (1 << 4);
  5993. }
  5994. switch (Instruction & ARM_SIMD_2_REGISTER_SCALAR_SIZE_MASK) {
  5995. case ARM_SIMD_2_REGISTER_SCALAR_SIZE_16:
  5996. VectorMIndex = (VectorM &
  5997. ARM_SIMD_2_REGISTER_SCALAR_SIZE_16_VM_INDEX_MASK) >>
  5998. ARM_SIMD_2_REGISTER_SCALAR_SIZE_16_VM_INDEX_SHIFT;
  5999. VectorM = (VectorM &
  6000. ARM_SIMD_2_REGISTER_SCALAR_SIZE_16_VM_VECTOR_MASK) >>
  6001. ARM_SIMD_2_REGISTER_SCALAR_SIZE_16_VM_VECTOR_SHIFT;
  6002. SizeValueSuffix = ARM_SIMD_DATA_SIZE_16;
  6003. break;
  6004. case ARM_SIMD_2_REGISTER_SCALAR_SIZE_32:
  6005. VectorMIndex = (VectorM &
  6006. ARM_SIMD_2_REGISTER_SCALAR_SIZE_32_VM_INDEX_MASK) >>
  6007. ARM_SIMD_2_REGISTER_SCALAR_SIZE_32_VM_INDEX_SHIFT;
  6008. VectorM = (VectorM &
  6009. ARM_SIMD_2_REGISTER_SCALAR_SIZE_32_VM_VECTOR_MASK) >>
  6010. ARM_SIMD_2_REGISTER_SCALAR_SIZE_32_VM_VECTOR_SHIFT;
  6011. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  6012. break;
  6013. default:
  6014. DbgpArmDecodeUndefined(Context);
  6015. return;
  6016. }
  6017. SizeTypeSuffix = ARM_SIMD_DATA_SIGNED;
  6018. if ((Instruction & ARM_SIMD_DATA_PROCESSING_UNSIGNED) != 0) {
  6019. SizeTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  6020. }
  6021. //
  6022. // Get the base mnemonic and finalize the type suffix.
  6023. //
  6024. FloatValid = FALSE;
  6025. QuadwordValid = FALSE;
  6026. BaseMnemonic = NULL;
  6027. switch (Instruction & ARM_SIMD_2_REGISTER_SCALAR_OPERATION_MASK) {
  6028. case ARM_SIMD_2_REGISTER_SCALAR_VMLA_MASK:
  6029. case (ARM_SIMD_2_REGISTER_SCALAR_VMLA_MASK |
  6030. ARM_SIMD_2_REGISTER_SCALAR_FLOAT):
  6031. FloatValid = TRUE;
  6032. QuadwordValid = TRUE;
  6033. BaseMnemonic = ARM_VMLA_MNEMONIC;
  6034. break;
  6035. case ARM_SIMD_2_REGISTER_SCALAR_VMLS_MASK:
  6036. case (ARM_SIMD_2_REGISTER_SCALAR_VMLS_MASK |
  6037. ARM_SIMD_2_REGISTER_SCALAR_FLOAT):
  6038. FloatValid = TRUE;
  6039. QuadwordValid = TRUE;
  6040. BaseMnemonic = ARM_VMLS_MNEMONIC;
  6041. break;
  6042. case ARM_SIMD_2_REGISTER_SCALAR_VMLAL_MASK:
  6043. BaseMnemonic = ARM_VMLAL_MNEMONIC;
  6044. break;
  6045. case ARM_SIMD_2_REGISTER_SCALAR_VMLSL_MASK:
  6046. BaseMnemonic = ARM_VMLSL_MNEMONIC;
  6047. break;
  6048. case ARM_SIMD_2_REGISTER_SCALAR_VQDMLAL_MASK:
  6049. BaseMnemonic = ARM_VQDMLAL_MNEMONIC;
  6050. break;
  6051. case ARM_SIMD_2_REGISTER_SCALAR_VQDMLSL_MASK:
  6052. BaseMnemonic = ARM_VQDMLSL_MNEMONIC;
  6053. break;
  6054. case ARM_SIMD_2_REGISTER_SCALAR_VMUL_MASK:
  6055. case (ARM_SIMD_2_REGISTER_SCALAR_VMUL_MASK |
  6056. ARM_SIMD_2_REGISTER_SCALAR_FLOAT):
  6057. FloatValid = TRUE;
  6058. QuadwordValid = TRUE;
  6059. BaseMnemonic = ARM_VMUL_MNEMONIC;
  6060. break;
  6061. case ARM_SIMD_2_REGISTER_SCALAR_VMULL_MASK:
  6062. BaseMnemonic = ARM_VMULL_MNEMONIC;
  6063. break;
  6064. case ARM_SIMD_2_REGISTER_SCALAR_VQDMULL_MASK:
  6065. BaseMnemonic = ARM_VQDMULL_MNEMONIC;
  6066. break;
  6067. case ARM_SIMD_2_REGISTER_SCALAR_VQDMULH_MASK:
  6068. QuadwordValid = TRUE;
  6069. BaseMnemonic = ARM_VQDMULH_MNEMONIC;
  6070. break;
  6071. case ARM_SIMD_2_REGISTER_SCALAR_VQRDMULH_MASK:
  6072. QuadwordValid = TRUE;
  6073. BaseMnemonic = ARM_VQRDMULH_MNEMONIC;
  6074. break;
  6075. default:
  6076. break;
  6077. }
  6078. if (BaseMnemonic == NULL) {
  6079. DbgpArmDecodeUndefined(Context);
  6080. return;
  6081. }
  6082. //
  6083. // Process the quadword and float bits if they are valid for the
  6084. // instruction being decoded.
  6085. //
  6086. if (QuadwordValid != FALSE) {
  6087. if ((Instruction & ARM_SIMD_2_REGISTER_SCALAR_QUADWORD) != 0) {
  6088. VectorNTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6089. } else {
  6090. VectorDTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  6091. }
  6092. }
  6093. if (FloatValid != FALSE) {
  6094. if ((Instruction & ARM_SIMD_2_REGISTER_SCALAR_FLOAT) != 0) {
  6095. SizeTypeSuffix = ARM_SIMD_DATA_FLOAT;
  6096. } else {
  6097. SizeTypeSuffix = ARM_SIMD_DATA_INTEGER;
  6098. }
  6099. }
  6100. strcpy(Context->Mnemonic, BaseMnemonic);
  6101. sprintf(Context->PostConditionMnemonicSuffix,
  6102. "%s%s",
  6103. SizeTypeSuffix,
  6104. SizeValueSuffix);
  6105. sprintf(Context->Operand1, "%s%d", VectorDTypeString, VectorD);
  6106. sprintf(Context->Operand2, "%s%d", VectorNTypeString, VectorN);
  6107. sprintf(Context->Operand3,
  6108. "%s%d[%d]",
  6109. ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR,
  6110. VectorM,
  6111. VectorMIndex);
  6112. return;
  6113. }
  6114. VOID
  6115. DbgpArmDecodeSimdTwoRegistersMiscellaneous (
  6116. PARM_DISASSEMBLY Context
  6117. )
  6118. /*++
  6119. Routine Description:
  6120. This routine decodes an SIMD data vector extract instruction.
  6121. Arguments:
  6122. Context - Supplies a pointer to the disassembly context.
  6123. Return Value:
  6124. None.
  6125. --*/
  6126. {
  6127. PSTR BaseMnemonic;
  6128. PSTR DestinationSizeSuffix;
  6129. PSTR DestinationTypeSuffix;
  6130. BOOL GetSizeSuffix;
  6131. ULONG Immediate;
  6132. ULONG Instruction;
  6133. BOOL PrintImmediate;
  6134. ULONG Size;
  6135. PSTR SourceSizeSuffix;
  6136. PSTR SourceTypeSuffix;
  6137. ULONG VectorD;
  6138. PSTR VectorDTypeString;
  6139. ULONG VectorM;
  6140. PSTR VectorMTypeString;
  6141. Instruction = Context->Instruction;
  6142. VectorDTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  6143. VectorD = (Instruction & ARM_SIMD_DATA_PROCESSING_VD_MASK) >>
  6144. ARM_SIMD_DATA_PROCESSING_VD_SHIFT;
  6145. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VD_BIT) != 0) {
  6146. VectorD |= (1 << 4);
  6147. }
  6148. VectorMTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  6149. VectorM = (Instruction & ARM_SIMD_DATA_PROCESSING_VM_MASK) >>
  6150. ARM_SIMD_DATA_PROCESSING_VM_SHIFT;
  6151. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VM_BIT) != 0) {
  6152. VectorM |= (1 << 4);
  6153. }
  6154. SourceSizeSuffix = "";
  6155. SourceTypeSuffix = "";
  6156. DestinationTypeSuffix = ARM_SIMD_DATA_DEFAULT;
  6157. DestinationSizeSuffix = "";
  6158. GetSizeSuffix = TRUE;
  6159. Size = (Instruction & ARM_SIMD_2_REGISTER_MISC_SIZE_MASK) >>
  6160. ARM_SIMD_2_REGISTER_MISC_SIZE_SHIFT;
  6161. //
  6162. // Some instructions include an immediate value. Default to not print it.
  6163. //
  6164. Immediate = 0;
  6165. PrintImmediate = FALSE;
  6166. //
  6167. // Determine the base mnemonic and perform and instruction specific
  6168. // modifications to the vector and size information.
  6169. //
  6170. BaseMnemonic = NULL;
  6171. switch (Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_MASK) {
  6172. case ARM_SIMD_2_REGISTER_MISC_TYPE_0:
  6173. switch (Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_0_OP_MASK) {
  6174. case ARM_SIMD_2_REGISTER_MISC_TYPE_0_VREV64_MASK:
  6175. BaseMnemonic = ARM_VREV64_MNEMONIC;
  6176. break;
  6177. case ARM_SIMD_2_REGISTER_MISC_TYPE_0_VREV32_MASK:
  6178. BaseMnemonic = ARM_VREV32_MNEMONIC;
  6179. break;
  6180. case ARM_SIMD_2_REGISTER_MISC_TYPE_0_VREV16_MASK:
  6181. BaseMnemonic = ARM_VREV16_MNEMONIC;
  6182. break;
  6183. case ARM_SIMD_2_REGISTER_MISC_TYPE_0_VPADDL_MASK:
  6184. case (ARM_SIMD_2_REGISTER_MISC_TYPE_0_VPADDL_MASK |
  6185. ARM_SIMD_2_REGISTER_MISC_TYPE_0_UNSIGNED):
  6186. if ((Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_0_UNSIGNED) != 0) {
  6187. DestinationTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  6188. } else {
  6189. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  6190. }
  6191. BaseMnemonic = ARM_VPADDL_MNEMONIC;
  6192. break;
  6193. case ARM_SIMD_2_REGISTER_MISC_TYPE_0_VCLS_MASK:
  6194. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  6195. BaseMnemonic = ARM_VCLS_MNEMONIC;
  6196. break;
  6197. case ARM_SIMD_2_REGISTER_MISC_TYPE_0_VCLZ_MASK:
  6198. DestinationTypeSuffix = ARM_SIMD_DATA_INTEGER;
  6199. BaseMnemonic = ARM_VCLZ_MNEMONIC;
  6200. break;
  6201. case ARM_SIMD_2_REGISTER_MISC_TYPE_0_VCNT_MASK:
  6202. BaseMnemonic = ARM_VCNT_MNEMONIC;
  6203. break;
  6204. case ARM_SIMD_2_REGISTER_MISC_TYPE_0_VMVN_MASK:
  6205. GetSizeSuffix = FALSE;
  6206. DestinationTypeSuffix = "";
  6207. BaseMnemonic = ARM_VMVN_MNEMONIC;
  6208. break;
  6209. case ARM_SIMD_2_REGISTER_MISC_TYPE_0_VPADAL_MASK:
  6210. case (ARM_SIMD_2_REGISTER_MISC_TYPE_0_VPADAL_MASK |
  6211. ARM_SIMD_2_REGISTER_MISC_TYPE_0_UNSIGNED):
  6212. if ((Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_0_UNSIGNED) != 0) {
  6213. DestinationTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  6214. } else {
  6215. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  6216. }
  6217. BaseMnemonic = ARM_VPADAL_MNEMONIC;
  6218. break;
  6219. case ARM_SIMD_2_REGISTER_MISC_TYPE_0_VQABS_MASK:
  6220. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  6221. BaseMnemonic = ARM_VQABS_MNEMONIC;
  6222. break;
  6223. case ARM_SIMD_2_REGISTER_MISC_TYPE_0_VQNEG_MASK:
  6224. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  6225. BaseMnemonic = ARM_VQNEG_MNEMONIC;
  6226. break;
  6227. default:
  6228. break;
  6229. }
  6230. //
  6231. // All of the type 0 instructions depend on the quadword bit.
  6232. //
  6233. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  6234. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6235. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6236. }
  6237. break;
  6238. case ARM_SIMD_2_REGISTER_MISC_TYPE_1:
  6239. //
  6240. // The majority of these instructions have an immediate 0 value and
  6241. // default to being signed.
  6242. //
  6243. PrintImmediate = TRUE;
  6244. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  6245. switch (Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_1_OP_MASK) {
  6246. case ARM_SIMD_2_REGISTER_MISC_TYPE_1_VCGT_MASK:
  6247. BaseMnemonic = ARM_VCGT_MNEMONIC;
  6248. break;
  6249. case ARM_SIMD_2_REGISTER_MISC_TYPE_1_VCGE_MASK:
  6250. BaseMnemonic = ARM_VCGE_MNEMONIC;
  6251. break;
  6252. case ARM_SIMD_2_REGISTER_MISC_TYPE_1_VCEQ_MASK:
  6253. DestinationTypeSuffix = ARM_SIMD_DATA_INTEGER;
  6254. BaseMnemonic = ARM_VCEQ_MNEMONIC;
  6255. break;
  6256. case ARM_SIMD_2_REGISTER_MISC_TYPE_1_VCLE_MASK:
  6257. BaseMnemonic = ARM_VCLE_MNEMONIC;
  6258. break;
  6259. case ARM_SIMD_2_REGISTER_MISC_TYPE_1_VCLT_MASK:
  6260. BaseMnemonic = ARM_VCLT_MNEMONIC;
  6261. break;
  6262. case ARM_SIMD_2_REGISTER_MISC_TYPE_1_VABS_MASK:
  6263. PrintImmediate = FALSE;
  6264. BaseMnemonic = ARM_VABS_MNEMONIC;
  6265. break;
  6266. case ARM_SIMD_2_REGISTER_MISC_TYPE_1_VNEG_MASK:
  6267. PrintImmediate = FALSE;
  6268. BaseMnemonic = ARM_VNEG_MNEMONIC;
  6269. break;
  6270. default:
  6271. break;
  6272. }
  6273. //
  6274. // All of the type 1 instructions depend on the type specific float bit.
  6275. //
  6276. if ((Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_1_FLOAT) != 0) {
  6277. DestinationTypeSuffix = ARM_SIMD_DATA_FLOAT;
  6278. }
  6279. //
  6280. // All of the type 1 instructions depend on the quadword bit.
  6281. //
  6282. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  6283. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6284. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6285. }
  6286. break;
  6287. case ARM_SIMD_2_REGISTER_MISC_TYPE_2:
  6288. switch (Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_2_OP_MASK) {
  6289. case ARM_SIMD_2_REGISTER_MISC_TYPE_2_VSWP_MASK:
  6290. GetSizeSuffix = FALSE;
  6291. DestinationTypeSuffix = "";
  6292. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  6293. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6294. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6295. }
  6296. BaseMnemonic = ARM_VSWP_MNEMONIC;
  6297. break;
  6298. case ARM_SIMD_2_REGISTER_MISC_TYPE_2_VTRN_MASK:
  6299. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  6300. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6301. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6302. }
  6303. BaseMnemonic = ARM_VTRN_MNEMONIC;
  6304. break;
  6305. case ARM_SIMD_2_REGISTER_MISC_TYPE_2_VUZP_MASK:
  6306. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  6307. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6308. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6309. }
  6310. BaseMnemonic = ARM_VUZP_MNEMONIC;
  6311. break;
  6312. case ARM_SIMD_2_REGISTER_MISC_TYPE_2_VZIP_MASK:
  6313. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  6314. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6315. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6316. }
  6317. BaseMnemonic = ARM_VZIP_MNEMONIC;
  6318. break;
  6319. case ARM_SIMD_2_REGISTER_MISC_TYPE_2_VMOVN_MASK:
  6320. if ((Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_2_UNSIGNED) != 0) {
  6321. BaseMnemonic = ARM_VQMOVUN_MNEMONIC;
  6322. } else {
  6323. BaseMnemonic = ARM_VMOVN_MNEMONIC;
  6324. }
  6325. DestinationTypeSuffix = ARM_SIMD_DATA_INTEGER;
  6326. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6327. //
  6328. // The size encodings are doubled, so add 1 to get the correct
  6329. // destination size suffix below.
  6330. //
  6331. Size += 1;
  6332. break;
  6333. case ARM_SIMD_2_REGISTER_MISC_TYPE_2_VQMOVN_MASK:
  6334. if ((Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_2_UNSIGNED) != 0) {
  6335. DestinationTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  6336. } else {
  6337. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  6338. }
  6339. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6340. //
  6341. // The size encodings are doubled, so add 1 to get the correct
  6342. // destination size suffix below.
  6343. //
  6344. Size += 1;
  6345. BaseMnemonic = ARM_VQMOVN_MNEMONIC;
  6346. break;
  6347. case ARM_SIMD_2_REGISTER_MISC_TYPE_2_VSHLL_MASK:
  6348. if ((Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_2_UNSIGNED) != 0) {
  6349. break;
  6350. }
  6351. Immediate = Size;
  6352. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6353. BaseMnemonic = ARM_VSHLL_MNEMONIC;
  6354. DestinationTypeSuffix = ARM_SIMD_DATA_INTEGER;
  6355. PrintImmediate = TRUE;
  6356. break;
  6357. case ARM_SIMD_2_REGISTER_MISC_TYPE_2_VCVT_HALF_TO_SINGLE_MASK:
  6358. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6359. DestinationTypeSuffix = ARM_SIMD_DATA_FLOAT;
  6360. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  6361. SourceTypeSuffix = ARM_SIMD_DATA_FLOAT;
  6362. SourceSizeSuffix = ARM_SIMD_DATA_SIZE_16;
  6363. GetSizeSuffix = FALSE;
  6364. BaseMnemonic = ARM_VCVT_MNEMONIC;
  6365. break;
  6366. case ARM_SIMD_2_REGISTER_MISC_TYPE_2_VCVT_SINGLE_TO_HALF_MASK:
  6367. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6368. DestinationTypeSuffix = ARM_SIMD_DATA_FLOAT;
  6369. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_16;
  6370. SourceTypeSuffix = ARM_SIMD_DATA_FLOAT;
  6371. SourceSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  6372. GetSizeSuffix = FALSE;
  6373. BaseMnemonic = ARM_VCVT_MNEMONIC;
  6374. break;
  6375. default:
  6376. break;
  6377. }
  6378. break;
  6379. case ARM_SIMD_2_REGISTER_MISC_TYPE_3:
  6380. switch (Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_3_OP_MASK) {
  6381. case ARM_SIMD_2_REGISTER_MISC_TYPE_3_VRECPE_MASK:
  6382. if ((Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_3_FLOAT) != 0) {
  6383. DestinationTypeSuffix = ARM_SIMD_DATA_FLOAT;
  6384. } else {
  6385. DestinationTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  6386. }
  6387. BaseMnemonic = ARM_VRECPE_MNEMONIC;
  6388. break;
  6389. case ARM_SIMD_2_REGISTER_MISC_TYPE_3_VRSQRTE_MASK:
  6390. if ((Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_3_FLOAT) != 0) {
  6391. DestinationTypeSuffix = ARM_SIMD_DATA_FLOAT;
  6392. } else {
  6393. DestinationTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  6394. }
  6395. BaseMnemonic = ARM_VRSQRTE_MNEMONIC;
  6396. break;
  6397. case ARM_SIMD_2_REGISTER_MISC_TYPE_3_VCVT_TO_INTEGER_MASK:
  6398. if ((Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_3_UNSIGNED) != 0) {
  6399. DestinationTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  6400. } else {
  6401. DestinationTypeSuffix = ARM_SIMD_DATA_SIGNED;
  6402. }
  6403. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  6404. SourceTypeSuffix = ARM_SIMD_DATA_FLOAT;
  6405. SourceSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  6406. GetSizeSuffix = FALSE;
  6407. BaseMnemonic = ARM_VCVT_MNEMONIC;
  6408. break;
  6409. case ARM_SIMD_2_REGISTER_MISC_TYPE_3_VCVT_FROM_INTEGER_MASK:
  6410. if ((Instruction & ARM_SIMD_2_REGISTER_MISC_TYPE_3_UNSIGNED) != 0) {
  6411. SourceTypeSuffix = ARM_SIMD_DATA_UNSIGNED;
  6412. } else {
  6413. SourceTypeSuffix = ARM_SIMD_DATA_SIGNED;
  6414. }
  6415. SourceSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  6416. DestinationTypeSuffix = ARM_SIMD_DATA_FLOAT;
  6417. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  6418. GetSizeSuffix = FALSE;
  6419. BaseMnemonic = ARM_VCVT_MNEMONIC;
  6420. break;
  6421. default:
  6422. break;
  6423. }
  6424. //
  6425. // All of the type 3 instructions depend on the quadword bit.
  6426. //
  6427. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  6428. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6429. VectorMTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6430. }
  6431. break;
  6432. default:
  6433. break;
  6434. }
  6435. if (BaseMnemonic == NULL) {
  6436. DbgpArmDecodeUndefined(Context);
  6437. return;
  6438. }
  6439. if (GetSizeSuffix != FALSE) {
  6440. switch (Size) {
  6441. case ARM_SIMD_2_REGISTER_MISC_SIZE_8:
  6442. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_8;
  6443. break;
  6444. case ARM_SIMD_2_REGISTER_MISC_SIZE_16:
  6445. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_16;
  6446. break;
  6447. case ARM_SIMD_2_REGISTER_MISC_SIZE_32:
  6448. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_32;
  6449. break;
  6450. case ARM_SIMD_2_REGISTER_MISC_SIZE_64:
  6451. DestinationSizeSuffix = ARM_SIMD_DATA_SIZE_64;
  6452. break;
  6453. default:
  6454. return;
  6455. }
  6456. }
  6457. strcpy(Context->Mnemonic, BaseMnemonic);
  6458. sprintf(Context->PostConditionMnemonicSuffix,
  6459. "%s%s%s%s",
  6460. DestinationTypeSuffix,
  6461. DestinationSizeSuffix,
  6462. SourceTypeSuffix,
  6463. SourceSizeSuffix);
  6464. sprintf(Context->Operand1, "%s%d", VectorDTypeString, VectorD);
  6465. sprintf(Context->Operand2, "%s%d", VectorMTypeString, VectorM);
  6466. if (PrintImmediate != FALSE) {
  6467. sprintf(Context->Operand3, "#%d ; 0x%x", Immediate, Immediate);
  6468. }
  6469. return;
  6470. }
  6471. VOID
  6472. DbgpArmDecodeSimdVectorExtract (
  6473. PARM_DISASSEMBLY Context
  6474. )
  6475. /*++
  6476. Routine Description:
  6477. This routine decodes an SIMD data vector extract instruction.
  6478. Arguments:
  6479. Context - Supplies a pointer to the disassembly context.
  6480. Return Value:
  6481. None.
  6482. --*/
  6483. {
  6484. ULONG Immediate;
  6485. ULONG Instruction;
  6486. ULONG VectorD;
  6487. ULONG VectorM;
  6488. ULONG VectorN;
  6489. PSTR VectorTypeString;
  6490. Instruction = Context->Instruction;
  6491. VectorD = (Instruction & ARM_SIMD_DATA_PROCESSING_VD_MASK) >>
  6492. ARM_SIMD_DATA_PROCESSING_VD_SHIFT;
  6493. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VD_BIT) != 0) {
  6494. VectorD |= (1 << 4);
  6495. }
  6496. VectorM = (Instruction & ARM_SIMD_DATA_PROCESSING_VM_MASK) >>
  6497. ARM_SIMD_DATA_PROCESSING_VM_SHIFT;
  6498. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VM_BIT) != 0) {
  6499. VectorM |= (1 << 4);
  6500. }
  6501. VectorN = (Instruction & ARM_SIMD_DATA_PROCESSING_VN_MASK) >>
  6502. ARM_SIMD_DATA_PROCESSING_VN_SHIFT;
  6503. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VN_BIT) != 0) {
  6504. VectorN |= (1 << 4);
  6505. }
  6506. VectorTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  6507. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  6508. VectorTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6509. }
  6510. Immediate = (Instruction & ARM_SIMD_VEXT_IMMEDIATE4_MASK) >>
  6511. ARM_SIMD_VEXT_IMMEDIATE4_SHIFT;
  6512. strcpy(Context->Mnemonic, ARM_VEXT_MNEMONIC);
  6513. sprintf(Context->PostConditionMnemonicSuffix,
  6514. "%s%s",
  6515. ARM_SIMD_DATA_DEFAULT,
  6516. ARM_SIMD_DATA_SIZE_8);
  6517. sprintf(Context->Operand1, "%s%d", VectorTypeString, VectorD);
  6518. sprintf(Context->Operand2, "%s%d", VectorTypeString, VectorN);
  6519. sprintf(Context->Operand3, "%s%d", VectorTypeString, VectorM);
  6520. sprintf(Context->Operand4, "#%d ; 0x%x", Immediate, Immediate);
  6521. return;
  6522. }
  6523. VOID
  6524. DbgpArmDecodeSimdVectorTableLookup (
  6525. PARM_DISASSEMBLY Context
  6526. )
  6527. /*++
  6528. Routine Description:
  6529. This routine decodes an SIMD vector table lookup instruction.
  6530. Arguments:
  6531. Context - Supplies a pointer to the disassembly context.
  6532. Return Value:
  6533. None.
  6534. --*/
  6535. {
  6536. PSTR BaseMnemonic;
  6537. ULONG Instruction;
  6538. ULONG VectorCount;
  6539. ULONG VectorD;
  6540. ULONG VectorM;
  6541. ULONG VectorN;
  6542. Instruction = Context->Instruction;
  6543. VectorD = (Instruction & ARM_SIMD_DATA_PROCESSING_VD_MASK) >>
  6544. ARM_SIMD_DATA_PROCESSING_VD_SHIFT;
  6545. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VD_BIT) != 0) {
  6546. VectorD |= (1 << 4);
  6547. }
  6548. VectorM = (Instruction & ARM_SIMD_DATA_PROCESSING_VM_MASK) >>
  6549. ARM_SIMD_DATA_PROCESSING_VM_SHIFT;
  6550. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VM_BIT) != 0) {
  6551. VectorM |= (1 << 4);
  6552. }
  6553. VectorN = (Instruction & ARM_SIMD_DATA_PROCESSING_VN_MASK) >>
  6554. ARM_SIMD_DATA_PROCESSING_VN_SHIFT;
  6555. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VN_BIT) != 0) {
  6556. VectorN |= (1 << 4);
  6557. }
  6558. VectorCount = (Instruction & ARM_SIMD_VTB_LENGTH_MASK) >>
  6559. ARM_SIMD_VTB_LENGTH_SHIFT;
  6560. VectorCount += 1;
  6561. if ((Instruction & ARM_SIMD_VTB_EXTENSION) != 0) {
  6562. BaseMnemonic = ARM_VTBX_MNEMONIC;
  6563. } else {
  6564. BaseMnemonic = ARM_VTBL_MNEMONIC;
  6565. }
  6566. strcpy(Context->Mnemonic, BaseMnemonic);
  6567. sprintf(Context->PostConditionMnemonicSuffix,
  6568. "%s%s",
  6569. ARM_SIMD_DATA_DEFAULT,
  6570. ARM_SIMD_DATA_SIZE_8);
  6571. sprintf(Context->Operand1,
  6572. "%s%d",
  6573. ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR,
  6574. VectorD);
  6575. DbgpArmPrintVectorList(Context->Operand2,
  6576. sizeof(Context->Operand2),
  6577. VectorN,
  6578. VectorCount,
  6579. 1,
  6580. ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR,
  6581. 0,
  6582. 0);
  6583. sprintf(Context->Operand3,
  6584. "%s%d",
  6585. ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR,
  6586. VectorM);
  6587. return;
  6588. }
  6589. VOID
  6590. DbgpArmDecodeSimdVectorDuplicate (
  6591. PARM_DISASSEMBLY Context
  6592. )
  6593. /*++
  6594. Routine Description:
  6595. This routine decodes an SIMD data vector duplicate instruction.
  6596. Arguments:
  6597. Context - Supplies a pointer to the disassembly context.
  6598. Return Value:
  6599. None.
  6600. --*/
  6601. {
  6602. ULONG Instruction;
  6603. PSTR SizeTypeSuffix;
  6604. PSTR SizeValueSuffix;
  6605. ULONG VectorD;
  6606. PSTR VectorDTypeString;
  6607. ULONG VectorM;
  6608. ULONG VectorMIndex;
  6609. Instruction = Context->Instruction;
  6610. SizeTypeSuffix = ARM_SIMD_DATA_DEFAULT;
  6611. SizeValueSuffix = "";
  6612. VectorMIndex = 0;
  6613. VectorD = (Instruction & ARM_SIMD_DATA_PROCESSING_VD_MASK) >>
  6614. ARM_SIMD_DATA_PROCESSING_VD_SHIFT;
  6615. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VD_BIT) != 0) {
  6616. VectorD |= (1 << 4);
  6617. }
  6618. VectorM = (Instruction & ARM_SIMD_DATA_PROCESSING_VM_MASK) >>
  6619. ARM_SIMD_DATA_PROCESSING_VM_SHIFT;
  6620. if ((Instruction & ARM_SIMD_DATA_PROCESSING_VM_BIT) != 0) {
  6621. VectorM |= (1 << 4);
  6622. }
  6623. if ((Instruction & ARM_SIMD_VDUP_SIZE_8_MASK) ==
  6624. ARM_SIMD_VDUP_SIZE_8_VALUE) {
  6625. SizeValueSuffix = ARM_SIMD_DATA_SIZE_8;
  6626. VectorMIndex = (Instruction & ARM_SIMD_VDUP_SIZE_8_INDEX_MASK) >>
  6627. ARM_SIMD_VDUP_SIZE_8_INDEX_SHIFT;
  6628. } else if ((Instruction & ARM_SIMD_VDUP_SIZE_16_MASK) ==
  6629. ARM_SIMD_VDUP_SIZE_16_VALUE) {
  6630. SizeValueSuffix = ARM_SIMD_DATA_SIZE_16;
  6631. VectorMIndex = (Instruction & ARM_SIMD_VDUP_SIZE_16_INDEX_MASK) >>
  6632. ARM_SIMD_VDUP_SIZE_16_INDEX_SHIFT;
  6633. } else if ((Instruction & ARM_SIMD_VDUP_SIZE_32_MASK) ==
  6634. ARM_SIMD_VDUP_SIZE_32_VALUE) {
  6635. SizeValueSuffix = ARM_SIMD_DATA_SIZE_32;
  6636. VectorMIndex = (Instruction & ARM_SIMD_VDUP_SIZE_32_INDEX_MASK) >>
  6637. ARM_SIMD_VDUP_SIZE_32_INDEX_SHIFT;
  6638. } else {
  6639. SizeTypeSuffix = "";
  6640. }
  6641. VectorDTypeString = ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR;
  6642. if ((Instruction & ARM_SIMD_DATA_PROCESSING_QUADWORD) != 0) {
  6643. VectorDTypeString = ARM_FLOATING_POINT_QUADWORD_VECTOR;
  6644. }
  6645. strcpy(Context->Mnemonic, ARM_VDUP_MNEMONIC);
  6646. sprintf(Context->PostConditionMnemonicSuffix,
  6647. "%s%s",
  6648. SizeTypeSuffix,
  6649. SizeValueSuffix);
  6650. sprintf(Context->Operand1, "%s%d", VectorDTypeString, VectorD);
  6651. sprintf(Context->Operand2,
  6652. "%s%d[%d]",
  6653. ARM_FLOATING_POINT_DOUBLE_PRECISION_VECTOR,
  6654. VectorM,
  6655. VectorMIndex);
  6656. return;
  6657. }
  6658. PSTR
  6659. DbgpArmGetLoadStoreTypeString (
  6660. ULONG Instruction
  6661. )
  6662. /*++
  6663. Routine Description:
  6664. This routine returns the push/pop type string.
  6665. Arguments:
  6666. Instruction - Supplies the instruction. The push/pop type is always in the
  6667. same bits.
  6668. Return Value:
  6669. Returns a static string for the push/pop type.
  6670. --*/
  6671. {
  6672. switch (Instruction & ARM_LOAD_STORE_TYPE_MASK) {
  6673. case ARM_LOAD_STORE_INCREMENT_AFTER:
  6674. return ARM_INCREMENT_AFTER_SUFFIX;
  6675. case ARM_LOAD_STORE_INCREMENT_BEFORE:
  6676. return ARM_INCREMENT_BEFORE_SUFFIX;
  6677. case ARM_LOAD_STORE_DECREMENT_AFTER:
  6678. return ARM_DECREMENT_AFTER_SUFFIX;
  6679. case ARM_LOAD_STORE_DECREMENT_BEFORE:
  6680. return ARM_DECREMENT_BEFORE_SUFFIX;
  6681. default:
  6682. break;
  6683. }
  6684. return "";
  6685. }
  6686. PSTR
  6687. DbgpArmGetBankedRegisterString (
  6688. ULONG Instruction
  6689. )
  6690. /*++
  6691. Routine Description:
  6692. This routine returns the banked register/mode string, encoded in
  6693. instructions as the m1 and R fields.
  6694. Arguments:
  6695. Instruction - Supplies the instruction.
  6696. Return Value:
  6697. Returns a static string for the encoding mode.
  6698. --*/
  6699. {
  6700. ULONG Index;
  6701. Index = (Instruction & ARM_BANKED_MODE_MASK) >> ARM_BANKED_MODE_SHIFT;
  6702. if ((Instruction & ARM_BANKED_MODE_R_BIT) != 0) {
  6703. Index |= 0x20;
  6704. }
  6705. return DbgArmBankedRegisters[Index];
  6706. }
  6707. VOID
  6708. DbgpArmPrintStatusRegister (
  6709. PSTR Operand,
  6710. ULONG Instruction
  6711. )
  6712. /*++
  6713. Routine Description:
  6714. This routine prints the status register and flags for a given instruction.
  6715. Arguments:
  6716. Operand - Supplies the buffer where the completed string will be returned.
  6717. Instruction - Supplies the instruction.
  6718. Return Value:
  6719. None.
  6720. --*/
  6721. {
  6722. ULONG ExtraFlagCount;
  6723. CHAR ExtraFlags[5];
  6724. PSTR Register;
  6725. memset(ExtraFlags, 0, sizeof(ExtraFlags));
  6726. ExtraFlagCount = 0;
  6727. if ((Instruction & ARM_MOVE_STATUS_SPSR) != 0) {
  6728. Register = ARM_SPSR_STRING;
  6729. } else {
  6730. Register = ARM_CPSR_STRING;
  6731. }
  6732. if ((Instruction & ARM_MSR_MASK_C) != 0) {
  6733. ExtraFlags[ExtraFlagCount] = ARM_MSR_MASK_C_FLAG;
  6734. ExtraFlagCount += 1;
  6735. }
  6736. if ((Instruction & ARM_MSR_MASK_X) != 0) {
  6737. ExtraFlags[ExtraFlagCount] = ARM_MSR_MASK_X_FLAG;
  6738. ExtraFlagCount += 1;
  6739. }
  6740. if ((Instruction & ARM_MSR_MASK_S) != 0) {
  6741. ExtraFlags[ExtraFlagCount] = ARM_MSR_MASK_S_FLAG;
  6742. ExtraFlagCount += 1;
  6743. }
  6744. if ((Instruction & ARM_MSR_MASK_F) != 0) {
  6745. ExtraFlags[ExtraFlagCount] = ARM_MSR_MASK_F_FLAG;
  6746. ExtraFlagCount += 1;
  6747. }
  6748. sprintf(Operand, "%s_%s", Register, ExtraFlags);
  6749. return;
  6750. }
  6751. VOID
  6752. DbgpArmPrintVectorList (
  6753. PSTR Destination,
  6754. ULONG DestinationSize,
  6755. ULONG VectorStart,
  6756. ULONG VectorCount,
  6757. ULONG VectorIncrement,
  6758. PSTR VectorTypeString,
  6759. ULONG VectorIndex,
  6760. ULONG Flags
  6761. )
  6762. /*++
  6763. Routine Description:
  6764. This routine converts a count of vectors starting at a given vector into
  6765. a string.
  6766. Arguments:
  6767. Destination - Supplies a pointer to the destination string.
  6768. DestinationSize - Supplies the size of the destination string.
  6769. VectorStart - Supplies the starting vector.
  6770. VectorCount - Supplies the total number of vectors to convert.
  6771. VectorIncrement - Supplies the interval between vectors.
  6772. VectorTypeString - Supplies the character to use to describe each vector.
  6773. VectorIndex - Supplies the option index into each vector.
  6774. Flags - Supplies a bitmask of flags. See DBG_ARM_VECTOR_LIST_FLAG_* for
  6775. definitions.
  6776. Return Value:
  6777. None.
  6778. --*/
  6779. {
  6780. ULONG CurrentVector;
  6781. PSTR Separator;
  6782. INT Size;
  6783. CHAR VectorString[16];
  6784. if (DestinationSize > 1) {
  6785. strcpy(Destination, "{");
  6786. Size = strlen(Destination);
  6787. Destination += Size;
  6788. DestinationSize -= Size;
  6789. }
  6790. Separator = "";
  6791. for (CurrentVector = VectorStart;
  6792. CurrentVector < VectorStart + VectorCount;
  6793. CurrentVector += VectorIncrement) {
  6794. if ((Flags & DBG_ARM_VECTOR_LIST_FLAG_INDEX) != 0) {
  6795. if ((Flags & DBG_ARM_VECTOR_LIST_FLAG_ALL_LANES) != 0) {
  6796. snprintf(VectorString,
  6797. sizeof(VectorString),
  6798. "%s%s%d[]",
  6799. Separator,
  6800. VectorTypeString,
  6801. CurrentVector);
  6802. } else {
  6803. snprintf(VectorString,
  6804. sizeof(VectorString),
  6805. "%s%s%d[%d]",
  6806. Separator,
  6807. VectorTypeString,
  6808. CurrentVector,
  6809. VectorIndex);
  6810. }
  6811. } else {
  6812. snprintf(VectorString,
  6813. sizeof(VectorString),
  6814. "%s%s%d",
  6815. Separator,
  6816. VectorTypeString,
  6817. CurrentVector);
  6818. }
  6819. Size = strlen(VectorString);
  6820. if (Size < DestinationSize) {
  6821. strcpy(Destination, VectorString);
  6822. Destination += Size;
  6823. DestinationSize -= Size;
  6824. }
  6825. Separator = ", ";
  6826. }
  6827. if (DestinationSize > 1) {
  6828. strcpy(Destination, "}");
  6829. }
  6830. return;
  6831. }
  6832. VOID
  6833. DbgpArmDecodeImmediateShift (
  6834. PSTR Destination,
  6835. ULONG DestinationSize,
  6836. ULONG Register,
  6837. ULONG Type,
  6838. ULONG Immediate
  6839. )
  6840. /*++
  6841. Routine Description:
  6842. This routine converts a register, type and immediate value into a string
  6843. representing the register shifted by the immediate value.
  6844. Arguments:
  6845. Destination - Supplies a pointer to the destination string.
  6846. DestinationSize - Supplies the size of the destination string.
  6847. Register - Supplies the register that is to be shifted.
  6848. Type - Supplies the type of shift. See ARM_SHIFT_* for definitions.
  6849. Immediate - Supplies the immediate value by which to shift.
  6850. Return Value:
  6851. None.
  6852. --*/
  6853. {
  6854. PSTR RegisterName;
  6855. PSTR ShiftType;
  6856. ShiftType = NULL;
  6857. switch (Type) {
  6858. case ARM_SHIFT_LSL:
  6859. if (Immediate != 0) {
  6860. ShiftType = ARM_LSL_MNEMONIC;
  6861. }
  6862. break;
  6863. case ARM_SHIFT_LSR:
  6864. if (Immediate == 0) {
  6865. Immediate = 32;
  6866. }
  6867. ShiftType = ARM_LSR_MNEMONIC;
  6868. break;
  6869. case ARM_SHIFT_ASR:
  6870. if (Immediate == 0) {
  6871. Immediate = 32;
  6872. }
  6873. ShiftType = ARM_ASR_MNEMONIC;
  6874. break;
  6875. case ARM_SHIFT_ROR:
  6876. if (Immediate == 0) {
  6877. ShiftType = ARM_RRX_MNEMONIC;
  6878. } else {
  6879. ShiftType = ARM_ROR_MNEMONIC;
  6880. }
  6881. break;
  6882. //
  6883. // This case should never hit since all 4 bit combinations are
  6884. // covered.
  6885. //
  6886. default:
  6887. break;
  6888. }
  6889. RegisterName = DbgArmRegisterNames[Register];
  6890. if (Immediate != 0) {
  6891. sprintf(Destination, "%s, %s #%d", RegisterName, ShiftType, Immediate);
  6892. } else if (ShiftType != NULL) {
  6893. sprintf(Destination, "%s, %s", RegisterName, ShiftType);
  6894. } else {
  6895. sprintf(Destination, "%s", RegisterName);
  6896. }
  6897. return;
  6898. }