armdis.c 221 KB

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