armemu.cpp 239 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600
  1. /* armemu.c -- Main instruction emulation: ARM7 Instruction Emulator.
  2. Copyright (C) 1994 Advanced RISC Machines Ltd.
  3. Modifications to add arch. v4 support by <jsmith@cygnus.com>.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  15. //#include <util.h> // DEBUG()
  16. #include "core/arm/skyeye_common/arm_regformat.h"
  17. #include "core/arm/skyeye_common/armdefs.h"
  18. #include "core/arm/skyeye_common/armemu.h"
  19. #include "core/hle/hle.h"
  20. //#include "svc.h"
  21. //ichfly
  22. //#define callstacker 1
  23. //#include "skyeye_callback.h"
  24. //#include "skyeye_bus.h"
  25. //#include "sim_control.h"
  26. //#include "skyeye_pref.h"
  27. //#include "skyeye.h"
  28. //#include "skyeye2gdb.h"
  29. //#include "code_cov.h"
  30. //#include "iwmmxt.h"
  31. //chy 2003-07-11: for debug instrs
  32. //extern int skyeye_instr_debug;
  33. extern FILE *skyeye_logfd;
  34. static ARMword GetDPRegRHS (ARMul_State *, ARMword);
  35. static ARMword GetDPSRegRHS (ARMul_State *, ARMword);
  36. static void WriteR15 (ARMul_State *, ARMword);
  37. static void WriteSR15 (ARMul_State *, ARMword);
  38. static void WriteR15Branch (ARMul_State *, ARMword);
  39. static ARMword GetLSRegRHS (ARMul_State *, ARMword);
  40. static ARMword GetLS7RHS (ARMul_State *, ARMword);
  41. static unsigned LoadWord (ARMul_State *, ARMword, ARMword);
  42. static unsigned LoadHalfWord (ARMul_State *, ARMword, ARMword, int);
  43. static unsigned LoadByte (ARMul_State *, ARMword, ARMword, int);
  44. static unsigned StoreWord (ARMul_State *, ARMword, ARMword);
  45. static unsigned StoreHalfWord (ARMul_State *, ARMword, ARMword);
  46. static unsigned StoreByte (ARMul_State *, ARMword, ARMword);
  47. static void LoadMult (ARMul_State *, ARMword, ARMword, ARMword);
  48. static void StoreMult (ARMul_State *, ARMword, ARMword, ARMword);
  49. static void LoadSMult (ARMul_State *, ARMword, ARMword, ARMword);
  50. static void StoreSMult (ARMul_State *, ARMword, ARMword, ARMword);
  51. static unsigned Multiply64 (ARMul_State *, ARMword, int, int);
  52. static unsigned MultiplyAdd64 (ARMul_State *, ARMword, int, int);
  53. static void Handle_Load_Double (ARMul_State *, ARMword);
  54. static void Handle_Store_Double (ARMul_State *, ARMword);
  55. static int
  56. handle_v6_insn (ARMul_State * state, ARMword instr);
  57. #define LUNSIGNED (0) /* unsigned operation */
  58. #define LSIGNED (1) /* signed operation */
  59. #define LDEFAULT (0) /* default : do nothing */
  60. #define LSCC (1) /* set condition codes on result */
  61. #ifdef NEED_UI_LOOP_HOOK
  62. /* How often to run the ui_loop update, when in use. */
  63. #define UI_LOOP_POLL_INTERVAL 0x32000
  64. /* Counter for the ui_loop_hook update. */
  65. static int ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
  66. /* Actual hook to call to run through gdb's gui event loop. */
  67. extern int (*ui_loop_hook) (int);
  68. #endif /* NEED_UI_LOOP_HOOK */
  69. /* Short-hand macros for LDR/STR. */
  70. /* Store post decrement writeback. */
  71. #define SHDOWNWB() \
  72. lhs = LHS ; \
  73. if (StoreHalfWord (state, instr, lhs)) \
  74. LSBase = lhs - GetLS7RHS (state, instr);
  75. /* Store post increment writeback. */
  76. #define SHUPWB() \
  77. lhs = LHS ; \
  78. if (StoreHalfWord (state, instr, lhs)) \
  79. LSBase = lhs + GetLS7RHS (state, instr);
  80. /* Store pre decrement. */
  81. #define SHPREDOWN() \
  82. (void)StoreHalfWord (state, instr, LHS - GetLS7RHS (state, instr));
  83. /* Store pre decrement writeback. */
  84. #define SHPREDOWNWB() \
  85. temp = LHS - GetLS7RHS (state, instr); \
  86. if (StoreHalfWord (state, instr, temp)) \
  87. LSBase = temp;
  88. /* Store pre increment. */
  89. #define SHPREUP() \
  90. (void)StoreHalfWord (state, instr, LHS + GetLS7RHS (state, instr));
  91. /* Store pre increment writeback. */
  92. #define SHPREUPWB() \
  93. temp = LHS + GetLS7RHS (state, instr); \
  94. if (StoreHalfWord (state, instr, temp)) \
  95. LSBase = temp;
  96. /* Load post decrement writeback. */
  97. #define LHPOSTDOWN() \
  98. { \
  99. int done = 1; \
  100. lhs = LHS; \
  101. temp = lhs - GetLS7RHS (state, instr); \
  102. \
  103. switch (BITS (5, 6)) \
  104. { \
  105. case 1: /* H */ \
  106. if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \
  107. LSBase = temp; \
  108. break; \
  109. case 2: /* SB */ \
  110. if (LoadByte (state, instr, lhs, LSIGNED)) \
  111. LSBase = temp; \
  112. break; \
  113. case 3: /* SH */ \
  114. if (LoadHalfWord (state, instr, lhs, LSIGNED)) \
  115. LSBase = temp; \
  116. break; \
  117. case 0: /* SWP handled elsewhere. */ \
  118. default: \
  119. done = 0; \
  120. break; \
  121. } \
  122. if (done) \
  123. break; \
  124. }
  125. /* Load post increment writeback. */
  126. #define LHPOSTUP() \
  127. { \
  128. int done = 1; \
  129. lhs = LHS; \
  130. temp = lhs + GetLS7RHS (state, instr); \
  131. \
  132. switch (BITS (5, 6)) \
  133. { \
  134. case 1: /* H */ \
  135. if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \
  136. LSBase = temp; \
  137. break; \
  138. case 2: /* SB */ \
  139. if (LoadByte (state, instr, lhs, LSIGNED)) \
  140. LSBase = temp; \
  141. break; \
  142. case 3: /* SH */ \
  143. if (LoadHalfWord (state, instr, lhs, LSIGNED)) \
  144. LSBase = temp; \
  145. break; \
  146. case 0: /* SWP handled elsewhere. */ \
  147. default: \
  148. done = 0; \
  149. break; \
  150. } \
  151. if (done) \
  152. break; \
  153. }
  154. /* Load pre decrement. */
  155. #define LHPREDOWN() \
  156. { \
  157. int done = 1; \
  158. \
  159. temp = LHS - GetLS7RHS (state, instr); \
  160. switch (BITS (5, 6)) \
  161. { \
  162. case 1: /* H */ \
  163. (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \
  164. break; \
  165. case 2: /* SB */ \
  166. (void) LoadByte (state, instr, temp, LSIGNED); \
  167. break; \
  168. case 3: /* SH */ \
  169. (void) LoadHalfWord (state, instr, temp, LSIGNED); \
  170. break; \
  171. case 0: \
  172. /* SWP handled elsewhere. */ \
  173. default: \
  174. done = 0; \
  175. break; \
  176. } \
  177. if (done) \
  178. break; \
  179. }
  180. /* Load pre decrement writeback. */
  181. #define LHPREDOWNWB() \
  182. { \
  183. int done = 1; \
  184. \
  185. temp = LHS - GetLS7RHS (state, instr); \
  186. switch (BITS (5, 6)) \
  187. { \
  188. case 1: /* H */ \
  189. if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \
  190. LSBase = temp; \
  191. break; \
  192. case 2: /* SB */ \
  193. if (LoadByte (state, instr, temp, LSIGNED)) \
  194. LSBase = temp; \
  195. break; \
  196. case 3: /* SH */ \
  197. if (LoadHalfWord (state, instr, temp, LSIGNED)) \
  198. LSBase = temp; \
  199. break; \
  200. case 0: \
  201. /* SWP handled elsewhere. */ \
  202. default: \
  203. done = 0; \
  204. break; \
  205. } \
  206. if (done) \
  207. break; \
  208. }
  209. /* Load pre increment. */
  210. #define LHPREUP() \
  211. { \
  212. int done = 1; \
  213. \
  214. temp = LHS + GetLS7RHS (state, instr); \
  215. switch (BITS (5, 6)) \
  216. { \
  217. case 1: /* H */ \
  218. (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \
  219. break; \
  220. case 2: /* SB */ \
  221. (void) LoadByte (state, instr, temp, LSIGNED); \
  222. break; \
  223. case 3: /* SH */ \
  224. (void) LoadHalfWord (state, instr, temp, LSIGNED); \
  225. break; \
  226. case 0: \
  227. /* SWP handled elsewhere. */ \
  228. default: \
  229. done = 0; \
  230. break; \
  231. } \
  232. if (done) \
  233. break; \
  234. }
  235. /* Load pre increment writeback. */
  236. #define LHPREUPWB() \
  237. { \
  238. int done = 1; \
  239. \
  240. temp = LHS + GetLS7RHS (state, instr); \
  241. switch (BITS (5, 6)) \
  242. { \
  243. case 1: /* H */ \
  244. if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \
  245. LSBase = temp; \
  246. break; \
  247. case 2: /* SB */ \
  248. if (LoadByte (state, instr, temp, LSIGNED)) \
  249. LSBase = temp; \
  250. break; \
  251. case 3: /* SH */ \
  252. if (LoadHalfWord (state, instr, temp, LSIGNED)) \
  253. LSBase = temp; \
  254. break; \
  255. case 0: \
  256. /* SWP handled elsewhere. */ \
  257. default: \
  258. done = 0; \
  259. break; \
  260. } \
  261. if (done) \
  262. break; \
  263. }
  264. /*ywc 2005-03-31*/
  265. //teawater add for arm2x86 2005.02.17-------------------------------------------
  266. #ifdef DBCT
  267. #include "dbct/tb.h"
  268. #include "dbct/arm2x86_self.h"
  269. #endif
  270. //AJ2D--------------------------------------------------------------------------
  271. //Diff register
  272. unsigned int mirror_register_file[39];
  273. /* EMULATION of ARM6. */
  274. extern int debugmode;
  275. int ARMul_ICE_debug(ARMul_State *state,ARMword instr,ARMword addr);
  276. #ifdef MODE32
  277. //chy 2006-04-12, for ICE debug
  278. int ARMul_ICE_debug(ARMul_State *state,ARMword instr,ARMword addr)
  279. {
  280. return 0;
  281. }
  282. static int dump = 0;
  283. ARMword ARMul_Debug(ARMul_State * state, ARMword pc, ARMword instr)
  284. {
  285. /*printf("[%08x] ", pc);
  286. arm11_Disasm32(pc);*/
  287. /*if (pc >= 0x0010303C && pc <= 0x00103050)
  288. {
  289. printf("[%08x] = %08X = ", pc, instr);
  290. arm11_Disasm32(pc);
  291. arm11_Dump();
  292. }*/
  293. //fprintf(stderr,"[%08x]\n", pc);
  294. //if (pc == 0x00240C88)
  295. // arm11_Dump();
  296. /*if (pc == 0x188e04)
  297. {
  298. DEBUG("read %08X %08X %016X %08X %08X from %08X", state->Reg[0], state->Reg[1], state->Reg[2] | state->Reg[3] << 32, mem_Read32(state->Reg[13]), mem_Read32(state->Reg[13] + 4), state->Reg[14]);
  299. }
  300. if (pc == 0x21222c)
  301. {
  302. arm11_Dump();
  303. mem_Dbugdump();
  304. }*/
  305. /*if (pc == 0x0022D168)
  306. {
  307. int j = 0;
  308. }*/
  309. /*if (state->Reg[4] == 0x00105734)
  310. {
  311. printf("[%08x] ", pc);
  312. arm11_Disasm32(pc);
  313. }*/
  314. return 0;
  315. }
  316. /*
  317. void chy_debug()
  318. {
  319. printf("SkyEye chy_deubeg begin\n");
  320. }
  321. */
  322. ARMword
  323. ARMul_Emulate32 (ARMul_State * state)
  324. #else
  325. ARMword
  326. ARMul_Emulate26 (ARMul_State * state)
  327. #endif
  328. {
  329. /* The PC pipeline value depends on whether ARM
  330. or Thumb instructions are being
  331. d. */
  332. ARMword isize;
  333. ARMword instr; /* The current instruction. */
  334. ARMword dest = 0; /* Almost the DestBus. */
  335. ARMword temp; /* Ubiquitous third hand. */
  336. ARMword pc = 0; /* The address of the current instruction. */
  337. ARMword lhs; /* Almost the ABus and BBus. */
  338. ARMword rhs;
  339. ARMword decoded = 0; /* Instruction pipeline. */
  340. ARMword loaded = 0;
  341. ARMword decoded_addr=0;
  342. ARMword loaded_addr=0;
  343. ARMword have_bp=0;
  344. #ifdef callstacker
  345. char a[256];
  346. #endif
  347. /* shenoubang */
  348. static int instr_sum = 0;
  349. int reg_index = 0;
  350. #if DIFF_STATE
  351. //initialize all mirror register for follow mode
  352. for (reg_index = 0; reg_index < 16; reg_index ++) {
  353. mirror_register_file[reg_index] = state->Reg[reg_index];
  354. }
  355. mirror_register_file[CPSR_REG] = state->Cpsr;
  356. mirror_register_file[R13_SVC] = state->RegBank[SVCBANK][13];
  357. mirror_register_file[R14_SVC] = state->RegBank[SVCBANK][14];
  358. mirror_register_file[R13_ABORT] = state->RegBank[ABORTBANK][13];
  359. mirror_register_file[R14_ABORT] = state->RegBank[ABORTBANK][14];
  360. mirror_register_file[R13_UNDEF] = state->RegBank[UNDEFBANK][13];
  361. mirror_register_file[R14_UNDEF] = state->RegBank[UNDEFBANK][14];
  362. mirror_register_file[R13_IRQ] = state->RegBank[IRQBANK][13];
  363. mirror_register_file[R14_IRQ] = state->RegBank[IRQBANK][14];
  364. mirror_register_file[R8_FIRQ] = state->RegBank[FIQBANK][8];
  365. mirror_register_file[R9_FIRQ] = state->RegBank[FIQBANK][9];
  366. mirror_register_file[R10_FIRQ] = state->RegBank[FIQBANK][10];
  367. mirror_register_file[R11_FIRQ] = state->RegBank[FIQBANK][11];
  368. mirror_register_file[R12_FIRQ] = state->RegBank[FIQBANK][12];
  369. mirror_register_file[R13_FIRQ] = state->RegBank[FIQBANK][13];
  370. mirror_register_file[R14_FIRQ] = state->RegBank[FIQBANK][14];
  371. mirror_register_file[SPSR_SVC] = state->Spsr[SVCBANK];
  372. mirror_register_file[SPSR_ABORT] = state->Spsr[ABORTBANK];
  373. mirror_register_file[SPSR_UNDEF] = state->Spsr[UNDEFBANK];
  374. mirror_register_file[SPSR_IRQ] = state->Spsr[IRQBANK];
  375. mirror_register_file[SPSR_FIRQ] = state->Spsr[FIQBANK];
  376. #endif
  377. /* Execute the next instruction. */
  378. if (state->NextInstr < PRIMEPIPE) {
  379. decoded = state->decoded;
  380. loaded = state->loaded;
  381. pc = state->pc;
  382. //chy 2006-04-12, for ICE debug
  383. decoded_addr=state->decoded_addr;
  384. loaded_addr=state->loaded_addr;
  385. }
  386. do {
  387. //print_func_name(state->pc);
  388. /* Just keep going. */
  389. isize = INSN_SIZE;
  390. switch (state->NextInstr) {
  391. case SEQ:
  392. /* Advance the pipeline, and an S cycle. */
  393. state->Reg[15] += isize;
  394. pc += isize;
  395. instr = decoded;
  396. //chy 2006-04-12, for ICE debug
  397. have_bp = ARMul_ICE_debug(state,instr,decoded_addr);
  398. decoded = loaded;
  399. decoded_addr=loaded_addr;
  400. //loaded = ARMul_LoadInstrS (state, pc + (isize * 2),
  401. // isize);
  402. loaded_addr=pc + (isize * 2);
  403. if (have_bp) goto TEST_EMULATE;
  404. break;
  405. case NONSEQ:
  406. /* Advance the pipeline, and an N cycle. */
  407. state->Reg[15] += isize;
  408. pc += isize;
  409. instr = decoded;
  410. //chy 2006-04-12, for ICE debug
  411. have_bp=ARMul_ICE_debug(state,instr,decoded_addr);
  412. decoded = loaded;
  413. decoded_addr=loaded_addr;
  414. //loaded = ARMul_LoadInstrN (state, pc + (isize * 2),
  415. // isize);
  416. loaded_addr=pc + (isize * 2);
  417. NORMALCYCLE;
  418. if (have_bp) goto TEST_EMULATE;
  419. break;
  420. case PCINCEDSEQ:
  421. /* Program counter advanced, and an S cycle. */
  422. pc += isize;
  423. instr = decoded;
  424. //chy 2006-04-12, for ICE debug
  425. have_bp=ARMul_ICE_debug(state,instr,decoded_addr);
  426. decoded = loaded;
  427. decoded_addr=loaded_addr;
  428. //loaded = ARMul_LoadInstrS (state, pc + (isize * 2),
  429. // isize);
  430. loaded_addr=pc + (isize * 2);
  431. NORMALCYCLE;
  432. if (have_bp) goto TEST_EMULATE;
  433. break;
  434. case PCINCEDNONSEQ:
  435. /* Program counter advanced, and an N cycle. */
  436. pc += isize;
  437. instr = decoded;
  438. //chy 2006-04-12, for ICE debug
  439. have_bp=ARMul_ICE_debug(state,instr,decoded_addr);
  440. decoded = loaded;
  441. decoded_addr=loaded_addr;
  442. //loaded = ARMul_LoadInstrN (state, pc + (isize * 2),
  443. // isize);
  444. loaded_addr=pc + (isize * 2);
  445. NORMALCYCLE;
  446. if (have_bp) goto TEST_EMULATE;
  447. break;
  448. case RESUME:
  449. /* The program counter has been changed. */
  450. pc = state->Reg[15];
  451. #ifndef MODE32
  452. pc = pc & R15PCBITS;
  453. #endif
  454. state->Reg[15] = pc + (isize * 2);
  455. state->Aborted = 0;
  456. //chy 2004-05-25, fix bug provided by Carl van Schaik<cvansch@cse.unsw.EDU.AU>
  457. state->AbortAddr = 1;
  458. instr = ARMul_LoadInstrN (state, pc, isize);
  459. //instr = ARMul_ReLoadInstr (state, pc, isize);
  460. //chy 2006-04-12, for ICE debug
  461. have_bp=ARMul_ICE_debug(state,instr,pc);
  462. //decoded =
  463. // ARMul_ReLoadInstr (state, pc + isize, isize);
  464. decoded_addr=pc+isize;
  465. //loaded = ARMul_ReLoadInstr (state, pc + isize * 2,
  466. // isize);
  467. loaded_addr=pc + isize * 2;
  468. NORMALCYCLE;
  469. if (have_bp) goto TEST_EMULATE;
  470. break;
  471. default:
  472. /* The program counter has been changed. */
  473. pc = state->Reg[15];
  474. #ifndef MODE32
  475. pc = pc & R15PCBITS;
  476. #endif
  477. state->Reg[15] = pc + (isize * 2);
  478. state->Aborted = 0;
  479. //chy 2004-05-25, fix bug provided by Carl van Schaik<cvansch@cse.unsw.EDU.AU>
  480. state->AbortAddr = 1;
  481. instr = ARMul_LoadInstrN (state, pc, isize);
  482. //chy 2006-04-12, for ICE debug
  483. have_bp=ARMul_ICE_debug(state,instr,pc);
  484. #if 0
  485. decoded =
  486. ARMul_LoadInstrS (state, pc + (isize), isize);
  487. #endif
  488. decoded_addr=pc+isize;
  489. #if 0
  490. loaded = ARMul_LoadInstrS (state, pc + (isize * 2),
  491. isize);
  492. #endif
  493. loaded_addr=pc + isize * 2;
  494. NORMALCYCLE;
  495. if (have_bp) goto TEST_EMULATE;
  496. break;
  497. }
  498. #if 0
  499. int idx = 0;
  500. printf("pc:%x\n", pc);
  501. for (; idx < 17; idx ++) {
  502. printf("R%d:%x\t", idx, state->Reg[idx]);
  503. }
  504. printf("\n");
  505. #endif
  506. instr = ARMul_LoadInstrN (state, pc, isize);
  507. state->last_instr = state->CurrInstr;
  508. state->CurrInstr = instr;
  509. ARMul_Debug(state, pc, instr);
  510. #if 0
  511. if((state->NumInstrs % 10000000) == 0)
  512. printf("---|%p|--- %lld\n", pc, state->NumInstrs);
  513. if(state->NumInstrs > (3000000000)) {
  514. static int flag = 0;
  515. if(pc == 0x8032ccc4) {
  516. flag = 300;
  517. }
  518. if(flag) {
  519. int idx = 0;
  520. printf("------------------------------------\n");
  521. printf("pc:%x\n", pc);
  522. for (; idx < 17; idx ++) {
  523. printf("R%d:%x\t", idx, state->Reg[idx]);
  524. }
  525. printf("\nN:%d\t Z:%d\t C:%d\t V:%d\n", state->NFlag, state->ZFlag, state->CFlag, state->VFlag);
  526. printf("\n");
  527. printf("------------------------------------\n");
  528. flag--;
  529. }
  530. }
  531. #endif
  532. #if DIFF_STATE
  533. fprintf(state->state_log, "PC:0x%x\n", pc);
  534. if (pc && (pc + 8) != state->Reg[15]) {
  535. printf("lucky dog\n");
  536. printf("pc is %x, R15 is %x\n", pc, state->Reg[15]);
  537. //exit(-1);
  538. }
  539. for (reg_index = 0; reg_index < 16; reg_index ++) {
  540. if (state->Reg[reg_index] != mirror_register_file[reg_index]) {
  541. fprintf(state->state_log, "R%d:0x%x\n", reg_index, state->Reg[reg_index]);
  542. mirror_register_file[reg_index] = state->Reg[reg_index];
  543. }
  544. }
  545. if (state->Cpsr != mirror_register_file[CPSR_REG]) {
  546. fprintf(state->state_log, "Cpsr:0x%x\n", state->Cpsr);
  547. mirror_register_file[CPSR_REG] = state->Cpsr;
  548. }
  549. if (state->RegBank[SVCBANK][13] != mirror_register_file[R13_SVC]) {
  550. fprintf(state->state_log, "R13_SVC:0x%x\n", state->RegBank[SVCBANK][13]);
  551. mirror_register_file[R13_SVC] = state->RegBank[SVCBANK][13];
  552. }
  553. if (state->RegBank[SVCBANK][14] != mirror_register_file[R14_SVC]) {
  554. fprintf(state->state_log, "R14_SVC:0x%x\n", state->RegBank[SVCBANK][14]);
  555. mirror_register_file[R14_SVC] = state->RegBank[SVCBANK][14];
  556. }
  557. if (state->RegBank[ABORTBANK][13] != mirror_register_file[R13_ABORT]) {
  558. fprintf(state->state_log, "R13_ABORT:0x%x\n", state->RegBank[ABORTBANK][13]);
  559. mirror_register_file[R13_ABORT] = state->RegBank[ABORTBANK][13];
  560. }
  561. if (state->RegBank[ABORTBANK][14] != mirror_register_file[R14_ABORT]) {
  562. fprintf(state->state_log, "R14_ABORT:0x%x\n", state->RegBank[ABORTBANK][14]);
  563. mirror_register_file[R14_ABORT] = state->RegBank[ABORTBANK][14];
  564. }
  565. if (state->RegBank[UNDEFBANK][13] != mirror_register_file[R13_UNDEF]) {
  566. fprintf(state->state_log, "R13_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][13]);
  567. mirror_register_file[R13_UNDEF] = state->RegBank[UNDEFBANK][13];
  568. }
  569. if (state->RegBank[UNDEFBANK][14] != mirror_register_file[R14_UNDEF]) {
  570. fprintf(state->state_log, "R14_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][14]);
  571. mirror_register_file[R14_UNDEF] = state->RegBank[UNDEFBANK][14];
  572. }
  573. if (state->RegBank[IRQBANK][13] != mirror_register_file[R13_IRQ]) {
  574. fprintf(state->state_log, "R13_IRQ:0x%x\n", state->RegBank[IRQBANK][13]);
  575. mirror_register_file[R13_IRQ] = state->RegBank[IRQBANK][13];
  576. }
  577. if (state->RegBank[IRQBANK][14] != mirror_register_file[R14_IRQ]) {
  578. fprintf(state->state_log, "R14_IRQ:0x%x\n", state->RegBank[IRQBANK][14]);
  579. mirror_register_file[R14_IRQ] = state->RegBank[IRQBANK][14];
  580. }
  581. if (state->RegBank[FIQBANK][8] != mirror_register_file[R8_FIRQ]) {
  582. fprintf(state->state_log, "R8_FIRQ:0x%x\n", state->RegBank[FIQBANK][8]);
  583. mirror_register_file[R8_FIRQ] = state->RegBank[FIQBANK][8];
  584. }
  585. if (state->RegBank[FIQBANK][9] != mirror_register_file[R9_FIRQ]) {
  586. fprintf(state->state_log, "R9_FIRQ:0x%x\n", state->RegBank[FIQBANK][9]);
  587. mirror_register_file[R9_FIRQ] = state->RegBank[FIQBANK][9];
  588. }
  589. if (state->RegBank[FIQBANK][10] != mirror_register_file[R10_FIRQ]) {
  590. fprintf(state->state_log, "R10_FIRQ:0x%x\n", state->RegBank[FIQBANK][10]);
  591. mirror_register_file[R10_FIRQ] = state->RegBank[FIQBANK][10];
  592. }
  593. if (state->RegBank[FIQBANK][11] != mirror_register_file[R11_FIRQ]) {
  594. fprintf(state->state_log, "R11_FIRQ:0x%x\n", state->RegBank[FIQBANK][11]);
  595. mirror_register_file[R11_FIRQ] = state->RegBank[FIQBANK][11];
  596. }
  597. if (state->RegBank[FIQBANK][12] != mirror_register_file[R12_FIRQ]) {
  598. fprintf(state->state_log, "R12_FIRQ:0x%x\n", state->RegBank[FIQBANK][12]);
  599. mirror_register_file[R12_FIRQ] = state->RegBank[FIQBANK][12];
  600. }
  601. if (state->RegBank[FIQBANK][13] != mirror_register_file[R13_FIRQ]) {
  602. fprintf(state->state_log, "R13_FIRQ:0x%x\n", state->RegBank[FIQBANK][13]);
  603. mirror_register_file[R13_FIRQ] = state->RegBank[FIQBANK][13];
  604. }
  605. if (state->RegBank[FIQBANK][14] != mirror_register_file[R14_FIRQ]) {
  606. fprintf(state->state_log, "R14_FIRQ:0x%x\n", state->RegBank[FIQBANK][14]);
  607. mirror_register_file[R14_FIRQ] = state->RegBank[FIQBANK][14];
  608. }
  609. if (state->Spsr[SVCBANK] != mirror_register_file[SPSR_SVC]) {
  610. fprintf(state->state_log, "SPSR_SVC:0x%x\n", state->Spsr[SVCBANK]);
  611. mirror_register_file[SPSR_SVC] = state->RegBank[SVCBANK];
  612. }
  613. if (state->Spsr[ABORTBANK] != mirror_register_file[SPSR_ABORT]) {
  614. fprintf(state->state_log, "SPSR_ABORT:0x%x\n", state->Spsr[ABORTBANK]);
  615. mirror_register_file[SPSR_ABORT] = state->RegBank[ABORTBANK];
  616. }
  617. if (state->Spsr[UNDEFBANK] != mirror_register_file[SPSR_UNDEF]) {
  618. fprintf(state->state_log, "SPSR_UNDEF:0x%x\n", state->Spsr[UNDEFBANK]);
  619. mirror_register_file[SPSR_UNDEF] = state->RegBank[UNDEFBANK];
  620. }
  621. if (state->Spsr[IRQBANK] != mirror_register_file[SPSR_IRQ]) {
  622. fprintf(state->state_log, "SPSR_IRQ:0x%x\n", state->Spsr[IRQBANK]);
  623. mirror_register_file[SPSR_IRQ] = state->RegBank[IRQBANK];
  624. }
  625. if (state->Spsr[FIQBANK] != mirror_register_file[SPSR_FIRQ]) {
  626. fprintf(state->state_log, "SPSR_FIRQ:0x%x\n", state->Spsr[FIQBANK]);
  627. mirror_register_file[SPSR_FIRQ] = state->RegBank[FIQBANK];
  628. }
  629. #endif
  630. #if 0
  631. uint32_t alex = 0;
  632. static int flagged = 0;
  633. if ((flagged == 0) && (pc == 0xb224)) {
  634. flagged++;
  635. }
  636. if ((flagged == 1) && (pc == 0x1a800)) {
  637. flagged++;
  638. }
  639. if (flagged == 3) {
  640. printf("---|%p|--- %x\n", pc, state->NumInstrs);
  641. for (alex = 0; alex < 15; alex++) {
  642. printf("R%02d % 8x\n", alex, state->Reg[alex]);
  643. }
  644. printf("R%02d % 8x\n", alex, state->Reg[alex] - 8);
  645. printf("CPS %x%07x\n", (state->NFlag<<3 | state->ZFlag<<2 | state->CFlag<<1 | state->VFlag), state->Cpsr & 0xfffffff);
  646. } else {
  647. if (state->NumInstrs < 0x400000) {
  648. //exit(-1);
  649. }
  650. }
  651. #endif
  652. /*if (state->EventSet)
  653. ARMul_EnvokeEvent (state);*/
  654. #if 0
  655. /* do profiling for code coverage */
  656. if (skyeye_config.code_cov.prof_on)
  657. cov_prof(EXEC_FLAG, pc);
  658. #endif
  659. //2003-07-11 chy: for test
  660. #if 0
  661. if (skyeye_config.log.logon >= 1) {
  662. if (state->NumInstrs >= skyeye_config.log.start &&
  663. state->NumInstrs <= skyeye_config.log.end) {
  664. static int mybegin = 0;
  665. static int myinstrnum = 0;
  666. if (mybegin == 0)
  667. mybegin = 1;
  668. #if 0
  669. if (state->NumInstrs == 3695) {
  670. printf ("***********SKYEYE: numinstr = 3695\n");
  671. }
  672. static int mybeg2 = 0;
  673. static int mybeg3 = 0;
  674. static int mybeg4 = 0;
  675. static int mybeg5 = 0;
  676. if (pc == 0xa0008000) {
  677. //mybegin=1;
  678. printf ("************SKYEYE: real vmlinux begin now numinstr is %llu ****************\n", state->NumInstrs);
  679. }
  680. //chy 2003-09-02 test fiq
  681. if (state->NumInstrs == 67347000) {
  682. printf ("***********SKYEYE: numinstr = 67347000, begin log\n");
  683. mybegin = 1;
  684. }
  685. if (pc == 0xc00087b4) { //numinstr=67348714
  686. mybegin = 1;
  687. printf ("************SKYEYE: test irq now numinstr is %llu ****************\n", state->NumInstrs);
  688. }
  689. if (pc == 0xc00087b8) { //in start_kernel::sti()
  690. mybeg4 = 1;
  691. printf ("************SKYEYE: startkerenl: sti now numinstr is %llu ********\n", state->NumInstrs);
  692. }
  693. /*if (pc==0xc001e4f4||pc==0xc001e4f8||pc==0xc001e4fc||pc==0xc001e500||pc==0xffff0004) { //MRA instr */
  694. if (pc == 0xc001e500) { //MRA instr
  695. mybeg5 = 1;
  696. printf ("************SKYEYE: MRA instr now numinstr is %llu ********\n", state->NumInstrs);
  697. }
  698. if (pc >= 0xc0000000 && mybeg2 == 0) {
  699. mybeg2 = 1;
  700. printf ("************SKYEYE: enable mmu&cache, now numinstr is %llu **************\n", state->NumInstrs);
  701. SKYEYE_OUTREGS (stderr);
  702. printf ("************************************************************************\n");
  703. }
  704. //chy 2003-09-01 test after tlb-flush
  705. if (pc == 0xc00261ac) {
  706. //sleep(2);
  707. mybeg3 = 1;
  708. printf ("************SKYEYE: after tlb-flush numinstr is %llu ****************\n", state->NumInstrs);
  709. }
  710. if (mybeg3 == 1) {
  711. SKYEYE_OUTREGS (skyeye_logfd);
  712. SKYEYE_OUTMOREREGS (skyeye_logfd);
  713. fprintf (skyeye_logfd, "\n");
  714. }
  715. #endif
  716. if (mybegin == 1) {
  717. //fprintf(skyeye_logfd,"p %x,i %x,d %x,l %x,",pc,instr,decoded,loaded);
  718. //chy for test 20050729
  719. /*if (state->NumInstrs>=3302294) {
  720. if (pc==0x100c9d4 && instr==0xe1b0f00e){
  721. chy_debug();
  722. printf("*********************************************\n");
  723. printf("******SKYEYE N %llx :p %x,i %x\n SKYEYE******\n",state->NumInstrs,pc,instr);
  724. printf("*********************************************\n");
  725. }
  726. */
  727. if (skyeye_config.log.logon >= 1)
  728. /*
  729. fprintf (skyeye_logfd,
  730. "N %llx :p %x,i %x,",
  731. state->NumInstrs, pc,
  732. #ifdef MODET
  733. TFLAG ? instr & 0xffff : instr
  734. #else
  735. instr
  736. #endif
  737. );
  738. */
  739. fprintf(skyeye_logfd, "pc=0x%x,r3=0x%x\n", pc, state->Reg[3]);
  740. if (skyeye_config.log.logon >= 2)
  741. SKYEYE_OUTREGS (skyeye_logfd);
  742. if (skyeye_config.log.logon >= 3)
  743. SKYEYE_OUTMOREREGS
  744. (skyeye_logfd);
  745. //fprintf (skyeye_logfd, "\n");
  746. if (skyeye_config.log.length > 0) {
  747. myinstrnum++;
  748. if (myinstrnum >=
  749. skyeye_config.log.
  750. length) {
  751. myinstrnum = 0;
  752. fflush (skyeye_logfd);
  753. fseek (skyeye_logfd,
  754. 0L, SEEK_SET);
  755. }
  756. }
  757. }
  758. //SKYEYE_OUTREGS(skyeye_logfd);
  759. //SKYEYE_OUTMOREREGS(skyeye_logfd);
  760. }
  761. }
  762. #endif
  763. #if 0 /* Enable this for a helpful bit of debugging when tracing is needed. */
  764. fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr);
  765. if (instr == 0)
  766. abort ();
  767. #endif
  768. #if 0 /* Enable this code to help track down stack alignment bugs. */
  769. {
  770. static ARMword old_sp = -1;
  771. if (old_sp != state->Reg[13]) {
  772. old_sp = state->Reg[13];
  773. fprintf (stderr,
  774. "pc: %08x: SP set to %08x%s\n",
  775. pc & ~1, old_sp,
  776. (old_sp % 8) ? " [UNALIGNED!]" : "");
  777. }
  778. }
  779. #endif
  780. /* Any exceptions ? */
  781. if (state->NresetSig == LOW) {
  782. ARMul_Abort (state, ARMul_ResetV);
  783. /*added energy_prof statement by ksh in 2004-11-26 */
  784. //chy 2005-07-28 for standalone
  785. //ARMul_do_energy(state,instr,pc);
  786. break;
  787. } else if (!state->NfiqSig && !FFLAG) {
  788. ARMul_Abort (state, ARMul_FIQV);
  789. /*added energy_prof statement by ksh in 2004-11-26 */
  790. //chy 2005-07-28 for standalone
  791. //ARMul_do_energy(state,instr,pc);
  792. break;
  793. } else if (!state->NirqSig && !IFLAG) {
  794. ARMul_Abort (state, ARMul_IRQV);
  795. /*added energy_prof statement by ksh in 2004-11-26 */
  796. //chy 2005-07-28 for standalone
  797. //ARMul_do_energy(state,instr,pc);
  798. break;
  799. }
  800. //teawater add for arm2x86 2005.04.26-------------------------------------------
  801. #if 0
  802. // if (state->pc == 0xc011a868 || state->pc == 0xc011a86c) {
  803. if (state->NumInstrs == 1671574 || state->NumInstrs == 1671573 || state->NumInstrs == 1671572
  804. || state->NumInstrs == 1671575) {
  805. for (reg_index = 0; reg_index < 16; reg_index ++) {
  806. printf("R%d:%x\t", reg_index, state->Reg[reg_index]);
  807. }
  808. printf("\n");
  809. }
  810. #endif
  811. if (state->tea_pc) {
  812. int i;
  813. if (state->tea_reg_fd) {
  814. fprintf (state->tea_reg_fd, "\n");
  815. for (i = 0; i < 15; i++) {
  816. fprintf (state->tea_reg_fd, "%x,",
  817. state->Reg[i]);
  818. }
  819. fprintf (state->tea_reg_fd, "%x,", pc);
  820. state->Cpsr = ARMul_GetCPSR (state);
  821. fprintf (state->tea_reg_fd, "%x\n",
  822. state->Cpsr);
  823. } else {
  824. printf ("\n");
  825. for (i = 0; i < 15; i++) {
  826. printf ("%x,", state->Reg[i]);
  827. }
  828. printf ("%x,", pc);
  829. state->Cpsr = ARMul_GetCPSR (state);
  830. printf ("%x\n", state->Cpsr);
  831. }
  832. }
  833. //AJ2D--------------------------------------------------------------------------
  834. /*if (state->CallDebug > 0) {
  835. instr = ARMul_Debug (state, pc, instr);
  836. if (state->Emulate < ONCE) {
  837. state->NextInstr = RESUME;
  838. break;
  839. }
  840. if (state->Debug) {
  841. fprintf (stderr,
  842. "sim: At %08lx Instr %08lx Mode %02lx\n",
  843. pc, instr, state->Mode);
  844. (void) fgetc (stdin);
  845. }
  846. }
  847. else*/
  848. if (state->Emulate < ONCE) {
  849. state->NextInstr = RESUME;
  850. break;
  851. }
  852. //io_do_cycle (state);
  853. state->NumInstrs++;
  854. #if 0
  855. if (state->NumInstrs % 10000000 == 0) {
  856. printf("10 MIPS instr have been executed\n");
  857. }
  858. #endif
  859. #ifdef MODET
  860. /* Provide Thumb instruction decoding. If the processor is in Thumb
  861. mode, then we can simply decode the Thumb instruction, and map it
  862. to the corresponding ARM instruction (by directly loading the
  863. instr variable, and letting the normal ARM simulator
  864. execute). There are some caveats to ensure that the correct
  865. pipelined PC value is used when executing Thumb code, and also for
  866. dealing with the BL instruction. */
  867. if (TFLAG) {
  868. ARMword armOp = 0;
  869. /* Check if in Thumb mode. */
  870. switch (ARMul_ThumbDecode(state, pc, instr, &armOp)) {
  871. case t_undefined:
  872. /* This is a Thumb instruction. */
  873. ARMul_UndefInstr (state, instr);
  874. goto donext;
  875. case t_branch:
  876. /* Already processed. */
  877. //pc = state->Reg[15] - 2;
  878. //state->pc = state->Reg[15] - 2; //ichfly why do I need that
  879. goto donext;
  880. case t_decoded:
  881. /* ARM instruction available. */
  882. //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp);
  883. if (armOp == 0xDEADC0DE) {
  884. LOG_ERROR(Core_ARM11, "Failed to decode thumb opcode %04X at %08X", instr, pc);
  885. }
  886. instr = armOp;
  887. /* So continue instruction decoding. */
  888. break;
  889. default:
  890. break;
  891. }
  892. }
  893. #endif
  894. /* Check the condition codes. */
  895. if ((temp = TOPBITS (28)) == AL) {
  896. /* Vile deed in the need for speed. */
  897. goto mainswitch;
  898. }
  899. /* Check the condition code. */
  900. switch ((int) TOPBITS (28)) {
  901. case AL:
  902. temp = TRUE;
  903. break;
  904. case NV:
  905. /* shenoubang add for armv7 instr dmb 2012-3-11 */
  906. if (state->is_v7) {
  907. if ((instr & 0x0fffff00) == 0x057ff000) {
  908. switch((instr >> 4) & 0xf) {
  909. case 4: /* dsb */
  910. case 5: /* dmb */
  911. case 6: /* isb */
  912. // TODO: do no implemented thes instr
  913. goto donext;
  914. }
  915. }
  916. }
  917. /* dyf add for armv6 instruct CPS 2010.9.17 */
  918. if (state->is_v6) {
  919. /* clrex do nothing here temporary */
  920. if (instr == 0xf57ff01f) {
  921. //printf("clrex \n");
  922. #if 0
  923. int i;
  924. for(i = 0; i < 128; i++) {
  925. state->exclusive_tag_array[i] = 0xffffffff;
  926. }
  927. #endif
  928. /* shenoubang 2012-3-14 refer the dyncom_interpreter */
  929. state->exclusive_tag_array[0] = 0xFFFFFFFF;
  930. state->exclusive_access_state = 0;
  931. goto donext;
  932. }
  933. if (BITS(20, 27) == 0x10) {
  934. if (BIT(19)) {
  935. if (BIT(8)) {
  936. if (BIT(18))
  937. state->Cpsr |= 1<<8;
  938. else
  939. state->Cpsr &= ~(1<<8);
  940. }
  941. if (BIT(7)) {
  942. if (BIT(18))
  943. state->Cpsr |= 1<<7;
  944. else
  945. state->Cpsr &= ~(1<<7);
  946. ASSIGNINT (state->Cpsr & INTBITS);
  947. }
  948. if (BIT(6)) {
  949. if (BIT(18))
  950. state->Cpsr |= 1<<6;
  951. else
  952. state->Cpsr &= ~(1<<6);
  953. ASSIGNINT (state->Cpsr & INTBITS);
  954. }
  955. }
  956. if (BIT(17)) {
  957. state->Cpsr |= BITS(0, 4);
  958. printf("skyeye test state->Mode\n");
  959. if (state->Mode != (state->Cpsr & MODEBITS)) {
  960. state->Mode = ARMul_SwitchMode (state, state->Mode, state->Cpsr & MODEBITS);
  961. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  962. }
  963. }
  964. goto donext;
  965. }
  966. }
  967. if (state->is_v5) {
  968. if (BITS (25, 27) == 5) { /* BLX(1) */
  969. ARMword dest;
  970. state->Reg[14] = pc + 4;
  971. /* Force entry into Thumb mode. */
  972. dest = pc + 8 + 1;
  973. if (BIT (23))
  974. dest += (NEGBRANCH +
  975. (BIT (24) << 1));
  976. else
  977. dest += POSBRANCH +
  978. (BIT (24) << 1);
  979. WriteR15Branch (state, dest);
  980. goto donext;
  981. } else if ((instr & 0xFC70F000) == 0xF450F000) {
  982. /* The PLD instruction. Ignored. */
  983. goto donext;
  984. } else if (((instr & 0xfe500f00) == 0xfc100100)
  985. || ((instr & 0xfe500f00) ==
  986. 0xfc000100)) {
  987. /* wldrw and wstrw are unconditional. */
  988. goto mainswitch;
  989. } else {
  990. /* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2. */
  991. ARMul_UndefInstr (state, instr);
  992. }
  993. }
  994. temp = FALSE;
  995. break;
  996. case EQ:
  997. temp = ZFLAG;
  998. break;
  999. case NE:
  1000. temp = !ZFLAG;
  1001. break;
  1002. case VS:
  1003. temp = VFLAG;
  1004. break;
  1005. case VC:
  1006. temp = !VFLAG;
  1007. break;
  1008. case MI:
  1009. temp = NFLAG;
  1010. break;
  1011. case PL:
  1012. temp = !NFLAG;
  1013. break;
  1014. case CS:
  1015. temp = CFLAG;
  1016. break;
  1017. case CC:
  1018. temp = !CFLAG;
  1019. break;
  1020. case HI:
  1021. temp = (CFLAG && !ZFLAG);
  1022. break;
  1023. case LS:
  1024. temp = (!CFLAG || ZFLAG);
  1025. break;
  1026. case GE:
  1027. temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
  1028. break;
  1029. case LT:
  1030. temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
  1031. break;
  1032. case GT:
  1033. temp = ((!NFLAG && !VFLAG && !ZFLAG)
  1034. || (NFLAG && VFLAG && !ZFLAG));
  1035. break;
  1036. case LE:
  1037. temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG))
  1038. || ZFLAG;
  1039. break;
  1040. } /* cc check */
  1041. //chy 2003-08-24 now #if 0 .... #endif process cp14, cp15.reg14, I disable it...
  1042. /* Actual execution of instructions begins here. */
  1043. /* If the condition codes don't match, stop here. */
  1044. if (temp) {
  1045. mainswitch:
  1046. /* shenoubang sbfx and ubfx instr 2012-3-16 */
  1047. if (state->is_v6) {
  1048. unsigned int m, lsb, width, Rd, Rn, data;
  1049. Rd = Rn = lsb = width = data = m = 0;
  1050. //printf("helloworld\n");
  1051. if ((((int) BITS (21, 27)) == 0x3f) && (((int) BITS (4, 6)) == 0x5)) {
  1052. m = (unsigned)BITS(7, 11);
  1053. width = (unsigned)BITS(16, 20);
  1054. Rd = (unsigned)BITS(12, 15);
  1055. Rn = (unsigned)BITS(0, 3);
  1056. if ((Rd == 15) || (Rn == 15)) {
  1057. ARMul_UndefInstr (state, instr);
  1058. } else if ((m + width) < 32) {
  1059. data = state->Reg[Rn];
  1060. state->Reg[Rd] ^= state->Reg[Rd];
  1061. state->Reg[Rd] = ((ARMword)(data << (31 -(m + width))) >> ((31 - (m + width)) + (m)));
  1062. //SKYEYE_LOG_IN_CLR(RED, "UBFX: In %s, line = %d, Reg_src[%d] = 0x%x, Reg_d[%d] = 0x%x, m = %d, width = %d, Rd = %d, Rn = %d\n",
  1063. // __FUNCTION__, __LINE__, Rn, data, Rd, state->Reg[Rd], m, width + 1, Rd, Rn);
  1064. goto donext;
  1065. }
  1066. } // ubfx instr
  1067. else if ((((int) BITS (21, 27)) == 0x3d) && (((int) BITS (4, 6)) == 0x5)) {
  1068. int tmp = 0;
  1069. Rd = BITS(12, 15);
  1070. Rn = BITS(0, 3);
  1071. lsb = BITS(7, 11);
  1072. width = BITS(16, 20);
  1073. if ((Rd == 15) || (Rn == 15)) {
  1074. ARMul_UndefInstr (state, instr);
  1075. } else if ((lsb + width) < 32) {
  1076. state->Reg[Rd] ^= state->Reg[Rd];
  1077. data = state->Reg[Rn];
  1078. tmp = (data << (32 - (lsb + width + 1)));
  1079. state->Reg[Rd] = (tmp >> (32 - (lsb + width + 1)));
  1080. //SKYEYE_LOG_IN_CLR(RED, "sbfx: In %s, line = %d, pc = 0x%x, instr = 0x%x,Rd = 0x%x, Rn = 0x%x, lsb = %d, width = %d, Rs[%d] = 0x%x, Rd[%d] = 0x%x\n",
  1081. // __func__, __LINE__, pc, instr, Rd, Rn, lsb, width + 1, Rn, state->Reg[Rn], Rd, state->Reg[Rd]);
  1082. goto donext;
  1083. }
  1084. } // sbfx instr
  1085. else if ((((int)BITS(21, 27)) == 0x3e) && ((int)BITS(4, 6) == 0x1)) {
  1086. //(ARMword)(instr<<(31-(n))) >> ((31-(n))+(m))
  1087. unsigned msb ,tmp_rn, tmp_rd, dst;
  1088. tmp_rd = tmp_rn = dst = 0;
  1089. Rd = BITS(12, 15);
  1090. Rn = BITS(0, 3);
  1091. lsb = BITS(7, 11);
  1092. msb = BITS(16, 20); //-V519
  1093. if ((Rd == 15)) {
  1094. ARMul_UndefInstr (state, instr);
  1095. } else if ((Rn == 15)) {
  1096. data = state->Reg[Rd];
  1097. tmp_rd = ((ARMword)(data << (31 - lsb)) >> (31 - lsb));
  1098. dst = ((data >> msb) << (msb - lsb));
  1099. dst = (dst << lsb) | tmp_rd;
  1100. /*SKYEYE_DBG("BFC instr: msb = %d, lsb = %d, Rd[%d] : 0x%x, dst = 0x%x\n",
  1101. msb, lsb, Rd, state->Reg[Rd], dst);*/
  1102. goto donext;
  1103. } // bfc instr
  1104. else if (((msb >= lsb) && (msb < 32))) {
  1105. data = state->Reg[Rn];
  1106. tmp_rn = ((ARMword)(data << (31 - (msb - lsb))) >> (31 - (msb - lsb)));
  1107. data = state->Reg[Rd];
  1108. tmp_rd = ((ARMword)(data << (31 - lsb)) >> (31 - lsb));
  1109. dst = ((data >> msb) << (msb - lsb)) | tmp_rn;
  1110. dst = (dst << lsb) | tmp_rd;
  1111. /*SKYEYE_DBG("BFI instr:msb = %d, lsb = %d, Rd[%d] : 0x%x, Rn[%d]: 0x%x, dst = 0x%x\n",
  1112. msb, lsb, Rd, state->Reg[Rd], Rn, state->Reg[Rn], dst);*/
  1113. goto donext;
  1114. } // bfi instr
  1115. }
  1116. }
  1117. switch ((int) BITS (20, 27)) {
  1118. /* Data Processing Register RHS Instructions. */
  1119. case 0x00: /* AND reg and MUL */
  1120. #ifdef MODET
  1121. if (BITS (4, 11) == 0xB) {
  1122. /* STRH register offset, no write-back, down, post indexed. */
  1123. SHDOWNWB ();
  1124. break;
  1125. }
  1126. if (BITS (4, 7) == 0xD) {
  1127. Handle_Load_Double (state, instr);
  1128. break;
  1129. }
  1130. if (BITS (4, 7) == 0xF) {
  1131. Handle_Store_Double (state, instr);
  1132. break;
  1133. }
  1134. #endif
  1135. if (BITS (4, 7) == 9) {
  1136. /* MUL */
  1137. rhs = state->Reg[MULRHSReg];
  1138. //if (MULLHSReg == MULDESTReg) {
  1139. if(0) { /* For armv6, the restriction is removed */
  1140. UNDEF_MULDestEQOp1;
  1141. state->Reg[MULDESTReg] = 0;
  1142. } else if (MULDESTReg != 15)
  1143. state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs;
  1144. else
  1145. UNDEF_MULPCDest;
  1146. for (dest = 0, temp = 0; dest < 32;
  1147. dest++)
  1148. if (rhs & (1L << dest))
  1149. temp = dest;
  1150. /* Mult takes this many/2 I cycles. */
  1151. ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
  1152. } else {
  1153. /* AND reg. */
  1154. rhs = DPRegRHS;
  1155. dest = LHS & rhs;
  1156. WRITEDEST (dest);
  1157. }
  1158. break;
  1159. case 0x01: /* ANDS reg and MULS */
  1160. #ifdef MODET
  1161. if ((BITS (4, 11) & 0xF9) == 0x9)
  1162. /* LDR register offset, no write-back, down, post indexed. */
  1163. LHPOSTDOWN ();
  1164. /* Fall through to rest of decoding. */
  1165. #endif
  1166. if (BITS (4, 7) == 9) {
  1167. /* MULS */
  1168. rhs = state->Reg[MULRHSReg];
  1169. //if (MULLHSReg == MULDESTReg) {
  1170. if(0) {
  1171. printf("Something in %d line\n", __LINE__);
  1172. UNDEF_WARNING;
  1173. UNDEF_MULDestEQOp1;
  1174. state->Reg[MULDESTReg] = 0;
  1175. CLEARN;
  1176. SETZ;
  1177. } else if (MULDESTReg != 15) {
  1178. dest = state->Reg[MULLHSReg] * rhs;
  1179. ARMul_NegZero (state, dest);
  1180. state->Reg[MULDESTReg] = dest;
  1181. } else
  1182. UNDEF_MULPCDest;
  1183. for (dest = 0, temp = 0; dest < 32;
  1184. dest++)
  1185. if (rhs & (1L << dest))
  1186. temp = dest;
  1187. /* Mult takes this many/2 I cycles. */
  1188. ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
  1189. } else {
  1190. /* ANDS reg. */
  1191. rhs = DPSRegRHS;
  1192. dest = LHS & rhs;
  1193. WRITESDEST (dest);
  1194. }
  1195. break;
  1196. case 0x02: /* EOR reg and MLA */
  1197. #ifdef MODET
  1198. if (BITS (4, 11) == 0xB) {
  1199. /* STRH register offset, write-back, down, post indexed. */
  1200. SHDOWNWB ();
  1201. break;
  1202. }
  1203. #endif
  1204. if (BITS (4, 7) == 9) { /* MLA */
  1205. rhs = state->Reg[MULRHSReg];
  1206. #if 0
  1207. if (MULLHSReg == MULDESTReg) {
  1208. UNDEF_MULDestEQOp1;
  1209. state->Reg[MULDESTReg] = state->Reg[MULACCReg];
  1210. } else if (MULDESTReg != 15) {
  1211. #endif
  1212. if (MULDESTReg != 15) {
  1213. state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
  1214. } else
  1215. UNDEF_MULPCDest;
  1216. for (dest = 0, temp = 0; dest < 32;
  1217. dest++)
  1218. if (rhs & (1L << dest))
  1219. temp = dest;
  1220. /* Mult takes this many/2 I cycles. */
  1221. ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
  1222. } else {
  1223. rhs = DPRegRHS;
  1224. dest = LHS ^ rhs;
  1225. WRITEDEST (dest);
  1226. }
  1227. break;
  1228. case 0x03: /* EORS reg and MLAS */
  1229. #ifdef MODET
  1230. if ((BITS (4, 11) & 0xF9) == 0x9)
  1231. /* LDR register offset, write-back, down, post-indexed. */
  1232. LHPOSTDOWN ();
  1233. /* Fall through to rest of the decoding. */
  1234. #endif
  1235. if (BITS (4, 7) == 9) {
  1236. /* MLAS */
  1237. rhs = state->Reg[MULRHSReg];
  1238. //if (MULLHSReg == MULDESTReg) {
  1239. if (0) {
  1240. UNDEF_MULDestEQOp1;
  1241. dest = state->Reg[MULACCReg];
  1242. ARMul_NegZero (state, dest);
  1243. state->Reg[MULDESTReg] = dest;
  1244. } else if (MULDESTReg != 15) {
  1245. dest = state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
  1246. ARMul_NegZero (state, dest);
  1247. state->Reg[MULDESTReg] = dest;
  1248. } else
  1249. UNDEF_MULPCDest;
  1250. for (dest = 0, temp = 0; dest < 32;
  1251. dest++)
  1252. if (rhs & (1L << dest))
  1253. temp = dest;
  1254. /* Mult takes this many/2 I cycles. */
  1255. ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
  1256. } else {
  1257. /* EORS Reg. */
  1258. rhs = DPSRegRHS;
  1259. dest = LHS ^ rhs;
  1260. WRITESDEST (dest);
  1261. }
  1262. break;
  1263. case 0x04: /* SUB reg */
  1264. // Signifies UMAAL
  1265. if (state->is_v6 && BITS(4, 7) == 0x09) {
  1266. if (handle_v6_insn(state, instr))
  1267. break;
  1268. }
  1269. #ifdef MODET
  1270. if (BITS (4, 7) == 0xB) {
  1271. /* STRH immediate offset, no write-back, down, post indexed. */
  1272. SHDOWNWB ();
  1273. break;
  1274. }
  1275. if (BITS (4, 7) == 0xD) {
  1276. Handle_Load_Double (state, instr);
  1277. break;
  1278. }
  1279. if (BITS (4, 7) == 0xF) {
  1280. Handle_Store_Double (state, instr);
  1281. break;
  1282. }
  1283. #endif
  1284. rhs = DPRegRHS;
  1285. dest = LHS - rhs;
  1286. WRITEDEST (dest);
  1287. break;
  1288. case 0x05: /* SUBS reg */
  1289. #ifdef MODET
  1290. if ((BITS (4, 7) & 0x9) == 0x9)
  1291. /* LDR immediate offset, no write-back, down, post indexed. */
  1292. LHPOSTDOWN ();
  1293. /* Fall through to the rest of the instruction decoding. */
  1294. #endif
  1295. lhs = LHS;
  1296. rhs = DPRegRHS;
  1297. dest = lhs - rhs;
  1298. if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
  1299. ARMul_SubCarry (state, lhs, rhs, dest);
  1300. ARMul_SubOverflow (state, lhs, rhs, dest);
  1301. } else {
  1302. CLEARC;
  1303. CLEARV;
  1304. }
  1305. WRITESDEST (dest);
  1306. break;
  1307. case 0x06: /* RSB reg */
  1308. #ifdef MODET
  1309. if (BITS (4, 7) == 0xB) {
  1310. /* STRH immediate offset, write-back, down, post indexed. */
  1311. SHDOWNWB ();
  1312. break;
  1313. }
  1314. #endif
  1315. rhs = DPRegRHS;
  1316. dest = rhs - LHS;
  1317. WRITEDEST (dest);
  1318. break;
  1319. case 0x07: /* RSBS reg */
  1320. #ifdef MODET
  1321. if ((BITS (4, 7) & 0x9) == 0x9)
  1322. /* LDR immediate offset, write-back, down, post indexed. */
  1323. LHPOSTDOWN ();
  1324. /* Fall through to remainder of instruction decoding. */
  1325. #endif
  1326. lhs = LHS;
  1327. rhs = DPRegRHS;
  1328. dest = rhs - lhs;
  1329. if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
  1330. ARMul_SubCarry (state, rhs, lhs, dest);
  1331. ARMul_SubOverflow (state, rhs, lhs, dest);
  1332. } else {
  1333. CLEARC;
  1334. CLEARV;
  1335. }
  1336. WRITESDEST (dest);
  1337. break;
  1338. case 0x08: /* ADD reg */
  1339. #ifdef MODET
  1340. if (BITS (4, 11) == 0xB) {
  1341. /* STRH register offset, no write-back, up, post indexed. */
  1342. SHUPWB ();
  1343. break;
  1344. }
  1345. if (BITS (4, 7) == 0xD) {
  1346. Handle_Load_Double (state, instr);
  1347. break;
  1348. }
  1349. if (BITS (4, 7) == 0xF) {
  1350. Handle_Store_Double (state, instr);
  1351. break;
  1352. }
  1353. #endif
  1354. #ifdef MODET
  1355. if (BITS (4, 7) == 0x9) {
  1356. /* MULL */
  1357. /* 32x32 = 64 */
  1358. ARMul_Icycles (state, Multiply64 (state, instr, LUNSIGNED, LDEFAULT), 0L);
  1359. break;
  1360. }
  1361. #endif
  1362. rhs = DPRegRHS;
  1363. dest = LHS + rhs;
  1364. WRITEDEST (dest);
  1365. break;
  1366. case 0x09: /* ADDS reg */
  1367. #ifdef MODET
  1368. if ((BITS (4, 11) & 0xF9) == 0x9)
  1369. /* LDR register offset, no write-back, up, post indexed. */
  1370. LHPOSTUP ();
  1371. /* Fall through to remaining instruction decoding. */
  1372. #endif
  1373. #ifdef MODET
  1374. if (BITS (4, 7) == 0x9) {
  1375. /* MULL */
  1376. /* 32x32=64 */
  1377. ARMul_Icycles (state, Multiply64 (state, instr, LUNSIGNED, LSCC), 0L);
  1378. break;
  1379. }
  1380. #endif
  1381. lhs = LHS;
  1382. rhs = DPRegRHS;
  1383. dest = lhs + rhs;
  1384. ASSIGNZ (dest == 0);
  1385. if ((lhs | rhs) >> 30) {
  1386. /* Possible C,V,N to set. */
  1387. ASSIGNN (NEG (dest));
  1388. ARMul_AddCarry (state, lhs, rhs, dest);
  1389. ARMul_AddOverflow (state, lhs, rhs, dest);
  1390. } else {
  1391. CLEARN;
  1392. CLEARC;
  1393. CLEARV;
  1394. }
  1395. WRITESDEST (dest);
  1396. break;
  1397. case 0x0a: /* ADC reg */
  1398. #ifdef MODET
  1399. if (BITS (4, 11) == 0xB) {
  1400. /* STRH register offset, write-back, up, post-indexed. */
  1401. SHUPWB ();
  1402. break;
  1403. }
  1404. if (BITS (4, 7) == 0x9) {
  1405. /* MULL */
  1406. /* 32x32=64 */
  1407. ARMul_Icycles (state, MultiplyAdd64 (state, instr, LUNSIGNED, LDEFAULT), 0L);
  1408. break;
  1409. }
  1410. #endif
  1411. rhs = DPRegRHS;
  1412. dest = LHS + rhs + CFLAG;
  1413. WRITEDEST (dest);
  1414. break;
  1415. case 0x0b: /* ADCS reg */
  1416. #ifdef MODET
  1417. if ((BITS (4, 11) & 0xF9) == 0x9)
  1418. /* LDR register offset, write-back, up, post indexed. */
  1419. LHPOSTUP ();
  1420. /* Fall through to remaining instruction decoding. */
  1421. if (BITS (4, 7) == 0x9) {
  1422. /* MULL */
  1423. /* 32x32=64 */
  1424. ARMul_Icycles (state, MultiplyAdd64 (state, instr, LUNSIGNED, LSCC), 0L);
  1425. break;
  1426. }
  1427. #endif
  1428. lhs = LHS;
  1429. rhs = DPRegRHS;
  1430. dest = lhs + rhs + CFLAG;
  1431. ASSIGNZ (dest == 0);
  1432. if ((lhs | rhs) >> 30) {
  1433. /* Possible C,V,N to set. */
  1434. ASSIGNN (NEG (dest));
  1435. ARMul_AddCarry (state, lhs, rhs, dest);
  1436. ARMul_AddOverflow (state, lhs, rhs, dest);
  1437. } else {
  1438. CLEARN;
  1439. CLEARC;
  1440. CLEARV;
  1441. }
  1442. WRITESDEST (dest);
  1443. break;
  1444. case 0x0c: /* SBC reg */
  1445. #ifdef MODET
  1446. if (BITS (4, 7) == 0xB) {
  1447. /* STRH immediate offset, no write-back, up post indexed. */
  1448. SHUPWB ();
  1449. break;
  1450. }
  1451. if (BITS (4, 7) == 0xD) {
  1452. Handle_Load_Double (state, instr);
  1453. break;
  1454. }
  1455. if (BITS (4, 7) == 0xF) {
  1456. Handle_Store_Double (state, instr);
  1457. break;
  1458. }
  1459. if (BITS (4, 7) == 0x9) {
  1460. /* MULL */
  1461. /* 32x32=64 */
  1462. ARMul_Icycles (state, Multiply64 (state, instr, LSIGNED, LDEFAULT), 0L);
  1463. break;
  1464. }
  1465. #endif
  1466. rhs = DPRegRHS;
  1467. dest = LHS - rhs - !CFLAG;
  1468. WRITEDEST (dest);
  1469. break;
  1470. case 0x0d: /* SBCS reg */
  1471. #ifdef MODET
  1472. if ((BITS (4, 7) & 0x9) == 0x9)
  1473. /* LDR immediate offset, no write-back, up, post indexed. */
  1474. LHPOSTUP ();
  1475. if (BITS (4, 7) == 0x9) {
  1476. /* MULL */
  1477. /* 32x32=64 */
  1478. ARMul_Icycles (state, Multiply64 (state, instr, LSIGNED, LSCC), 0L);
  1479. break;
  1480. }
  1481. #endif
  1482. lhs = LHS;
  1483. rhs = DPRegRHS;
  1484. dest = lhs - rhs - !CFLAG;
  1485. if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
  1486. ARMul_SubCarry (state, lhs, rhs, dest);
  1487. ARMul_SubOverflow (state, lhs, rhs, dest);
  1488. } else {
  1489. CLEARC;
  1490. CLEARV;
  1491. }
  1492. WRITESDEST (dest);
  1493. break;
  1494. case 0x0e: /* RSC reg */
  1495. #ifdef MODET
  1496. if (BITS (4, 7) == 0xB) {
  1497. /* STRH immediate offset, write-back, up, post indexed. */
  1498. SHUPWB ();
  1499. break;
  1500. }
  1501. if (BITS (4, 7) == 0x9) {
  1502. /* MULL */
  1503. /* 32x32=64 */
  1504. ARMul_Icycles (state, MultiplyAdd64 (state, instr, LSIGNED, LDEFAULT), 0L);
  1505. break;
  1506. }
  1507. #endif
  1508. rhs = DPRegRHS;
  1509. dest = rhs - LHS - !CFLAG;
  1510. WRITEDEST (dest);
  1511. break;
  1512. case 0x0f: /* RSCS reg */
  1513. #ifdef MODET
  1514. if ((BITS (4, 7) & 0x9) == 0x9)
  1515. /* LDR immediate offset, write-back, up, post indexed. */
  1516. LHPOSTUP ();
  1517. /* Fall through to remaining instruction decoding. */
  1518. if (BITS (4, 7) == 0x9) {
  1519. /* MULL */
  1520. /* 32x32=64 */
  1521. ARMul_Icycles (state, MultiplyAdd64 (state, instr, LSIGNED, LSCC), 0L);
  1522. break;
  1523. }
  1524. #endif
  1525. lhs = LHS;
  1526. rhs = DPRegRHS;
  1527. dest = rhs - lhs - !CFLAG;
  1528. if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
  1529. ARMul_SubCarry (state, rhs, lhs, dest);
  1530. ARMul_SubOverflow (state, rhs, lhs, dest);
  1531. } else {
  1532. CLEARC;
  1533. CLEARV;
  1534. }
  1535. WRITESDEST (dest);
  1536. break;
  1537. case 0x10: /* TST reg and MRS CPSR and SWP word. */
  1538. if (state->is_v5e) {
  1539. if (BIT (4) == 0 && BIT (7) == 1) {
  1540. /* ElSegundo SMLAxy insn. */
  1541. ARMword op1 = state->Reg[BITS (0, 3)];
  1542. ARMword op2 = state->Reg[BITS (8, 11)];
  1543. ARMword Rn = state->Reg[BITS (12, 15)];
  1544. if (BIT (5))
  1545. op1 >>= 16;
  1546. if (BIT (6))
  1547. op2 >>= 16;
  1548. op1 &= 0xFFFF;
  1549. op2 &= 0xFFFF;
  1550. if (op1 & 0x8000)
  1551. op1 -= 65536;
  1552. if (op2 & 0x8000)
  1553. op2 -= 65536;
  1554. op1 *= op2;
  1555. //printf("SMLA_INST:BB,op1=0x%x, op2=0x%x. Rn=0x%x\n", op1, op2, Rn);
  1556. if (AddOverflow(op1, Rn, op1 + Rn))
  1557. SETQ;
  1558. state->Reg[BITS (16, 19)] = op1 + Rn;
  1559. break;
  1560. }
  1561. if (BITS (4, 11) == 5) {
  1562. /* ElSegundo QADD insn. */
  1563. ARMword op1 = state->Reg[BITS (0, 3)];
  1564. ARMword op2 = state->Reg[BITS (16, 19)];
  1565. ARMword result = op1 + op2;
  1566. if (AddOverflow(op1, op2, result)) {
  1567. result = POS (result) ? 0x80000000 : 0x7fffffff;
  1568. SETQ;
  1569. }
  1570. state->Reg[BITS (12, 15)] = result;
  1571. break;
  1572. }
  1573. }
  1574. #ifdef MODET
  1575. if (BITS (4, 11) == 0xB) {
  1576. /* STRH register offset, no write-back, down, pre indexed. */
  1577. SHPREDOWN ();
  1578. break;
  1579. }
  1580. if (BITS (4, 7) == 0xD) {
  1581. Handle_Load_Double (state, instr);
  1582. break;
  1583. }
  1584. if (BITS (4, 7) == 0xF) {
  1585. Handle_Store_Double (state, instr);
  1586. break;
  1587. }
  1588. #endif
  1589. if (BITS (4, 11) == 9) {
  1590. /* SWP */
  1591. UNDEF_SWPPC;
  1592. temp = LHS;
  1593. BUSUSEDINCPCS;
  1594. #ifndef MODE32
  1595. if (VECTORACCESS (temp) || ADDREXCEPT (temp)) {
  1596. INTERNALABORT (temp);
  1597. (void) ARMul_LoadWordN (state, temp);
  1598. (void) ARMul_LoadWordN (state, temp);
  1599. } else
  1600. #endif
  1601. dest = ARMul_SwapWord (state, temp, state->Reg[RHSReg]);
  1602. if (temp & 3)
  1603. DEST = ARMul_Align (state, temp, dest);
  1604. else
  1605. DEST = dest;
  1606. if (state->abortSig || state->Aborted)
  1607. TAKEABORT;
  1608. } else if ((BITS (0, 11) == 0) && (LHSReg == 15)) { /* MRS CPSR */
  1609. UNDEF_MRSPC;
  1610. DEST = ARMul_GetCPSR(state);
  1611. } else {
  1612. UNDEF_Test;
  1613. }
  1614. break;
  1615. case 0x11: /* TSTP reg */
  1616. #ifdef MODET
  1617. if ((BITS (4, 11) & 0xF9) == 0x9)
  1618. /* LDR register offset, no write-back, down, pre indexed. */
  1619. LHPREDOWN ();
  1620. /* Continue with remaining instruction decode. */
  1621. #endif
  1622. if (DESTReg == 15) {
  1623. /* TSTP reg */
  1624. #ifdef MODE32
  1625. //chy 2006-02-15 if in user mode, can not set cpsr 0:23
  1626. //from p165 of ARMARM book
  1627. state->Cpsr = GETSPSR (state->Bank);
  1628. ARMul_CPSRAltered (state);
  1629. #else
  1630. rhs = DPRegRHS;
  1631. temp = LHS & rhs;
  1632. SETR15PSR (temp);
  1633. #endif
  1634. } else {
  1635. /* TST reg */
  1636. rhs = DPSRegRHS;
  1637. dest = LHS & rhs;
  1638. ARMul_NegZero (state, dest);
  1639. }
  1640. break;
  1641. case 0x12: /* TEQ reg and MSR reg to CPSR (ARM6). */
  1642. if (state->is_v5) {
  1643. if (BITS (4, 7) == 3) {
  1644. /* BLX(2) */
  1645. ARMword temp;
  1646. if (TFLAG)
  1647. temp = (pc + 2) | 1;
  1648. else
  1649. temp = pc + 4;
  1650. WriteR15Branch (state, state->Reg[RHSReg]);
  1651. state->Reg[14] = temp;
  1652. break;
  1653. }
  1654. }
  1655. if (state->is_v5e) {
  1656. if (BIT (4) == 0 && BIT (7) == 1 && (BIT (5) == 0 || BITS (12, 15) == 0)) {
  1657. /* ElSegundo SMLAWy/SMULWy insn. */
  1658. unsigned long long op1 = state->Reg[BITS (0, 3)];
  1659. unsigned long long op2 = state->Reg[BITS (8, 11)];
  1660. unsigned long long result;
  1661. if (BIT (6))
  1662. op2 >>= 16;
  1663. if (op1 & 0x80000000)
  1664. op1 -= 1ULL << 32;
  1665. op2 &= 0xFFFF;
  1666. if (op2 & 0x8000)
  1667. op2 -= 65536;
  1668. result = (op1 * op2) >> 16;
  1669. if (BIT (5) == 0) {
  1670. ARMword Rn = state->Reg[BITS(12, 15)];
  1671. if (AddOverflow((ARMword)result, Rn, (ARMword)(result + Rn)))
  1672. SETQ;
  1673. result += Rn;
  1674. }
  1675. state->Reg[BITS (16, 19)] = (ARMword)result;
  1676. break;
  1677. }
  1678. if (BITS (4, 11) == 5) {
  1679. /* ElSegundo QSUB insn. */
  1680. ARMword op1 = state->Reg[BITS (0, 3)];
  1681. ARMword op2 = state->Reg[BITS (16, 19)];
  1682. ARMword result = op1 - op2;
  1683. if (SubOverflow
  1684. (op1, op2, result)) {
  1685. result = POS (result) ? 0x80000000 : 0x7fffffff;
  1686. SETQ;
  1687. }
  1688. state->Reg[BITS (12, 15)] = result;
  1689. break;
  1690. }
  1691. }
  1692. #ifdef MODET
  1693. if (BITS (4, 11) == 0xB) {
  1694. /* STRH register offset, write-back, down, pre indexed. */
  1695. SHPREDOWNWB ();
  1696. break;
  1697. }
  1698. if (BITS (4, 27) == 0x12FFF1) {
  1699. /* BX */
  1700. WriteR15Branch (state, state->Reg[RHSReg]);
  1701. break;
  1702. }
  1703. if (BITS (4, 7) == 0xD) {
  1704. Handle_Load_Double (state, instr);
  1705. break;
  1706. }
  1707. if (BITS (4, 7) == 0xF) {
  1708. Handle_Store_Double (state, instr);
  1709. break;
  1710. }
  1711. #endif
  1712. if (state->is_v5) {
  1713. if (BITS (4, 7) == 0x7) {
  1714. //ARMword value;
  1715. //extern int SWI_vector_installed;
  1716. /* Hardware is allowed to optionally override this
  1717. instruction and treat it as a breakpoint. Since
  1718. this is a simulator not hardware, we take the position
  1719. that if a SWI vector was not installed, then an Abort
  1720. vector was probably not installed either, and so
  1721. normally this instruction would be ignored, even if an
  1722. Abort is generated. This is a bad thing, since GDB
  1723. uses this instruction for its breakpoints (at least in
  1724. Thumb mode it does). So intercept the instruction here
  1725. and generate a breakpoint SWI instead. */
  1726. /* Force the next instruction to be refetched. */
  1727. state->NextInstr = RESUME;
  1728. break;
  1729. }
  1730. }
  1731. if (DESTReg == 15) {
  1732. /* MSR reg to CPSR. */
  1733. UNDEF_MSRPC;
  1734. temp = DPRegRHS;
  1735. #ifdef MODET
  1736. /* Don't allow TBIT to be set by MSR. */
  1737. temp &= ~TBIT;
  1738. #endif
  1739. ARMul_FixCPSR (state, instr, temp);
  1740. } else
  1741. UNDEF_Test;
  1742. break;
  1743. case 0x13: /* TEQP reg */
  1744. #ifdef MODET
  1745. if ((BITS (4, 11) & 0xF9) == 0x9)
  1746. /* LDR register offset, write-back, down, pre indexed. */
  1747. LHPREDOWNWB ();
  1748. /* Continue with remaining instruction decode. */
  1749. #endif
  1750. if (DESTReg == 15) {
  1751. /* TEQP reg */
  1752. #ifdef MODE32
  1753. state->Cpsr = GETSPSR (state->Bank);
  1754. ARMul_CPSRAltered (state);
  1755. #else
  1756. rhs = DPRegRHS;
  1757. temp = LHS ^ rhs;
  1758. SETR15PSR (temp);
  1759. #endif
  1760. } else {
  1761. /* TEQ Reg. */
  1762. rhs = DPSRegRHS;
  1763. dest = LHS ^ rhs;
  1764. ARMul_NegZero (state, dest);
  1765. }
  1766. break;
  1767. case 0x14: /* CMP reg and MRS SPSR and SWP byte. */
  1768. if (state->is_v5e) {
  1769. if (BIT (4) == 0 && BIT (7) == 1) {
  1770. /* ElSegundo SMLALxy insn. */
  1771. unsigned long long op1 = state->Reg[BITS (0, 3)];
  1772. unsigned long long op2 = state->Reg[BITS (8, 11)];
  1773. unsigned long long dest;
  1774. //unsigned long long result;
  1775. if (BIT (5))
  1776. op1 >>= 16;
  1777. if (BIT (6))
  1778. op2 >>= 16;
  1779. op1 &= 0xFFFF;
  1780. if (op1 & 0x8000)
  1781. op1 -= 65536;
  1782. op2 &= 0xFFFF;
  1783. if (op2 & 0x8000)
  1784. op2 -= 65536;
  1785. dest = (unsigned long long) state->Reg[BITS (16, 19)] << 32;
  1786. dest |= state->Reg[BITS (12, 15)];
  1787. dest += op1 * op2;
  1788. state->Reg[BITS(12, 15)] = (ARMword)dest;
  1789. state->Reg[BITS(16, 19)] = (ARMword)(dest >> 32);
  1790. break;
  1791. }
  1792. if (BITS (4, 11) == 5) {
  1793. /* ElSegundo QDADD insn. */
  1794. ARMword op1 = state->Reg[BITS (0, 3)];
  1795. ARMword op2 = state->Reg[BITS (16, 19)];
  1796. ARMword op2d = op2 + op2;
  1797. ARMword result;
  1798. if (AddOverflow
  1799. (op2, op2, op2d)) {
  1800. SETQ;
  1801. op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
  1802. }
  1803. result = op1 + op2d;
  1804. if (AddOverflow(op1, op2d, result)) {
  1805. SETQ;
  1806. result = POS (result) ? 0x80000000 : 0x7fffffff;
  1807. }
  1808. state->Reg[BITS (12, 15)] = result;
  1809. break;
  1810. }
  1811. }
  1812. #ifdef MODET
  1813. if (BITS (4, 7) == 0xB) {
  1814. /* STRH immediate offset, no write-back, down, pre indexed. */
  1815. SHPREDOWN ();
  1816. break;
  1817. }
  1818. if (BITS (4, 7) == 0xD) {
  1819. Handle_Load_Double (state, instr);
  1820. break;
  1821. }
  1822. if (BITS (4, 7) == 0xF) {
  1823. Handle_Store_Double (state, instr);
  1824. break;
  1825. }
  1826. #endif
  1827. if (BITS (4, 11) == 9) {
  1828. /* SWP */
  1829. UNDEF_SWPPC;
  1830. temp = LHS;
  1831. BUSUSEDINCPCS;
  1832. #ifndef MODE32
  1833. if (VECTORACCESS (temp) || ADDREXCEPT (temp)) {
  1834. INTERNALABORT (temp);
  1835. (void) ARMul_LoadByte (state, temp);
  1836. (void) ARMul_LoadByte (state, temp);
  1837. } else
  1838. #endif
  1839. DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]);
  1840. if (state->abortSig || state->Aborted)
  1841. TAKEABORT;
  1842. } else if ((BITS (0, 11) == 0)
  1843. && (LHSReg == 15)) {
  1844. /* MRS SPSR */
  1845. UNDEF_MRSPC;
  1846. DEST = GETSPSR (state->Bank);
  1847. } else
  1848. UNDEF_Test;
  1849. break;
  1850. case 0x15: /* CMPP reg. */
  1851. #ifdef MODET
  1852. if ((BITS (4, 7) & 0x9) == 0x9)
  1853. /* LDR immediate offset, no write-back, down, pre indexed. */
  1854. LHPREDOWN ();
  1855. /* Continue with remaining instruction decode. */
  1856. #endif
  1857. if (DESTReg == 15) {
  1858. /* CMPP reg. */
  1859. #ifdef MODE32
  1860. state->Cpsr = GETSPSR (state->Bank);
  1861. ARMul_CPSRAltered (state);
  1862. #else
  1863. rhs = DPRegRHS;
  1864. temp = LHS - rhs;
  1865. SETR15PSR (temp);
  1866. #endif
  1867. } else {
  1868. /* CMP reg. */
  1869. lhs = LHS;
  1870. rhs = DPRegRHS;
  1871. dest = lhs - rhs;
  1872. ARMul_NegZero (state, dest);
  1873. if ((lhs >= rhs)
  1874. || ((rhs | lhs) >> 31)) {
  1875. ARMul_SubCarry (state, lhs, rhs, dest);
  1876. ARMul_SubOverflow (state, lhs, rhs, dest);
  1877. } else {
  1878. CLEARC;
  1879. CLEARV;
  1880. }
  1881. }
  1882. break;
  1883. case 0x16: /* CMN reg and MSR reg to SPSR */
  1884. if (state->is_v5e) {
  1885. if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0) {
  1886. /* ElSegundo SMULxy insn. */
  1887. ARMword op1 = state->Reg[BITS (0, 3)];
  1888. ARMword op2 = state->Reg[BITS (8, 11)];
  1889. ARMword Rn = state->Reg[BITS (12, 15)];
  1890. if (BIT (5))
  1891. op1 >>= 16;
  1892. if (BIT (6))
  1893. op2 >>= 16;
  1894. op1 &= 0xFFFF;
  1895. op2 &= 0xFFFF;
  1896. if (op1 & 0x8000)
  1897. op1 -= 65536;
  1898. if (op2 & 0x8000)
  1899. op2 -= 65536;
  1900. state->Reg[BITS (16, 19)] = op1 * op2;
  1901. break;
  1902. }
  1903. if (BITS (4, 11) == 5) {
  1904. /* ElSegundo QDSUB insn. */
  1905. ARMword op1 = state->Reg[BITS (0, 3)];
  1906. ARMword op2 = state->Reg[BITS (16, 19)];
  1907. ARMword op2d = op2 + op2;
  1908. ARMword result;
  1909. if (AddOverflow(op2, op2, op2d)) {
  1910. SETQ;
  1911. op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
  1912. }
  1913. result = op1 - op2d;
  1914. if (SubOverflow(op1, op2d, result)) {
  1915. SETQ;
  1916. result = POS (result) ? 0x80000000 : 0x7fffffff;
  1917. }
  1918. state->Reg[BITS (12, 15)] = result;
  1919. break;
  1920. }
  1921. }
  1922. if (state->is_v5) {
  1923. if (BITS (4, 11) == 0xF1
  1924. && BITS (16, 19) == 0xF) {
  1925. /* ARM5 CLZ insn. */
  1926. ARMword op1 = state->Reg[BITS (0, 3)];
  1927. int result = 32;
  1928. if (op1)
  1929. for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1)
  1930. result++;
  1931. state->Reg[BITS (12, 15)] = result;
  1932. break;
  1933. }
  1934. }
  1935. #ifdef MODET
  1936. if (BITS (4, 7) == 0xB) {
  1937. /* STRH immediate offset, write-back, down, pre indexed. */
  1938. SHPREDOWNWB ();
  1939. break;
  1940. }
  1941. if (BITS (4, 7) == 0xD) {
  1942. Handle_Load_Double (state, instr);
  1943. break;
  1944. }
  1945. if (BITS (4, 7) == 0xF) {
  1946. Handle_Store_Double (state, instr);
  1947. break;
  1948. }
  1949. #endif
  1950. if (DESTReg == 15) {
  1951. /* MSR */
  1952. UNDEF_MSRPC;
  1953. /*ARMul_FixSPSR (state, instr,
  1954. DPRegRHS);*/
  1955. } else {
  1956. UNDEF_Test;
  1957. }
  1958. break;
  1959. case 0x17: /* CMNP reg */
  1960. #ifdef MODET
  1961. if ((BITS (4, 7) & 0x9) == 0x9)
  1962. /* LDR immediate offset, write-back, down, pre indexed. */
  1963. LHPREDOWNWB ();
  1964. /* Continue with remaining instruction decoding. */
  1965. #endif
  1966. if (DESTReg == 15) {
  1967. #ifdef MODE32
  1968. state->Cpsr = GETSPSR (state->Bank);
  1969. ARMul_CPSRAltered (state);
  1970. #else
  1971. rhs = DPRegRHS;
  1972. temp = LHS + rhs;
  1973. SETR15PSR (temp);
  1974. #endif
  1975. break;
  1976. } else {
  1977. /* CMN reg. */
  1978. lhs = LHS;
  1979. rhs = DPRegRHS;
  1980. dest = lhs + rhs;
  1981. ASSIGNZ (dest == 0);
  1982. if ((lhs | rhs) >> 30) {
  1983. /* Possible C,V,N to set. */
  1984. ASSIGNN (NEG (dest));
  1985. ARMul_AddCarry (state, lhs, rhs, dest);
  1986. ARMul_AddOverflow (state, lhs, rhs, dest);
  1987. } else {
  1988. CLEARN;
  1989. CLEARC;
  1990. CLEARV;
  1991. }
  1992. }
  1993. break;
  1994. case 0x18: /* ORR reg */
  1995. #ifdef MODET
  1996. /* dyf add armv6 instr strex 2010.9.17 */
  1997. if (state->is_v6) {
  1998. if (BITS (4, 7) == 0x9)
  1999. if (handle_v6_insn (state, instr))
  2000. break;
  2001. }
  2002. if (BITS (4, 11) == 0xB) {
  2003. /* STRH register offset, no write-back, up, pre indexed. */
  2004. SHPREUP ();
  2005. break;
  2006. }
  2007. if (BITS (4, 7) == 0xD) {
  2008. Handle_Load_Double (state, instr);
  2009. break;
  2010. }
  2011. if (BITS (4, 7) == 0xF) {
  2012. Handle_Store_Double (state, instr);
  2013. break;
  2014. }
  2015. #endif
  2016. rhs = DPRegRHS;
  2017. dest = LHS | rhs;
  2018. WRITEDEST (dest);
  2019. break;
  2020. case 0x19: /* ORRS reg */
  2021. #ifdef MODET
  2022. /* dyf add armv6 instr ldrex */
  2023. if (state->is_v6) {
  2024. if (BITS (4, 7) == 0x9) {
  2025. if (handle_v6_insn (state, instr))
  2026. break;
  2027. }
  2028. }
  2029. if ((BITS (4, 11) & 0xF9) == 0x9)
  2030. /* LDR register offset, no write-back, up, pre indexed. */
  2031. LHPREUP ();
  2032. /* Continue with remaining instruction decoding. */
  2033. #endif
  2034. rhs = DPSRegRHS;
  2035. dest = LHS | rhs;
  2036. WRITESDEST (dest);
  2037. break;
  2038. case 0x1a: /* MOV reg */
  2039. #ifdef MODET
  2040. if (BITS (4, 11) == 0xB) {
  2041. /* STRH register offset, write-back, up, pre indexed. */
  2042. SHPREUPWB ();
  2043. break;
  2044. }
  2045. if (BITS (4, 7) == 0xD) {
  2046. Handle_Load_Double (state, instr);
  2047. break;
  2048. }
  2049. if (BITS (4, 7) == 0xF) {
  2050. Handle_Store_Double (state, instr);
  2051. break;
  2052. }
  2053. if (BITS(4, 11) == 0xF9) { //strexd
  2054. u32 l = LHSReg;
  2055. bool enter = false;
  2056. if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr)&&
  2057. state->currentexvald == (u32)ARMul_ReadWord(state, state->currentexaddr + 4))
  2058. enter = true;
  2059. //todo bug this and STREXD and LDREXD http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360e/CHDGJGGC.html
  2060. if (enter) {
  2061. ARMul_StoreWordN(state, LHS, state->Reg[RHSReg]);
  2062. ARMul_StoreWordN(state,LHS + 4 , state->Reg[RHSReg + 1]);
  2063. state->Reg[DESTReg] = 0;
  2064. } else {
  2065. state->Reg[DESTReg] = 1;
  2066. }
  2067. break;
  2068. }
  2069. #endif
  2070. dest = DPRegRHS;
  2071. WRITEDEST (dest);
  2072. break;
  2073. case 0x1B: /* MOVS reg */
  2074. #ifdef MODET
  2075. /* ldrexd ichfly */
  2076. if (BITS(0, 11) == 0xF9F) { //strexd
  2077. lhs = LHS;
  2078. state->currentexaddr = lhs;
  2079. state->currentexval = (u32)ARMul_ReadWord(state, lhs);
  2080. state->currentexvald = (u32)ARMul_ReadWord(state, lhs + 4);
  2081. state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs);
  2082. state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs + 4);
  2083. break;
  2084. }
  2085. if ((BITS (4, 11) & 0xF9) == 0x9)
  2086. /* LDR register offset, write-back, up, pre indexed. */
  2087. LHPREUPWB ();
  2088. /* Continue with remaining instruction decoding. */
  2089. #endif
  2090. dest = DPSRegRHS;
  2091. WRITESDEST (dest);
  2092. break;
  2093. case 0x1c: /* BIC reg */
  2094. #ifdef MODET
  2095. /* dyf add for STREXB */
  2096. if (state->is_v6) {
  2097. if (BITS (4, 7) == 0x9) {
  2098. if (handle_v6_insn (state, instr))
  2099. break;
  2100. }
  2101. }
  2102. if (BITS (4, 7) == 0xB) {
  2103. /* STRH immediate offset, no write-back, up, pre indexed. */
  2104. SHPREUP ();
  2105. break;
  2106. }
  2107. if (BITS (4, 7) == 0xD) {
  2108. Handle_Load_Double (state, instr);
  2109. break;
  2110. } else if (BITS (4, 7) == 0xF) {
  2111. Handle_Store_Double (state, instr);
  2112. break;
  2113. }
  2114. #endif
  2115. rhs = DPRegRHS;
  2116. dest = LHS & ~rhs;
  2117. WRITEDEST (dest);
  2118. break;
  2119. case 0x1d: /* BICS reg */
  2120. #ifdef MODET
  2121. /* ladsh P=1 U=1 W=0 L=1 S=1 H=1 */
  2122. if (BITS(4, 7) == 0xF) {
  2123. temp = LHS + GetLS7RHS (state, instr);
  2124. LoadHalfWord (state, instr, temp, LSIGNED);
  2125. break;
  2126. }
  2127. if (BITS (4, 7) == 0xb) {
  2128. /* LDRH immediate offset, no write-back, up, pre indexed. */
  2129. temp = LHS + GetLS7RHS (state, instr);
  2130. LoadHalfWord (state, instr, temp, LUNSIGNED);
  2131. break;
  2132. }
  2133. if (BITS (4, 7) == 0xd) {
  2134. // alex-ykl fix: 2011-07-20 missing ldrsb instruction
  2135. temp = LHS + GetLS7RHS (state, instr);
  2136. LoadByte (state, instr, temp, LSIGNED);
  2137. break;
  2138. }
  2139. /* Continue with instruction decoding. */
  2140. /*if ((BITS (4, 7) & 0x9) == 0x9) */
  2141. if ((BITS (4, 7)) == 0x9) {
  2142. /* ldrexb */
  2143. if (state->is_v6) {
  2144. if (handle_v6_insn (state, instr))
  2145. break;
  2146. }
  2147. /* LDR immediate offset, no write-back, up, pre indexed. */
  2148. LHPREUP ();
  2149. }
  2150. #endif
  2151. rhs = DPSRegRHS;
  2152. dest = LHS & ~rhs;
  2153. WRITESDEST (dest);
  2154. break;
  2155. case 0x1e: /* MVN reg */
  2156. #ifdef MODET
  2157. if ((instr & 0x00000FF0) == 0x00000F90) { //if ((instr & 0x0FF00FF0) == 0x01e00f90) { //todo make that better ichfly
  2158. /* strexh ichfly */
  2159. u32 l = LHSReg;
  2160. u32 r = RHSReg;
  2161. lhs = LHS;
  2162. bool enter = false;
  2163. if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true;
  2164. //StoreWord(state, lhs, RHS)
  2165. if (state->Aborted) {
  2166. TAKEABORT;
  2167. }
  2168. if (enter) {
  2169. ARMul_StoreHalfWord(state, lhs, RHS);
  2170. state->Reg[DESTReg] = 0;
  2171. } else {
  2172. state->Reg[DESTReg] = 1;
  2173. }
  2174. break;
  2175. }
  2176. if (BITS (4, 7) == 0xB) {
  2177. /* STRH immediate offset, write-back, up, pre indexed. */
  2178. SHPREUPWB ();
  2179. break;
  2180. }
  2181. if (BITS (4, 7) == 0xD) {
  2182. Handle_Load_Double (state, instr);
  2183. break;
  2184. }
  2185. if (BITS (4, 7) == 0xF) {
  2186. Handle_Store_Double (state, instr);
  2187. break;
  2188. }
  2189. #endif
  2190. dest = ~DPRegRHS;
  2191. WRITEDEST (dest);
  2192. break;
  2193. case 0x1f: /* MVNS reg */
  2194. #ifdef MODET
  2195. if ((instr & 0x00000FF0) == 0x00000F90) { //(instr & 0x0FF00FF0) == 0x01f00f90)//if ((instr & 0x0FF00FF0) == 0x01f00f90) {
  2196. /* ldrexh ichfly */
  2197. lhs = LHS;
  2198. state->currentexaddr = lhs;
  2199. state->currentexval = (u32)ARMul_LoadHalfWord(state, lhs);
  2200. LoadHalfWord(state, instr, lhs,0);
  2201. break;
  2202. }
  2203. if ((BITS (4, 7) & 0x9) == 0x9)
  2204. /* LDR immediate offset, write-back, up, pre indexed. */
  2205. LHPREUPWB ();
  2206. /* Continue instruction decoding. */
  2207. #endif
  2208. dest = ~DPSRegRHS;
  2209. WRITESDEST (dest);
  2210. break;
  2211. /* Data Processing Immediate RHS Instructions. */
  2212. case 0x20: /* AND immed */
  2213. dest = LHS & DPImmRHS;
  2214. WRITEDEST (dest);
  2215. break;
  2216. case 0x21: /* ANDS immed */
  2217. DPSImmRHS;
  2218. dest = LHS & rhs;
  2219. WRITESDEST (dest);
  2220. break;
  2221. case 0x22: /* EOR immed */
  2222. dest = LHS ^ DPImmRHS;
  2223. WRITEDEST (dest);
  2224. break;
  2225. case 0x23: /* EORS immed */
  2226. DPSImmRHS;
  2227. dest = LHS ^ rhs;
  2228. WRITESDEST (dest);
  2229. break;
  2230. case 0x24: /* SUB immed */
  2231. dest = LHS - DPImmRHS;
  2232. WRITEDEST (dest);
  2233. break;
  2234. case 0x25: /* SUBS immed */
  2235. lhs = LHS;
  2236. rhs = DPImmRHS;
  2237. dest = lhs - rhs;
  2238. if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
  2239. ARMul_SubCarry (state, lhs, rhs, dest);
  2240. ARMul_SubOverflow (state, lhs, rhs, dest);
  2241. } else {
  2242. CLEARC;
  2243. CLEARV;
  2244. }
  2245. WRITESDEST (dest);
  2246. break;
  2247. case 0x26: /* RSB immed */
  2248. dest = DPImmRHS - LHS;
  2249. WRITEDEST (dest);
  2250. break;
  2251. case 0x27: /* RSBS immed */
  2252. lhs = LHS;
  2253. rhs = DPImmRHS;
  2254. dest = rhs - lhs;
  2255. if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
  2256. ARMul_SubCarry (state, rhs, lhs, dest);
  2257. ARMul_SubOverflow (state, rhs, lhs, dest);
  2258. } else {
  2259. CLEARC;
  2260. CLEARV;
  2261. }
  2262. WRITESDEST (dest);
  2263. break;
  2264. case 0x28: /* ADD immed */
  2265. dest = LHS + DPImmRHS;
  2266. WRITEDEST (dest);
  2267. break;
  2268. case 0x29: /* ADDS immed */
  2269. lhs = LHS;
  2270. rhs = DPImmRHS;
  2271. dest = lhs + rhs;
  2272. ASSIGNZ (dest == 0);
  2273. if ((lhs | rhs) >> 30) {
  2274. /* Possible C,V,N to set. */
  2275. ASSIGNN (NEG (dest));
  2276. ARMul_AddCarry (state, lhs, rhs, dest);
  2277. ARMul_AddOverflow (state, lhs, rhs, dest);
  2278. } else {
  2279. CLEARN;
  2280. CLEARC;
  2281. CLEARV;
  2282. }
  2283. WRITESDEST (dest);
  2284. break;
  2285. case 0x2a: /* ADC immed */
  2286. dest = LHS + DPImmRHS + CFLAG;
  2287. WRITEDEST (dest);
  2288. break;
  2289. case 0x2b: /* ADCS immed */
  2290. lhs = LHS;
  2291. rhs = DPImmRHS;
  2292. dest = lhs + rhs + CFLAG;
  2293. ASSIGNZ (dest == 0);
  2294. if ((lhs | rhs) >> 30) {
  2295. /* Possible C,V,N to set. */
  2296. ASSIGNN (NEG (dest));
  2297. ARMul_AddCarry (state, lhs, rhs, dest);
  2298. ARMul_AddOverflow (state, lhs, rhs, dest);
  2299. } else {
  2300. CLEARN;
  2301. CLEARC;
  2302. CLEARV;
  2303. }
  2304. WRITESDEST (dest);
  2305. break;
  2306. case 0x2c: /* SBC immed */
  2307. dest = LHS - DPImmRHS - !CFLAG;
  2308. WRITEDEST (dest);
  2309. break;
  2310. case 0x2d: /* SBCS immed */
  2311. lhs = LHS;
  2312. rhs = DPImmRHS;
  2313. dest = lhs - rhs - !CFLAG;
  2314. if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
  2315. ARMul_SubCarry (state, lhs, rhs, dest);
  2316. ARMul_SubOverflow (state, lhs, rhs, dest);
  2317. } else {
  2318. CLEARC;
  2319. CLEARV;
  2320. }
  2321. WRITESDEST (dest);
  2322. break;
  2323. case 0x2e: /* RSC immed */
  2324. dest = DPImmRHS - LHS - !CFLAG;
  2325. WRITEDEST (dest);
  2326. break;
  2327. case 0x2f: /* RSCS immed */
  2328. lhs = LHS;
  2329. rhs = DPImmRHS;
  2330. dest = rhs - lhs - !CFLAG;
  2331. if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
  2332. ARMul_SubCarry (state, rhs, lhs, dest);
  2333. ARMul_SubOverflow (state, rhs, lhs, dest);
  2334. } else {
  2335. CLEARC;
  2336. CLEARV;
  2337. }
  2338. WRITESDEST (dest);
  2339. break;
  2340. case 0x30: /* TST immed */
  2341. /* shenoubang 2012-3-14*/
  2342. if (state->is_v6) { /* movw, ARMV6, ARMv7 */
  2343. dest ^= dest;
  2344. dest = BITS(16, 19);
  2345. dest = ((dest<<12) | BITS(0, 11));
  2346. WRITEDEST(dest);
  2347. //SKYEYE_DBG("In %s, line = %d, pc = 0x%x, instr = 0x%x, R[0:11]: 0x%x, R[16:19]: 0x%x, R[%d]:0x%x\n",
  2348. // __func__, __LINE__, pc, instr, BITS(0, 11), BITS(16, 19), DESTReg, state->Reg[DESTReg]);
  2349. break;
  2350. } else {
  2351. UNDEF_Test;
  2352. break;
  2353. }
  2354. case 0x31: /* TSTP immed */
  2355. if (DESTReg == 15) {
  2356. /* TSTP immed. */
  2357. #ifdef MODE32
  2358. state->Cpsr = GETSPSR (state->Bank);
  2359. ARMul_CPSRAltered (state);
  2360. #else
  2361. temp = LHS & DPImmRHS;
  2362. SETR15PSR (temp);
  2363. #endif
  2364. } else {
  2365. /* TST immed. */
  2366. DPSImmRHS;
  2367. dest = LHS & rhs;
  2368. ARMul_NegZero (state, dest);
  2369. }
  2370. break;
  2371. case 0x32: /* TEQ immed and MSR immed to CPSR */
  2372. if (DESTReg == 15)
  2373. /* MSR immed to CPSR. */
  2374. ARMul_FixCPSR (state, instr,
  2375. DPImmRHS);
  2376. else
  2377. UNDEF_Test;
  2378. break;
  2379. case 0x33: /* TEQP immed */
  2380. if (DESTReg == 15) {
  2381. /* TEQP immed. */
  2382. #ifdef MODE32
  2383. state->Cpsr = GETSPSR (state->Bank);
  2384. ARMul_CPSRAltered (state);
  2385. #else
  2386. temp = LHS ^ DPImmRHS;
  2387. SETR15PSR (temp);
  2388. #endif
  2389. } else {
  2390. DPSImmRHS; /* TEQ immed */
  2391. dest = LHS ^ rhs;
  2392. ARMul_NegZero (state, dest);
  2393. }
  2394. break;
  2395. case 0x34: /* CMP immed */
  2396. UNDEF_Test;
  2397. break;
  2398. case 0x35: /* CMPP immed */
  2399. if (DESTReg == 15) {
  2400. /* CMPP immed. */
  2401. #ifdef MODE32
  2402. state->Cpsr = GETSPSR (state->Bank);
  2403. ARMul_CPSRAltered (state);
  2404. #else
  2405. temp = LHS - DPImmRHS;
  2406. SETR15PSR (temp);
  2407. #endif
  2408. break;
  2409. } else {
  2410. /* CMP immed. */
  2411. lhs = LHS;
  2412. rhs = DPImmRHS;
  2413. dest = lhs - rhs;
  2414. ARMul_NegZero (state, dest);
  2415. if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
  2416. ARMul_SubCarry (state, lhs, rhs, dest);
  2417. ARMul_SubOverflow (state, lhs, rhs, dest);
  2418. } else {
  2419. CLEARC;
  2420. CLEARV;
  2421. }
  2422. }
  2423. break;
  2424. case 0x36: /* CMN immed and MSR immed to SPSR */
  2425. //if (DESTReg == 15)
  2426. /*ARMul0_FixSPSR (state, instr,
  2427. DPImmRHS);*/
  2428. //else
  2429. UNDEF_Test;
  2430. break;
  2431. case 0x37: /* CMNP immed. */
  2432. if (DESTReg == 15) {
  2433. /* CMNP immed. */
  2434. #ifdef MODE32
  2435. state->Cpsr = GETSPSR (state->Bank);
  2436. ARMul_CPSRAltered (state);
  2437. #else
  2438. temp = LHS + DPImmRHS;
  2439. SETR15PSR (temp);
  2440. #endif
  2441. break;
  2442. } else {
  2443. /* CMN immed. */
  2444. lhs = LHS;
  2445. rhs = DPImmRHS;
  2446. dest = lhs + rhs;
  2447. ASSIGNZ (dest == 0);
  2448. if ((lhs | rhs) >> 30) {
  2449. /* Possible C,V,N to set. */
  2450. ASSIGNN (NEG (dest));
  2451. ARMul_AddCarry (state, lhs, rhs, dest);
  2452. ARMul_AddOverflow (state, lhs, rhs, dest);
  2453. } else {
  2454. CLEARN;
  2455. CLEARC;
  2456. CLEARV;
  2457. }
  2458. }
  2459. break;
  2460. case 0x38: /* ORR immed. */
  2461. dest = LHS | DPImmRHS;
  2462. WRITEDEST (dest);
  2463. break;
  2464. case 0x39: /* ORRS immed. */
  2465. DPSImmRHS;
  2466. dest = LHS | rhs;
  2467. WRITESDEST (dest);
  2468. break;
  2469. case 0x3a: /* MOV immed. */
  2470. dest = DPImmRHS;
  2471. WRITEDEST (dest);
  2472. break;
  2473. case 0x3b: /* MOVS immed. */
  2474. DPSImmRHS;
  2475. WRITESDEST (rhs);
  2476. break;
  2477. case 0x3c: /* BIC immed. */
  2478. dest = LHS & ~DPImmRHS;
  2479. WRITEDEST (dest);
  2480. break;
  2481. case 0x3d: /* BICS immed. */
  2482. DPSImmRHS;
  2483. dest = LHS & ~rhs;
  2484. WRITESDEST (dest);
  2485. break;
  2486. case 0x3e: /* MVN immed. */
  2487. dest = ~DPImmRHS;
  2488. WRITEDEST (dest);
  2489. break;
  2490. case 0x3f: /* MVNS immed. */
  2491. DPSImmRHS;
  2492. WRITESDEST (~rhs);
  2493. break;
  2494. /* Single Data Transfer Immediate RHS Instructions. */
  2495. case 0x40: /* Store Word, No WriteBack, Post Dec, Immed. */
  2496. lhs = LHS;
  2497. if (StoreWord (state, instr, lhs))
  2498. LSBase = lhs - LSImmRHS;
  2499. break;
  2500. case 0x41: /* Load Word, No WriteBack, Post Dec, Immed. */
  2501. lhs = LHS;
  2502. if (LoadWord (state, instr, lhs))
  2503. LSBase = lhs - LSImmRHS;
  2504. break;
  2505. case 0x42: /* Store Word, WriteBack, Post Dec, Immed. */
  2506. UNDEF_LSRBaseEQDestWb;
  2507. UNDEF_LSRPCBaseWb;
  2508. lhs = LHS;
  2509. temp = lhs - LSImmRHS;
  2510. state->NtransSig = LOW;
  2511. if (StoreWord (state, instr, lhs))
  2512. LSBase = temp;
  2513. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2514. break;
  2515. case 0x43: /* Load Word, WriteBack, Post Dec, Immed. */
  2516. UNDEF_LSRBaseEQDestWb;
  2517. UNDEF_LSRPCBaseWb;
  2518. lhs = LHS;
  2519. state->NtransSig = LOW;
  2520. if (LoadWord (state, instr, lhs))
  2521. LSBase = lhs - LSImmRHS;
  2522. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2523. break;
  2524. case 0x44: /* Store Byte, No WriteBack, Post Dec, Immed. */
  2525. lhs = LHS;
  2526. if (StoreByte (state, instr, lhs))
  2527. LSBase = lhs - LSImmRHS;
  2528. break;
  2529. case 0x45: /* Load Byte, No WriteBack, Post Dec, Immed. */
  2530. lhs = LHS;
  2531. if (LoadByte (state, instr, lhs, LUNSIGNED))
  2532. LSBase = lhs - LSImmRHS;
  2533. break;
  2534. case 0x46: /* Store Byte, WriteBack, Post Dec, Immed. */
  2535. UNDEF_LSRBaseEQDestWb;
  2536. UNDEF_LSRPCBaseWb;
  2537. lhs = LHS;
  2538. state->NtransSig = LOW;
  2539. if (StoreByte (state, instr, lhs))
  2540. LSBase = lhs - LSImmRHS;
  2541. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2542. break;
  2543. case 0x47: /* Load Byte, WriteBack, Post Dec, Immed. */
  2544. UNDEF_LSRBaseEQDestWb;
  2545. UNDEF_LSRPCBaseWb;
  2546. lhs = LHS;
  2547. state->NtransSig = LOW;
  2548. if (LoadByte (state, instr, lhs, LUNSIGNED))
  2549. LSBase = lhs - LSImmRHS;
  2550. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2551. break;
  2552. case 0x48: /* Store Word, No WriteBack, Post Inc, Immed. */
  2553. lhs = LHS;
  2554. if (StoreWord (state, instr, lhs))
  2555. LSBase = lhs + LSImmRHS;
  2556. break;
  2557. case 0x49: /* Load Word, No WriteBack, Post Inc, Immed. */
  2558. lhs = LHS;
  2559. if (LoadWord (state, instr, lhs))
  2560. LSBase = lhs + LSImmRHS;
  2561. break;
  2562. case 0x4a: /* Store Word, WriteBack, Post Inc, Immed. */
  2563. UNDEF_LSRBaseEQDestWb;
  2564. UNDEF_LSRPCBaseWb;
  2565. lhs = LHS;
  2566. state->NtransSig = LOW;
  2567. if (StoreWord (state, instr, lhs))
  2568. LSBase = lhs + LSImmRHS;
  2569. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2570. break;
  2571. case 0x4b: /* Load Word, WriteBack, Post Inc, Immed. */
  2572. UNDEF_LSRBaseEQDestWb;
  2573. UNDEF_LSRPCBaseWb;
  2574. lhs = LHS;
  2575. state->NtransSig = LOW;
  2576. if (LoadWord (state, instr, lhs))
  2577. LSBase = lhs + LSImmRHS;
  2578. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2579. break;
  2580. case 0x4c: /* Store Byte, No WriteBack, Post Inc, Immed. */
  2581. lhs = LHS;
  2582. if (StoreByte (state, instr, lhs))
  2583. LSBase = lhs + LSImmRHS;
  2584. break;
  2585. case 0x4d: /* Load Byte, No WriteBack, Post Inc, Immed. */
  2586. lhs = LHS;
  2587. if (LoadByte (state, instr, lhs, LUNSIGNED))
  2588. LSBase = lhs + LSImmRHS;
  2589. break;
  2590. case 0x4e: /* Store Byte, WriteBack, Post Inc, Immed. */
  2591. UNDEF_LSRBaseEQDestWb;
  2592. UNDEF_LSRPCBaseWb;
  2593. lhs = LHS;
  2594. state->NtransSig = LOW;
  2595. if (StoreByte (state, instr, lhs))
  2596. LSBase = lhs + LSImmRHS;
  2597. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2598. break;
  2599. case 0x4f: /* Load Byte, WriteBack, Post Inc, Immed. */
  2600. UNDEF_LSRBaseEQDestWb;
  2601. UNDEF_LSRPCBaseWb;
  2602. lhs = LHS;
  2603. state->NtransSig = LOW;
  2604. if (LoadByte (state, instr, lhs, LUNSIGNED))
  2605. LSBase = lhs + LSImmRHS;
  2606. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2607. break;
  2608. case 0x50: /* Store Word, No WriteBack, Pre Dec, Immed. */
  2609. (void) StoreWord (state, instr, LHS - LSImmRHS);
  2610. break;
  2611. case 0x51: /* Load Word, No WriteBack, Pre Dec, Immed. */
  2612. (void) LoadWord (state, instr, LHS - LSImmRHS);
  2613. break;
  2614. case 0x52: /* Store Word, WriteBack, Pre Dec, Immed. */
  2615. UNDEF_LSRBaseEQDestWb;
  2616. UNDEF_LSRPCBaseWb;
  2617. temp = LHS - LSImmRHS;
  2618. if (StoreWord (state, instr, temp))
  2619. LSBase = temp;
  2620. break;
  2621. case 0x53: /* Load Word, WriteBack, Pre Dec, Immed. */
  2622. UNDEF_LSRBaseEQDestWb;
  2623. UNDEF_LSRPCBaseWb;
  2624. temp = LHS - LSImmRHS;
  2625. if (LoadWord (state, instr, temp))
  2626. LSBase = temp;
  2627. break;
  2628. case 0x54: /* Store Byte, No WriteBack, Pre Dec, Immed. */
  2629. (void) StoreByte (state, instr, LHS - LSImmRHS);
  2630. break;
  2631. case 0x55: /* Load Byte, No WriteBack, Pre Dec, Immed. */
  2632. (void) LoadByte (state, instr, LHS - LSImmRHS, LUNSIGNED);
  2633. break;
  2634. case 0x56: /* Store Byte, WriteBack, Pre Dec, Immed. */
  2635. UNDEF_LSRBaseEQDestWb;
  2636. UNDEF_LSRPCBaseWb;
  2637. temp = LHS - LSImmRHS;
  2638. if (StoreByte (state, instr, temp))
  2639. LSBase = temp;
  2640. break;
  2641. case 0x57: /* Load Byte, WriteBack, Pre Dec, Immed. */
  2642. UNDEF_LSRBaseEQDestWb;
  2643. UNDEF_LSRPCBaseWb;
  2644. temp = LHS - LSImmRHS;
  2645. if (LoadByte (state, instr, temp, LUNSIGNED))
  2646. LSBase = temp;
  2647. break;
  2648. case 0x58: /* Store Word, No WriteBack, Pre Inc, Immed. */
  2649. (void) StoreWord (state, instr, LHS + LSImmRHS);
  2650. break;
  2651. case 0x59: /* Load Word, No WriteBack, Pre Inc, Immed. */
  2652. (void) LoadWord (state, instr, LHS + LSImmRHS);
  2653. break;
  2654. case 0x5a: /* Store Word, WriteBack, Pre Inc, Immed. */
  2655. UNDEF_LSRBaseEQDestWb;
  2656. UNDEF_LSRPCBaseWb;
  2657. temp = LHS + LSImmRHS;
  2658. if (StoreWord (state, instr, temp))
  2659. LSBase = temp;
  2660. break;
  2661. case 0x5b: /* Load Word, WriteBack, Pre Inc, Immed. */
  2662. UNDEF_LSRBaseEQDestWb;
  2663. UNDEF_LSRPCBaseWb;
  2664. temp = LHS + LSImmRHS;
  2665. if (LoadWord (state, instr, temp))
  2666. LSBase = temp;
  2667. break;
  2668. case 0x5c: /* Store Byte, No WriteBack, Pre Inc, Immed. */
  2669. (void) StoreByte (state, instr, LHS + LSImmRHS);
  2670. break;
  2671. case 0x5d: /* Load Byte, No WriteBack, Pre Inc, Immed. */
  2672. (void) LoadByte (state, instr, LHS + LSImmRHS, LUNSIGNED);
  2673. break;
  2674. case 0x5e: /* Store Byte, WriteBack, Pre Inc, Immed. */
  2675. UNDEF_LSRBaseEQDestWb;
  2676. UNDEF_LSRPCBaseWb;
  2677. temp = LHS + LSImmRHS;
  2678. if (StoreByte (state, instr, temp))
  2679. LSBase = temp;
  2680. break;
  2681. case 0x5f: /* Load Byte, WriteBack, Pre Inc, Immed. */
  2682. UNDEF_LSRBaseEQDestWb;
  2683. UNDEF_LSRPCBaseWb;
  2684. temp = LHS + LSImmRHS;
  2685. if (LoadByte (state, instr, temp, LUNSIGNED))
  2686. LSBase = temp;
  2687. break;
  2688. /* Single Data Transfer Register RHS Instructions. */
  2689. case 0x60: /* Store Word, No WriteBack, Post Dec, Reg. */
  2690. if (BIT (4)) {
  2691. ARMul_UndefInstr (state, instr);
  2692. break;
  2693. }
  2694. UNDEF_LSRBaseEQOffWb;
  2695. UNDEF_LSRBaseEQDestWb;
  2696. UNDEF_LSRPCBaseWb;
  2697. UNDEF_LSRPCOffWb;
  2698. lhs = LHS;
  2699. if (StoreWord (state, instr, lhs))
  2700. LSBase = lhs - LSRegRHS;
  2701. break;
  2702. case 0x61: /* Load Word, No WriteBack, Post Dec, Reg. */
  2703. if (BIT (4)) {
  2704. #ifdef MODE32
  2705. if (state->is_v6 && handle_v6_insn (state, instr))
  2706. break;
  2707. #endif
  2708. ARMul_UndefInstr (state, instr);
  2709. break;
  2710. }
  2711. UNDEF_LSRBaseEQOffWb;
  2712. UNDEF_LSRBaseEQDestWb;
  2713. UNDEF_LSRPCBaseWb;
  2714. UNDEF_LSRPCOffWb;
  2715. lhs = LHS;
  2716. temp = lhs - LSRegRHS;
  2717. if (LoadWord (state, instr, lhs))
  2718. LSBase = temp;
  2719. break;
  2720. case 0x62: /* Store Word, WriteBack, Post Dec, Reg. */
  2721. if (BIT (4)) {
  2722. #ifdef MODE32
  2723. if (state->is_v6 && handle_v6_insn (state, instr))
  2724. break;
  2725. #endif
  2726. ARMul_UndefInstr (state, instr);
  2727. break;
  2728. }
  2729. UNDEF_LSRBaseEQOffWb;
  2730. UNDEF_LSRBaseEQDestWb;
  2731. UNDEF_LSRPCBaseWb;
  2732. UNDEF_LSRPCOffWb;
  2733. lhs = LHS;
  2734. state->NtransSig = LOW;
  2735. if (StoreWord (state, instr, lhs))
  2736. LSBase = lhs - LSRegRHS;
  2737. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2738. break;
  2739. case 0x63: /* Load Word, WriteBack, Post Dec, Reg. */
  2740. if (BIT (4)) {
  2741. #ifdef MODE32
  2742. if (state->is_v6 && handle_v6_insn (state, instr))
  2743. break;
  2744. #endif
  2745. ARMul_UndefInstr (state, instr);
  2746. break;
  2747. }
  2748. UNDEF_LSRBaseEQOffWb;
  2749. UNDEF_LSRBaseEQDestWb;
  2750. UNDEF_LSRPCBaseWb;
  2751. UNDEF_LSRPCOffWb;
  2752. lhs = LHS;
  2753. temp = lhs - LSRegRHS;
  2754. state->NtransSig = LOW;
  2755. if (LoadWord (state, instr, lhs))
  2756. LSBase = temp;
  2757. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2758. break;
  2759. case 0x64: /* Store Byte, No WriteBack, Post Dec, Reg. */
  2760. if (BIT (4)) {
  2761. ARMul_UndefInstr (state, instr);
  2762. break;
  2763. }
  2764. UNDEF_LSRBaseEQOffWb;
  2765. UNDEF_LSRBaseEQDestWb;
  2766. UNDEF_LSRPCBaseWb;
  2767. UNDEF_LSRPCOffWb;
  2768. lhs = LHS;
  2769. if (StoreByte (state, instr, lhs))
  2770. LSBase = lhs - LSRegRHS;
  2771. break;
  2772. case 0x65: /* Load Byte, No WriteBack, Post Dec, Reg. */
  2773. if (BIT (4)) {
  2774. #ifdef MODE32
  2775. if (state->is_v6 && handle_v6_insn (state, instr))
  2776. break;
  2777. #endif
  2778. ARMul_UndefInstr (state, instr);
  2779. break;
  2780. }
  2781. UNDEF_LSRBaseEQOffWb;
  2782. UNDEF_LSRBaseEQDestWb;
  2783. UNDEF_LSRPCBaseWb;
  2784. UNDEF_LSRPCOffWb;
  2785. lhs = LHS;
  2786. temp = lhs - LSRegRHS;
  2787. if (LoadByte (state, instr, lhs, LUNSIGNED))
  2788. LSBase = temp;
  2789. break;
  2790. case 0x66: /* Store Byte, WriteBack, Post Dec, Reg. */
  2791. if (BIT (4)) {
  2792. #ifdef MODE32
  2793. if (state->is_v6 && handle_v6_insn (state, instr))
  2794. break;
  2795. #endif
  2796. ARMul_UndefInstr (state, instr);
  2797. break;
  2798. }
  2799. UNDEF_LSRBaseEQOffWb;
  2800. UNDEF_LSRBaseEQDestWb;
  2801. UNDEF_LSRPCBaseWb;
  2802. UNDEF_LSRPCOffWb;
  2803. lhs = LHS;
  2804. state->NtransSig = LOW;
  2805. if (StoreByte (state, instr, lhs))
  2806. LSBase = lhs - LSRegRHS;
  2807. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2808. break;
  2809. case 0x67: /* Load Byte, WriteBack, Post Dec, Reg. */
  2810. if (BIT (4)) {
  2811. #ifdef MODE32
  2812. if (state->is_v6
  2813. && handle_v6_insn (state, instr))
  2814. break;
  2815. #endif
  2816. ARMul_UndefInstr (state, instr);
  2817. break;
  2818. }
  2819. UNDEF_LSRBaseEQOffWb;
  2820. UNDEF_LSRBaseEQDestWb;
  2821. UNDEF_LSRPCBaseWb;
  2822. UNDEF_LSRPCOffWb;
  2823. lhs = LHS;
  2824. temp = lhs - LSRegRHS;
  2825. state->NtransSig = LOW;
  2826. if (LoadByte (state, instr, lhs, LUNSIGNED))
  2827. LSBase = temp;
  2828. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2829. break;
  2830. case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
  2831. if ((instr & 0x70) == 0x10) { //pkhbt
  2832. u8 idest = BITS(12, 15);
  2833. u8 rfis = BITS(16, 19);
  2834. u8 rlast = BITS(0, 3);
  2835. u8 ishi = BITS(7,11);
  2836. state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000);
  2837. break;
  2838. } else if ((instr & 0x70) == 0x50) { //pkhtb
  2839. u8 rd_idx = BITS(12, 15);
  2840. u8 rn_idx = BITS(16, 19);
  2841. u8 rm_idx = BITS(0, 3);
  2842. u8 imm5 = BITS(7, 11) ? BITS(7, 11) : 31;
  2843. state->Reg[rd_idx] = ((static_cast<s32>(state->Reg[rm_idx]) >> imm5) & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000);
  2844. break;
  2845. } else if (BIT (4)) {
  2846. #ifdef MODE32
  2847. if (state->is_v6
  2848. && handle_v6_insn (state, instr))
  2849. break;
  2850. #endif
  2851. ARMul_UndefInstr (state, instr);
  2852. break;
  2853. }
  2854. UNDEF_LSRBaseEQOffWb;
  2855. UNDEF_LSRBaseEQDestWb;
  2856. UNDEF_LSRPCBaseWb;
  2857. UNDEF_LSRPCOffWb;
  2858. lhs = LHS;
  2859. if (StoreWord (state, instr, lhs))
  2860. LSBase = lhs + LSRegRHS;
  2861. break;
  2862. case 0x69: /* Load Word, No WriteBack, Post Inc, Reg. */
  2863. if (BIT (4)) {
  2864. ARMul_UndefInstr (state, instr);
  2865. break;
  2866. }
  2867. UNDEF_LSRBaseEQOffWb;
  2868. UNDEF_LSRBaseEQDestWb;
  2869. UNDEF_LSRPCBaseWb;
  2870. UNDEF_LSRPCOffWb;
  2871. lhs = LHS;
  2872. temp = lhs + LSRegRHS;
  2873. if (LoadWord (state, instr, lhs))
  2874. LSBase = temp;
  2875. break;
  2876. case 0x6a: /* Store Word, WriteBack, Post Inc, Reg. */
  2877. if (BIT (4)) {
  2878. #ifdef MODE32
  2879. if (state->is_v6
  2880. && handle_v6_insn (state, instr))
  2881. break;
  2882. #endif
  2883. ARMul_UndefInstr (state, instr);
  2884. break;
  2885. }
  2886. UNDEF_LSRBaseEQOffWb;
  2887. UNDEF_LSRBaseEQDestWb;
  2888. UNDEF_LSRPCBaseWb;
  2889. UNDEF_LSRPCOffWb;
  2890. lhs = LHS;
  2891. state->NtransSig = LOW;
  2892. if (StoreWord (state, instr, lhs))
  2893. LSBase = lhs + LSRegRHS;
  2894. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2895. break;
  2896. case 0x6b: /* Load Word, WriteBack, Post Inc, Reg. */
  2897. if (BIT (4)) {
  2898. #ifdef MODE32
  2899. if (state->is_v6
  2900. && handle_v6_insn (state, instr))
  2901. break;
  2902. #endif
  2903. ARMul_UndefInstr (state, instr);
  2904. break;
  2905. }
  2906. UNDEF_LSRBaseEQOffWb;
  2907. UNDEF_LSRBaseEQDestWb;
  2908. UNDEF_LSRPCBaseWb;
  2909. UNDEF_LSRPCOffWb;
  2910. lhs = LHS;
  2911. temp = lhs + LSRegRHS;
  2912. state->NtransSig = LOW;
  2913. if (LoadWord (state, instr, lhs))
  2914. LSBase = temp;
  2915. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2916. break;
  2917. case 0x6c: /* Store Byte, No WriteBack, Post Inc, Reg. */
  2918. if (BIT (4)) {
  2919. #ifdef MODE32
  2920. if (state->is_v6
  2921. && handle_v6_insn (state, instr))
  2922. break;
  2923. #endif
  2924. ARMul_UndefInstr (state, instr);
  2925. break;
  2926. }
  2927. UNDEF_LSRBaseEQOffWb;
  2928. UNDEF_LSRBaseEQDestWb;
  2929. UNDEF_LSRPCBaseWb;
  2930. UNDEF_LSRPCOffWb;
  2931. lhs = LHS;
  2932. if (StoreByte (state, instr, lhs))
  2933. LSBase = lhs + LSRegRHS;
  2934. break;
  2935. case 0x6d: /* Load Byte, No WriteBack, Post Inc, Reg. */
  2936. if (BIT (4)) {
  2937. ARMul_UndefInstr (state, instr);
  2938. break;
  2939. }
  2940. UNDEF_LSRBaseEQOffWb;
  2941. UNDEF_LSRBaseEQDestWb;
  2942. UNDEF_LSRPCBaseWb;
  2943. UNDEF_LSRPCOffWb;
  2944. lhs = LHS;
  2945. temp = lhs + LSRegRHS;
  2946. if (LoadByte (state, instr, lhs, LUNSIGNED))
  2947. LSBase = temp;
  2948. break;
  2949. case 0x6e: /* Store Byte, WriteBack, Post Inc, Reg. */
  2950. #if 0
  2951. if (state->is_v6) {
  2952. int Rm = 0;
  2953. /* utxb */
  2954. if (BITS(15, 19) == 0xf && BITS(4, 7) == 0x7) {
  2955. Rm = (RHS >> (8 * BITS(10, 11))) & 0xff;
  2956. DEST = Rm;
  2957. }
  2958. }
  2959. #endif
  2960. if (BIT (4)) {
  2961. #ifdef MODE32
  2962. if (state->is_v6
  2963. && handle_v6_insn (state, instr))
  2964. break;
  2965. #endif
  2966. ARMul_UndefInstr (state, instr);
  2967. break;
  2968. }
  2969. UNDEF_LSRBaseEQOffWb;
  2970. UNDEF_LSRBaseEQDestWb;
  2971. UNDEF_LSRPCBaseWb;
  2972. UNDEF_LSRPCOffWb;
  2973. lhs = LHS;
  2974. state->NtransSig = LOW;
  2975. if (StoreByte (state, instr, lhs))
  2976. LSBase = lhs + LSRegRHS;
  2977. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2978. break;
  2979. case 0x6f: /* Load Byte, WriteBack, Post Inc, Reg. */
  2980. if (BIT (4)) {
  2981. #ifdef MODE32
  2982. if (state->is_v6
  2983. && handle_v6_insn (state, instr))
  2984. break;
  2985. #endif
  2986. ARMul_UndefInstr (state, instr);
  2987. break;
  2988. }
  2989. UNDEF_LSRBaseEQOffWb;
  2990. UNDEF_LSRBaseEQDestWb;
  2991. UNDEF_LSRPCBaseWb;
  2992. UNDEF_LSRPCOffWb;
  2993. lhs = LHS;
  2994. temp = lhs + LSRegRHS;
  2995. state->NtransSig = LOW;
  2996. if (LoadByte (state, instr, lhs, LUNSIGNED))
  2997. LSBase = temp;
  2998. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  2999. break;
  3000. case 0x70: /* Store Word, No WriteBack, Pre Dec, Reg. */
  3001. if (BIT (4)) {
  3002. #ifdef MODE32
  3003. if (state->is_v6 && handle_v6_insn (state, instr))
  3004. break;
  3005. #endif
  3006. ARMul_UndefInstr (state, instr);
  3007. break;
  3008. }
  3009. (void) StoreWord (state, instr, LHS - LSRegRHS);
  3010. break;
  3011. case 0x71: /* Load Word, No WriteBack, Pre Dec, Reg. */
  3012. if (BIT (4)) {
  3013. ARMul_UndefInstr (state, instr);
  3014. break;
  3015. }
  3016. (void) LoadWord (state, instr, LHS - LSRegRHS);
  3017. break;
  3018. case 0x72: /* Store Word, WriteBack, Pre Dec, Reg. */
  3019. if (BIT (4)) {
  3020. ARMul_UndefInstr (state, instr);
  3021. break;
  3022. }
  3023. UNDEF_LSRBaseEQOffWb;
  3024. UNDEF_LSRBaseEQDestWb;
  3025. UNDEF_LSRPCBaseWb;
  3026. UNDEF_LSRPCOffWb;
  3027. temp = LHS - LSRegRHS;
  3028. if (StoreWord (state, instr, temp))
  3029. LSBase = temp;
  3030. break;
  3031. case 0x73: /* Load Word, WriteBack, Pre Dec, Reg. */
  3032. if (BIT (4)) {
  3033. ARMul_UndefInstr (state, instr);
  3034. break;
  3035. }
  3036. UNDEF_LSRBaseEQOffWb;
  3037. UNDEF_LSRBaseEQDestWb;
  3038. UNDEF_LSRPCBaseWb;
  3039. UNDEF_LSRPCOffWb;
  3040. temp = LHS - LSRegRHS;
  3041. if (LoadWord (state, instr, temp))
  3042. LSBase = temp;
  3043. break;
  3044. case 0x74: /* Store Byte, No WriteBack, Pre Dec, Reg. */
  3045. if (BIT (4)) {
  3046. #ifdef MODE32
  3047. if (state->is_v6 && handle_v6_insn (state, instr))
  3048. break;
  3049. #endif
  3050. ARMul_UndefInstr (state, instr);
  3051. break;
  3052. }
  3053. (void) StoreByte (state, instr, LHS - LSRegRHS);
  3054. break;
  3055. case 0x75: /* Load Byte, No WriteBack, Pre Dec, Reg. */
  3056. if (BIT (4)) {
  3057. #ifdef MODE32
  3058. if (state->is_v6 && handle_v6_insn (state, instr))
  3059. break;
  3060. #endif
  3061. ARMul_UndefInstr (state, instr);
  3062. break;
  3063. }
  3064. (void) LoadByte (state, instr, LHS - LSRegRHS, LUNSIGNED);
  3065. break;
  3066. case 0x76: /* Store Byte, WriteBack, Pre Dec, Reg. */
  3067. if (BIT (4)) {
  3068. ARMul_UndefInstr (state, instr);
  3069. break;
  3070. }
  3071. UNDEF_LSRBaseEQOffWb;
  3072. UNDEF_LSRBaseEQDestWb;
  3073. UNDEF_LSRPCBaseWb;
  3074. UNDEF_LSRPCOffWb;
  3075. temp = LHS - LSRegRHS;
  3076. if (StoreByte (state, instr, temp))
  3077. LSBase = temp;
  3078. break;
  3079. case 0x77: /* Load Byte, WriteBack, Pre Dec, Reg. */
  3080. if (BIT (4)) {
  3081. ARMul_UndefInstr (state, instr);
  3082. break;
  3083. }
  3084. UNDEF_LSRBaseEQOffWb;
  3085. UNDEF_LSRBaseEQDestWb;
  3086. UNDEF_LSRPCBaseWb;
  3087. UNDEF_LSRPCOffWb;
  3088. temp = LHS - LSRegRHS;
  3089. if (LoadByte (state, instr, temp, LUNSIGNED))
  3090. LSBase = temp;
  3091. break;
  3092. case 0x78: /* Store Word, No WriteBack, Pre Inc, Reg. */
  3093. if (BIT (4)) {
  3094. #ifdef MODE32
  3095. if (state->is_v6 && handle_v6_insn (state, instr))
  3096. break;
  3097. #endif
  3098. ARMul_UndefInstr (state, instr);
  3099. break;
  3100. }
  3101. (void) StoreWord (state, instr, LHS + LSRegRHS);
  3102. break;
  3103. case 0x79: /* Load Word, No WriteBack, Pre Inc, Reg. */
  3104. if (BIT (4)) {
  3105. ARMul_UndefInstr (state, instr);
  3106. break;
  3107. }
  3108. (void) LoadWord (state, instr, LHS + LSRegRHS);
  3109. break;
  3110. case 0x7a: /* Store Word, WriteBack, Pre Inc, Reg. */
  3111. if (BIT (4)) {
  3112. #ifdef MODE32
  3113. if (state->is_v6 && handle_v6_insn (state, instr))
  3114. break;
  3115. #endif
  3116. ARMul_UndefInstr (state, instr);
  3117. break;
  3118. }
  3119. UNDEF_LSRBaseEQOffWb;
  3120. UNDEF_LSRBaseEQDestWb;
  3121. UNDEF_LSRPCBaseWb;
  3122. UNDEF_LSRPCOffWb;
  3123. temp = LHS + LSRegRHS;
  3124. if (StoreWord (state, instr, temp))
  3125. LSBase = temp;
  3126. break;
  3127. case 0x7b: /* Load Word, WriteBack, Pre Inc, Reg. */
  3128. if (BIT (4)) {
  3129. ARMul_UndefInstr (state, instr);
  3130. break;
  3131. }
  3132. UNDEF_LSRBaseEQOffWb;
  3133. UNDEF_LSRBaseEQDestWb;
  3134. UNDEF_LSRPCBaseWb;
  3135. UNDEF_LSRPCOffWb;
  3136. temp = LHS + LSRegRHS;
  3137. if (LoadWord (state, instr, temp))
  3138. LSBase = temp;
  3139. break;
  3140. case 0x7c: /* Store Byte, No WriteBack, Pre Inc, Reg. */
  3141. if (BIT (4)) {
  3142. #ifdef MODE32
  3143. if (state->is_v6 && handle_v6_insn (state, instr))
  3144. break;
  3145. #endif
  3146. ARMul_UndefInstr (state, instr);
  3147. break;
  3148. }
  3149. (void) StoreByte (state, instr, LHS + LSRegRHS);
  3150. break;
  3151. case 0x7d: /* Load Byte, No WriteBack, Pre Inc, Reg. */
  3152. if (BIT (4)) {
  3153. ARMul_UndefInstr (state, instr);
  3154. break;
  3155. }
  3156. (void) LoadByte (state, instr, LHS + LSRegRHS, LUNSIGNED);
  3157. break;
  3158. case 0x7e: /* Store Byte, WriteBack, Pre Inc, Reg. */
  3159. if (BIT (4)) {
  3160. ARMul_UndefInstr (state, instr);
  3161. break;
  3162. }
  3163. UNDEF_LSRBaseEQOffWb;
  3164. UNDEF_LSRBaseEQDestWb;
  3165. UNDEF_LSRPCBaseWb;
  3166. UNDEF_LSRPCOffWb;
  3167. temp = LHS + LSRegRHS;
  3168. if (StoreByte (state, instr, temp))
  3169. LSBase = temp;
  3170. break;
  3171. case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */
  3172. if (BIT (4)) {
  3173. LOG_DEBUG(Core_ARM11, "got unhandled special breakpoint");
  3174. return 1;
  3175. }
  3176. UNDEF_LSRBaseEQOffWb;
  3177. UNDEF_LSRBaseEQDestWb;
  3178. UNDEF_LSRPCBaseWb;
  3179. UNDEF_LSRPCOffWb;
  3180. temp = LHS + LSRegRHS;
  3181. if (LoadByte (state, instr, temp, LUNSIGNED))
  3182. LSBase = temp;
  3183. break;
  3184. /* Multiple Data Transfer Instructions. */
  3185. case 0x80: /* Store, No WriteBack, Post Dec. */
  3186. STOREMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
  3187. break;
  3188. case 0x81: /* Load, No WriteBack, Post Dec. */
  3189. LOADMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
  3190. break;
  3191. case 0x82: /* Store, WriteBack, Post Dec. */
  3192. temp = LSBase - LSMNumRegs;
  3193. STOREMULT (instr, temp + 4L, temp);
  3194. break;
  3195. case 0x83: /* Load, WriteBack, Post Dec. */
  3196. temp = LSBase - LSMNumRegs;
  3197. LOADMULT (instr, temp + 4L, temp);
  3198. break;
  3199. case 0x84: /* Store, Flags, No WriteBack, Post Dec. */
  3200. STORESMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
  3201. break;
  3202. case 0x85: /* Load, Flags, No WriteBack, Post Dec. */
  3203. LOADSMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
  3204. break;
  3205. case 0x86: /* Store, Flags, WriteBack, Post Dec. */
  3206. temp = LSBase - LSMNumRegs;
  3207. STORESMULT (instr, temp + 4L, temp);
  3208. break;
  3209. case 0x87: /* Load, Flags, WriteBack, Post Dec. */
  3210. temp = LSBase - LSMNumRegs;
  3211. LOADSMULT (instr, temp + 4L, temp);
  3212. break;
  3213. case 0x88: /* Store, No WriteBack, Post Inc. */
  3214. STOREMULT (instr, LSBase, 0L);
  3215. break;
  3216. case 0x89: /* Load, No WriteBack, Post Inc. */
  3217. LOADMULT (instr, LSBase, 0L);
  3218. break;
  3219. case 0x8a: /* Store, WriteBack, Post Inc. */
  3220. temp = LSBase;
  3221. STOREMULT (instr, temp, temp + LSMNumRegs);
  3222. break;
  3223. case 0x8b: /* Load, WriteBack, Post Inc. */
  3224. temp = LSBase;
  3225. LOADMULT (instr, temp, temp + LSMNumRegs);
  3226. break;
  3227. case 0x8c: /* Store, Flags, No WriteBack, Post Inc. */
  3228. STORESMULT (instr, LSBase, 0L);
  3229. break;
  3230. case 0x8d: /* Load, Flags, No WriteBack, Post Inc. */
  3231. LOADSMULT (instr, LSBase, 0L);
  3232. break;
  3233. case 0x8e: /* Store, Flags, WriteBack, Post Inc. */
  3234. temp = LSBase;
  3235. STORESMULT (instr, temp, temp + LSMNumRegs);
  3236. break;
  3237. case 0x8f: /* Load, Flags, WriteBack, Post Inc. */
  3238. temp = LSBase;
  3239. LOADSMULT (instr, temp, temp + LSMNumRegs);
  3240. break;
  3241. case 0x90: /* Store, No WriteBack, Pre Dec. */
  3242. STOREMULT (instr, LSBase - LSMNumRegs, 0L);
  3243. break;
  3244. case 0x91: /* Load, No WriteBack, Pre Dec. */
  3245. LOADMULT (instr, LSBase - LSMNumRegs, 0L);
  3246. break;
  3247. case 0x92: /* Store, WriteBack, Pre Dec. */
  3248. temp = LSBase - LSMNumRegs;
  3249. STOREMULT (instr, temp, temp);
  3250. break;
  3251. case 0x93: /* Load, WriteBack, Pre Dec. */
  3252. temp = LSBase - LSMNumRegs;
  3253. LOADMULT (instr, temp, temp);
  3254. break;
  3255. case 0x94: /* Store, Flags, No WriteBack, Pre Dec. */
  3256. STORESMULT (instr, LSBase - LSMNumRegs, 0L);
  3257. break;
  3258. case 0x95: /* Load, Flags, No WriteBack, Pre Dec. */
  3259. LOADSMULT (instr, LSBase - LSMNumRegs, 0L);
  3260. break;
  3261. case 0x96: /* Store, Flags, WriteBack, Pre Dec. */
  3262. temp = LSBase - LSMNumRegs;
  3263. STORESMULT (instr, temp, temp);
  3264. break;
  3265. case 0x97: /* Load, Flags, WriteBack, Pre Dec. */
  3266. temp = LSBase - LSMNumRegs;
  3267. LOADSMULT (instr, temp, temp);
  3268. break;
  3269. case 0x98: /* Store, No WriteBack, Pre Inc. */
  3270. STOREMULT (instr, LSBase + 4L, 0L);
  3271. break;
  3272. case 0x99: /* Load, No WriteBack, Pre Inc. */
  3273. LOADMULT (instr, LSBase + 4L, 0L);
  3274. break;
  3275. case 0x9a: /* Store, WriteBack, Pre Inc. */
  3276. temp = LSBase;
  3277. STOREMULT (instr, temp + 4L, temp + LSMNumRegs);
  3278. break;
  3279. case 0x9b: /* Load, WriteBack, Pre Inc. */
  3280. temp = LSBase;
  3281. LOADMULT (instr, temp + 4L, temp + LSMNumRegs);
  3282. break;
  3283. case 0x9c: /* Store, Flags, No WriteBack, Pre Inc. */
  3284. STORESMULT (instr, LSBase + 4L, 0L);
  3285. break;
  3286. case 0x9d: /* Load, Flags, No WriteBack, Pre Inc. */
  3287. LOADSMULT (instr, LSBase + 4L, 0L);
  3288. break;
  3289. case 0x9e: /* Store, Flags, WriteBack, Pre Inc. */
  3290. temp = LSBase;
  3291. STORESMULT (instr, temp + 4L, temp + LSMNumRegs);
  3292. break;
  3293. case 0x9f: /* Load, Flags, WriteBack, Pre Inc. */
  3294. temp = LSBase;
  3295. LOADSMULT (instr, temp + 4L, temp + LSMNumRegs);
  3296. break;
  3297. /* Branch forward. */
  3298. case 0xa0:
  3299. case 0xa1:
  3300. case 0xa2:
  3301. case 0xa3:
  3302. case 0xa4:
  3303. case 0xa5:
  3304. case 0xa6:
  3305. case 0xa7:
  3306. state->Reg[15] = pc + 8 + POSBRANCH;
  3307. FLUSHPIPE;
  3308. break;
  3309. /* Branch backward. */
  3310. case 0xa8:
  3311. case 0xa9:
  3312. case 0xaa:
  3313. case 0xab:
  3314. case 0xac:
  3315. case 0xad:
  3316. case 0xae:
  3317. case 0xaf:
  3318. state->Reg[15] = pc + 8 + NEGBRANCH;
  3319. FLUSHPIPE;
  3320. break;
  3321. /* Branch and Link forward. */
  3322. case 0xb0:
  3323. case 0xb1:
  3324. case 0xb2:
  3325. case 0xb3:
  3326. case 0xb4:
  3327. case 0xb5:
  3328. case 0xb6:
  3329. case 0xb7:
  3330. /* Put PC into Link. */
  3331. #ifdef MODE32
  3332. state->Reg[14] = pc + 4;
  3333. #else
  3334. state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
  3335. #endif
  3336. state->Reg[15] = pc + 8 + POSBRANCH;
  3337. FLUSHPIPE;
  3338. #ifdef callstacker
  3339. memset(a, 0, 256);
  3340. aufloeser(a, state->Reg[15]);
  3341. printf("call %08X %08X %s(%08X %08X %08X %08X %08X %08X %08X)\n", state->Reg[14], state->Reg[15], a, state->Reg[0], state->Reg[1], state->Reg[2], state->Reg[3], mem_Read32(state->Reg[13]), mem_Read32(state->Reg[13] - 4),mem_Read32(state->Reg[13] - 8));
  3342. #endif
  3343. break;
  3344. /* Branch and Link backward. */
  3345. case 0xb8:
  3346. case 0xb9:
  3347. case 0xba:
  3348. case 0xbb:
  3349. case 0xbc:
  3350. case 0xbd:
  3351. case 0xbe:
  3352. case 0xbf:
  3353. /* Put PC into Link. */
  3354. #ifdef MODE32
  3355. state->Reg[14] = pc + 4;
  3356. #else
  3357. state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
  3358. #endif
  3359. state->Reg[15] = pc + 8 + NEGBRANCH;
  3360. FLUSHPIPE;
  3361. #ifdef callstacker
  3362. memset(a, 0, 256);
  3363. aufloeser(a, state->Reg[15]);
  3364. printf("call %08X %08X %s(%08X %08X %08X %08X %08X %08X %08X)\n", state->Reg[14], state->Reg[15], a, state->Reg[0], state->Reg[1], state->Reg[2], state->Reg[3], mem_Read32(state->Reg[13]), mem_Read32(state->Reg[13] - 4),mem_Read32(state->Reg[13] - 8));
  3365. #endif
  3366. break;
  3367. /* Co-Processor Data Transfers. */
  3368. case 0xc4:
  3369. if ((instr & 0x0FF00FF0) == 0xC400B10) { //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0
  3370. state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)];
  3371. state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)];
  3372. break;
  3373. } else if (state->is_v5) {
  3374. /* Reading from R15 is UNPREDICTABLE. */
  3375. if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
  3376. ARMul_UndefInstr (state, instr);
  3377. /* Is access to coprocessor 0 allowed ? */
  3378. else if (!CP_ACCESS_ALLOWED(state, CPNum))
  3379. ARMul_UndefInstr (state, instr);
  3380. else {
  3381. /* MCRR, ARMv5TE and up */
  3382. ARMul_MCRR (state, instr, DEST, state->Reg[LHSReg]);
  3383. break;
  3384. }
  3385. }
  3386. /* Drop through. */
  3387. case 0xc0: /* Store , No WriteBack , Post Dec. */
  3388. ARMul_STC (state, instr, LHS);
  3389. break;
  3390. case 0xc5:
  3391. if ((instr & 0x00000FF0) == 0xB10) { //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0
  3392. state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1];
  3393. state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1];
  3394. break;
  3395. } else if (state->is_v5) {
  3396. /* Writes to R15 are UNPREDICATABLE. */
  3397. if (DESTReg == 15 || LHSReg == 15)
  3398. ARMul_UndefInstr (state, instr);
  3399. /* Is access to the coprocessor allowed ? */
  3400. else if (!CP_ACCESS_ALLOWED(state, CPNum)) {
  3401. ARMul_UndefInstr(state, instr);
  3402. } else {
  3403. /* MRRC, ARMv5TE and up */
  3404. ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg]));
  3405. break;
  3406. }
  3407. }
  3408. /* Drop through. */
  3409. case 0xc1: /* Load , No WriteBack , Post Dec. */
  3410. ARMul_LDC (state, instr, LHS);
  3411. break;
  3412. case 0xc2:
  3413. case 0xc6: /* Store , WriteBack , Post Dec. */
  3414. lhs = LHS;
  3415. state->Base = lhs - LSCOff;
  3416. ARMul_STC (state, instr, lhs);
  3417. break;
  3418. case 0xc3:
  3419. case 0xc7: /* Load , WriteBack , Post Dec. */
  3420. lhs = LHS;
  3421. state->Base = lhs - LSCOff;
  3422. ARMul_LDC (state, instr, lhs);
  3423. break;
  3424. case 0xc8:
  3425. case 0xcc: /* Store , No WriteBack , Post Inc. */
  3426. ARMul_STC (state, instr, LHS);
  3427. break;
  3428. case 0xc9:
  3429. case 0xcd: /* Load , No WriteBack , Post Inc. */
  3430. ARMul_LDC (state, instr, LHS);
  3431. break;
  3432. case 0xca:
  3433. case 0xce: /* Store , WriteBack , Post Inc. */
  3434. lhs = LHS;
  3435. state->Base = lhs + LSCOff;
  3436. ARMul_STC (state, instr, LHS);
  3437. break;
  3438. case 0xcb:
  3439. case 0xcf: /* Load , WriteBack , Post Inc. */
  3440. lhs = LHS;
  3441. state->Base = lhs + LSCOff;
  3442. ARMul_LDC (state, instr, LHS);
  3443. break;
  3444. case 0xd0:
  3445. case 0xd4: /* Store , No WriteBack , Pre Dec. */
  3446. ARMul_STC (state, instr, LHS - LSCOff);
  3447. break;
  3448. case 0xd1:
  3449. case 0xd5: /* Load , No WriteBack , Pre Dec. */
  3450. ARMul_LDC (state, instr, LHS - LSCOff);
  3451. break;
  3452. case 0xd2:
  3453. case 0xd6: /* Store , WriteBack , Pre Dec. */
  3454. lhs = LHS - LSCOff;
  3455. state->Base = lhs;
  3456. ARMul_STC (state, instr, lhs);
  3457. break;
  3458. case 0xd3:
  3459. case 0xd7: /* Load , WriteBack , Pre Dec. */
  3460. lhs = LHS - LSCOff;
  3461. state->Base = lhs;
  3462. ARMul_LDC (state, instr, lhs);
  3463. break;
  3464. case 0xd8:
  3465. case 0xdc: /* Store , No WriteBack , Pre Inc. */
  3466. ARMul_STC (state, instr, LHS + LSCOff);
  3467. break;
  3468. case 0xd9:
  3469. case 0xdd: /* Load , No WriteBack , Pre Inc. */
  3470. ARMul_LDC (state, instr, LHS + LSCOff);
  3471. break;
  3472. case 0xda:
  3473. case 0xde: /* Store , WriteBack , Pre Inc. */
  3474. lhs = LHS + LSCOff;
  3475. state->Base = lhs;
  3476. ARMul_STC (state, instr, lhs);
  3477. break;
  3478. case 0xdb:
  3479. case 0xdf: /* Load , WriteBack , Pre Inc. */
  3480. lhs = LHS + LSCOff;
  3481. state->Base = lhs;
  3482. ARMul_LDC (state, instr, lhs);
  3483. break;
  3484. /* Co-Processor Register Transfers (MCR) and Data Ops. */
  3485. case 0xe2:
  3486. /*if (!CP_ACCESS_ALLOWED (state, CPNum)) {
  3487. ARMul_UndefInstr (state, instr);
  3488. break;
  3489. }*/
  3490. case 0xe0:
  3491. case 0xe4:
  3492. case 0xe6:
  3493. case 0xe8:
  3494. case 0xea:
  3495. case 0xec:
  3496. case 0xee:
  3497. if (BIT (4)) {
  3498. /* MCR. */
  3499. if (DESTReg == 15) {
  3500. UNDEF_MCRPC;
  3501. #ifdef MODE32
  3502. ARMul_MCR (state, instr, state->Reg[15] + isize);
  3503. #else
  3504. ARMul_MCR (state, instr, ECC | ER15INT | EMODE | ((state->Reg[15] + isize) & R15PCBITS));
  3505. #endif
  3506. } else
  3507. ARMul_MCR (state, instr, DEST);
  3508. } else
  3509. /* CDP Part 1. */
  3510. ARMul_CDP (state, instr);
  3511. break;
  3512. /* Co-Processor Register Transfers (MRC) and Data Ops. */
  3513. case 0xe1:
  3514. case 0xe3:
  3515. case 0xe5:
  3516. case 0xe7:
  3517. case 0xe9:
  3518. case 0xeb:
  3519. case 0xed:
  3520. case 0xef:
  3521. if (BIT (4)) {
  3522. /* MRC */
  3523. temp = ARMul_MRC (state, instr);
  3524. if (DESTReg == 15) {
  3525. ASSIGNN ((temp & NBIT) != 0);
  3526. ASSIGNZ ((temp & ZBIT) != 0);
  3527. ASSIGNC ((temp & CBIT) != 0);
  3528. ASSIGNV ((temp & VBIT) != 0);
  3529. } else
  3530. DEST = temp;
  3531. } else
  3532. /* CDP Part 2. */
  3533. ARMul_CDP (state, instr);
  3534. break;
  3535. /* SWI instruction. */
  3536. case 0xf0:
  3537. case 0xf1:
  3538. case 0xf2:
  3539. case 0xf3:
  3540. case 0xf4:
  3541. case 0xf5:
  3542. case 0xf6:
  3543. case 0xf7:
  3544. case 0xf8:
  3545. case 0xf9:
  3546. case 0xfa:
  3547. case 0xfb:
  3548. case 0xfc:
  3549. case 0xfd:
  3550. case 0xfe:
  3551. case 0xff:
  3552. //svc_Execute(state, BITS(0, 23));
  3553. HLE::CallSVC(instr);
  3554. break;
  3555. }
  3556. }
  3557. #ifdef MODET
  3558. donext:
  3559. #endif
  3560. state->pc = pc;
  3561. #if 0
  3562. /* shenoubang */
  3563. instr_sum++;
  3564. int i, j;
  3565. i = j = 0;
  3566. if (instr_sum >= 7388648) {
  3567. //if (pc == 0xc0008ab4) {
  3568. // printf("instr_sum: %d\n", instr_sum);
  3569. // start_kernel : 0xc000895c
  3570. printf("--------------------------------------------------\n");
  3571. for (i = 0; i < 16; i++) {
  3572. printf("[R%02d]:[0x%08x]\t", i, state->Reg[i]);
  3573. if ((i % 3) == 2) {
  3574. printf("\n");
  3575. }
  3576. }
  3577. printf("[cpr]:[0x%08x]\t[spr0]:[0x%08x]\n", state->Cpsr, state->Spsr[0]);
  3578. for (j = 1; j < 7; j++) {
  3579. printf("[spr%d]:[0x%08x]\t", j, state->Spsr[j]);
  3580. if ((j % 4) == 3) {
  3581. printf("\n");
  3582. }
  3583. }
  3584. printf("\n[PC]:[0x%08x]\t[INST]:[0x%08x]\t[COUNT]:[%d]\n", pc, instr, instr_sum);
  3585. printf("--------------------------------------------------\n");
  3586. }
  3587. #endif
  3588. #if 0
  3589. fprintf(state->state_log, "PC:0x%x\n", pc);
  3590. for (reg_index = 0; reg_index < 16; reg_index ++) {
  3591. if (state->Reg[reg_index] != mirror_register_file[reg_index]) {
  3592. fprintf(state->state_log, "R%d:0x%x\n", reg_index, state->Reg[reg_index]);
  3593. mirror_register_file[reg_index] = state->Reg[reg_index];
  3594. }
  3595. }
  3596. if (state->Cpsr != mirror_register_file[CPSR_REG]) {
  3597. fprintf(state->state_log, "Cpsr:0x%x\n", state->Cpsr);
  3598. mirror_register_file[CPSR_REG] = state->Cpsr;
  3599. }
  3600. if (state->RegBank[SVCBANK][13] != mirror_register_file[R13_SVC]) {
  3601. fprintf(state->state_log, "R13_SVC:0x%x\n", state->RegBank[SVCBANK][13]);
  3602. mirror_register_file[R13_SVC] = state->RegBank[SVCBANK][13];
  3603. }
  3604. if (state->RegBank[SVCBANK][14] != mirror_register_file[R14_SVC]) {
  3605. fprintf(state->state_log, "R14_SVC:0x%x\n", state->RegBank[SVCBANK][14]);
  3606. mirror_register_file[R14_SVC] = state->RegBank[SVCBANK][14];
  3607. }
  3608. if (state->RegBank[ABORTBANK][13] != mirror_register_file[R13_ABORT]) {
  3609. fprintf(state->state_log, "R13_ABORT:0x%x\n", state->RegBank[ABORTBANK][13]);
  3610. mirror_register_file[R13_ABORT] = state->RegBank[ABORTBANK][13];
  3611. }
  3612. if (state->RegBank[ABORTBANK][14] != mirror_register_file[R14_ABORT]) {
  3613. fprintf(state->state_log, "R14_ABORT:0x%x\n", state->RegBank[ABORTBANK][14]);
  3614. mirror_register_file[R14_ABORT] = state->RegBank[ABORTBANK][14];
  3615. }
  3616. if (state->RegBank[UNDEFBANK][13] != mirror_register_file[R13_UNDEF]) {
  3617. fprintf(state->state_log, "R13_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][13]);
  3618. mirror_register_file[R13_UNDEF] = state->RegBank[UNDEFBANK][13];
  3619. }
  3620. if (state->RegBank[UNDEFBANK][14] != mirror_register_file[R14_UNDEF]) {
  3621. fprintf(state->state_log, "R14_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][14]);
  3622. mirror_register_file[R14_UNDEF] = state->RegBank[UNDEFBANK][14];
  3623. }
  3624. if (state->RegBank[IRQBANK][13] != mirror_register_file[R13_IRQ]) {
  3625. fprintf(state->state_log, "R13_IRQ:0x%x\n", state->RegBank[IRQBANK][13]);
  3626. mirror_register_file[R13_IRQ] = state->RegBank[IRQBANK][13];
  3627. }
  3628. if (state->RegBank[IRQBANK][14] != mirror_register_file[R14_IRQ]) {
  3629. fprintf(state->state_log, "R14_IRQ:0x%x\n", state->RegBank[IRQBANK][14]);
  3630. mirror_register_file[R14_IRQ] = state->RegBank[IRQBANK][14];
  3631. }
  3632. if (state->RegBank[FIQBANK][8] != mirror_register_file[R8_FIRQ]) {
  3633. fprintf(state->state_log, "R8_FIRQ:0x%x\n", state->RegBank[FIQBANK][8]);
  3634. mirror_register_file[R8_FIRQ] = state->RegBank[FIQBANK][8];
  3635. }
  3636. if (state->RegBank[FIQBANK][9] != mirror_register_file[R9_FIRQ]) {
  3637. fprintf(state->state_log, "R9_FIRQ:0x%x\n", state->RegBank[FIQBANK][9]);
  3638. mirror_register_file[R9_FIRQ] = state->RegBank[FIQBANK][9];
  3639. }
  3640. if (state->RegBank[FIQBANK][10] != mirror_register_file[R10_FIRQ]) {
  3641. fprintf(state->state_log, "R10_FIRQ:0x%x\n", state->RegBank[FIQBANK][10]);
  3642. mirror_register_file[R10_FIRQ] = state->RegBank[FIQBANK][10];
  3643. }
  3644. if (state->RegBank[FIQBANK][11] != mirror_register_file[R11_FIRQ]) {
  3645. fprintf(state->state_log, "R11_FIRQ:0x%x\n", state->RegBank[FIQBANK][11]);
  3646. mirror_register_file[R11_FIRQ] = state->RegBank[FIQBANK][11];
  3647. }
  3648. if (state->RegBank[FIQBANK][12] != mirror_register_file[R12_FIRQ]) {
  3649. fprintf(state->state_log, "R12_FIRQ:0x%x\n", state->RegBank[FIQBANK][12]);
  3650. mirror_register_file[R12_FIRQ] = state->RegBank[FIQBANK][12];
  3651. }
  3652. if (state->RegBank[FIQBANK][13] != mirror_register_file[R13_FIRQ]) {
  3653. fprintf(state->state_log, "R13_FIRQ:0x%x\n", state->RegBank[FIQBANK][13]);
  3654. mirror_register_file[R13_FIRQ] = state->RegBank[FIQBANK][13];
  3655. }
  3656. if (state->RegBank[FIQBANK][14] != mirror_register_file[R14_FIRQ]) {
  3657. fprintf(state->state_log, "R14_FIRQ:0x%x\n", state->RegBank[FIQBANK][14]);
  3658. mirror_register_file[R14_FIRQ] = state->RegBank[FIQBANK][14];
  3659. }
  3660. if (state->Spsr[SVCBANK] != mirror_register_file[SPSR_SVC]) {
  3661. fprintf(state->state_log, "SPSR_SVC:0x%x\n", state->Spsr[SVCBANK]);
  3662. mirror_register_file[SPSR_SVC] = state->RegBank[SVCBANK];
  3663. }
  3664. if (state->Spsr[ABORTBANK] != mirror_register_file[SPSR_ABORT]) {
  3665. fprintf(state->state_log, "SPSR_ABORT:0x%x\n", state->Spsr[ABORTBANK]);
  3666. mirror_register_file[SPSR_ABORT] = state->RegBank[ABORTBANK];
  3667. }
  3668. if (state->Spsr[UNDEFBANK] != mirror_register_file[SPSR_UNDEF]) {
  3669. fprintf(state->state_log, "SPSR_UNDEF:0x%x\n", state->Spsr[UNDEFBANK]);
  3670. mirror_register_file[SPSR_UNDEF] = state->RegBank[UNDEFBANK];
  3671. }
  3672. if (state->Spsr[IRQBANK] != mirror_register_file[SPSR_IRQ]) {
  3673. fprintf(state->state_log, "SPSR_IRQ:0x%x\n", state->Spsr[IRQBANK]);
  3674. mirror_register_file[SPSR_IRQ] = state->RegBank[IRQBANK];
  3675. }
  3676. if (state->Spsr[FIQBANK] != mirror_register_file[SPSR_FIRQ]) {
  3677. fprintf(state->state_log, "SPSR_FIRQ:0x%x\n", state->Spsr[FIQBANK]);
  3678. mirror_register_file[SPSR_FIRQ] = state->RegBank[FIQBANK];
  3679. }
  3680. #endif
  3681. #ifdef NEED_UI_LOOP_HOOK
  3682. if (ui_loop_hook != NULL && ui_loop_hook_counter-- < 0) {
  3683. ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
  3684. ui_loop_hook (0);
  3685. }
  3686. #endif /* NEED_UI_LOOP_HOOK */
  3687. /*added energy_prof statement by ksh in 2004-11-26 */
  3688. //chy 2005-07-28 for standalone
  3689. //ARMul_do_energy(state,instr,pc);
  3690. //teawater add for record reg value to ./reg.txt 2005.07.10---------------------
  3691. if (state->tea_break_ok && pc == state->tea_break_addr) {
  3692. //ARMul_Debug (state, 0, 0);
  3693. state->tea_break_ok = 0;
  3694. } else {
  3695. state->tea_break_ok = 1;
  3696. }
  3697. //AJ2D--------------------------------------------------------------------------
  3698. //chy 2006-04-14 for ctrl-c debug
  3699. #if 0
  3700. if (debugmode) {
  3701. if (instr != ARMul_ABORTWORD) {
  3702. remote_interrupt_test_time++;
  3703. //chy 2006-04-14 2000 should be changed in skyeye_conf ???!!!
  3704. if (remote_interrupt_test_time >= 2000) {
  3705. remote_interrupt_test_time=0;
  3706. if (remote_interrupt()) {
  3707. //for test
  3708. //printf("SKYEYE: ICE_debug recv Ctrl_C\n");
  3709. state->EndCondition = 0;
  3710. state->Emulate = STOP;
  3711. }
  3712. }
  3713. }
  3714. }
  3715. #endif
  3716. /* jump out every time */
  3717. //state->EndCondition = 0;
  3718. //state->Emulate = STOP;
  3719. //chy 2006-04-12 for ICE debug
  3720. TEST_EMULATE:
  3721. if (state->Emulate == ONCE)
  3722. state->Emulate = STOP;
  3723. //chy: 2003-08-23: should not use CHANGEMODE !!!!
  3724. /* If we have changed mode, allow the PC to advance before stopping. */
  3725. // else if (state->Emulate == CHANGEMODE)
  3726. // continue;
  3727. else if (state->Emulate != RUN)
  3728. break;
  3729. }
  3730. while (state->NumInstrsToExecute);
  3731. exit:
  3732. state->decoded = decoded;
  3733. state->loaded = loaded;
  3734. state->pc = pc;
  3735. //chy 2006-04-12, for ICE debug
  3736. state->decoded_addr=decoded_addr;
  3737. state->loaded_addr=loaded_addr;
  3738. return pc;
  3739. }
  3740. //teawater add for arm2x86 2005.02.17-------------------------------------------
  3741. /*ywc 2005-04-01*/
  3742. //#include "tb.h"
  3743. //#include "arm2x86_self.h"
  3744. static volatile void (*gen_func) (void);
  3745. //static volatile ARMul_State *tmp_st;
  3746. //static volatile ARMul_State *save_st;
  3747. static volatile uint32_t tmp_st;
  3748. static volatile uint32_t save_st;
  3749. static volatile uint32_t save_T0;
  3750. static volatile uint32_t save_T1;
  3751. static volatile uint32_t save_T2;
  3752. #ifdef MODE32
  3753. #ifdef DBCT
  3754. //teawater change for debug function 2005.07.09---------------------------------
  3755. ARMword
  3756. ARMul_Emulate32_dbct (ARMul_State * state) {
  3757. static int init = 0;
  3758. static FILE *fd;
  3759. /*if (!init) {
  3760. fd = fopen("./pc.txt", "w");
  3761. if (!fd) {
  3762. exit(-1);
  3763. }
  3764. init = 1;
  3765. } */
  3766. state->Reg[15] += INSN_SIZE;
  3767. do {
  3768. /*if (skyeye_config.log.logon>=1) {
  3769. if (state->NumInstrs>=skyeye_config.log.start && state->NumInstrs<=skyeye_config.log.end) {
  3770. static int mybegin=0;
  3771. static int myinstrnum=0;
  3772. if (mybegin==0) mybegin=1;
  3773. if (mybegin==1) {
  3774. state->Reg[15] -= INSN_SIZE;
  3775. if (skyeye_config.log.logon>=1) fprintf(skyeye_logfd,"N %llx :p %x,i %x,",state->NumInstrs, (state->Reg[15] - INSN_SIZE), instr);
  3776. if (skyeye_config.log.logon>=2) SKYEYE_OUTREGS(skyeye_logfd);
  3777. if (skyeye_config.log.logon>=3) SKYEYE_OUTMOREREGS(skyeye_logfd);
  3778. fprintf(skyeye_logfd,"\n");
  3779. if (skyeye_config.log.length>0) {
  3780. myinstrnum++;
  3781. if (myinstrnum>=skyeye_config.log.length) {
  3782. myinstrnum=0;
  3783. fflush(skyeye_logfd);
  3784. fseek(skyeye_logfd,0L,SEEK_SET);
  3785. }
  3786. }
  3787. state->Reg[15] += INSN_SIZE;
  3788. }
  3789. }
  3790. } */
  3791. state->trap = 0;
  3792. gen_func =
  3793. (void *) tb_find (state, state->Reg[15] - INSN_SIZE);
  3794. if (!gen_func) {
  3795. //fprintf(stderr, "SKYEYE: tb_find: Error in find the translate block.\n");
  3796. //exit(-1);
  3797. //TRAP_INSN_ABORT
  3798. //TEA_OUT(printf("\n------------\npc:%x\n", state->Reg[15] - INSN_SIZE));
  3799. //TEA_OUT(printf("TRAP_INSN_ABORT\n"));
  3800. //teawater add for xscale(arm v5) 2005.09.01------------------------------------
  3801. /*XScale_set_fsr_far(state, ARMul_CP15_R5_MMU_EXCPT, state->Reg[15] - INSN_SIZE);
  3802. state->Reg[15] += INSN_SIZE;
  3803. ARMul_Abort(state, ARMul_PrefetchAbortV);
  3804. state->Reg[15] += INSN_SIZE;
  3805. goto next; */
  3806. state->trap = TRAP_INSN_ABORT;
  3807. goto check;
  3808. //AJ2D--------------------------------------------------------------------------
  3809. }
  3810. save_st = (uint32_t) st;
  3811. save_T0 = T0;
  3812. save_T1 = T1;
  3813. save_T2 = T2;
  3814. tmp_st = (uint32_t) state;
  3815. wmb ();
  3816. st = (ARMul_State *) tmp_st;
  3817. gen_func ();
  3818. st = (ARMul_State *) save_st;
  3819. T0 = save_T0;
  3820. T1 = save_T1;
  3821. T2 = save_T2;
  3822. /*if (state->trap != TRAP_OUT) {
  3823. state->tea_break_ok = 1;
  3824. }
  3825. if (state->trap <= TRAP_SET_R15) {
  3826. goto next;
  3827. } */
  3828. //TEA_OUT(printf("\n------------\npc:%x\n", state->Reg[15] - INSN_SIZE));
  3829. //teawater add check thumb 2005.07.21-------------------------------------------
  3830. /*if (TFLAG) {
  3831. state->Reg[15] -= 2;
  3832. return(state->Reg[15]);
  3833. } */
  3834. //AJ2D--------------------------------------------------------------------------
  3835. //teawater add for xscale(arm v5) 2005.09.01------------------------------------
  3836. check:
  3837. //AJ2D--------------------------------------------------------------------------
  3838. switch (state->trap) {
  3839. case TRAP_RESET: {
  3840. //TEA_OUT(printf("TRAP_RESET\n"));
  3841. ARMul_Abort (state, ARMul_ResetV);
  3842. state->Reg[15] += INSN_SIZE;
  3843. }
  3844. break;
  3845. case TRAP_UNPREDICTABLE: {
  3846. //ARMul_Debug (state, 0, 0);
  3847. }
  3848. break;
  3849. case TRAP_INSN_UNDEF: {
  3850. //TEA_OUT(printf("TRAP_INSN_UNDEF\n"));
  3851. state->Reg[15] += INSN_SIZE;
  3852. ARMul_UndefInstr (state, 0);
  3853. state->Reg[15] += INSN_SIZE;
  3854. }
  3855. break;
  3856. case TRAP_SWI: {
  3857. //TEA_OUT(printf("TRAP_SWI\n"));
  3858. state->Reg[15] += INSN_SIZE;
  3859. ARMul_Abort (state, ARMul_SWIV);
  3860. state->Reg[15] += INSN_SIZE;
  3861. }
  3862. break;
  3863. //teawater add for xscale(arm v5) 2005.09.01------------------------------------
  3864. case TRAP_INSN_ABORT: {
  3865. /*XScale_set_fsr_far (state,
  3866. ARMul_CP15_R5_MMU_EXCPT,
  3867. state->Reg[15] -
  3868. INSN_SIZE);*/
  3869. state->Reg[15] += INSN_SIZE;
  3870. ARMul_Abort (state, ARMul_PrefetchAbortV);
  3871. state->Reg[15] += INSN_SIZE;
  3872. }
  3873. break;
  3874. //AJ2D--------------------------------------------------------------------------
  3875. case TRAP_DATA_ABORT: {
  3876. //TEA_OUT(printf("TRAP_DATA_ABORT\n"));
  3877. state->Reg[15] += INSN_SIZE;
  3878. ARMul_Abort (state, ARMul_DataAbortV);
  3879. state->Reg[15] += INSN_SIZE;
  3880. }
  3881. break;
  3882. case TRAP_IRQ: {
  3883. //TEA_OUT(printf("TRAP_IRQ\n"));
  3884. state->Reg[15] += INSN_SIZE;
  3885. ARMul_Abort (state, ARMul_IRQV);
  3886. state->Reg[15] += INSN_SIZE;
  3887. }
  3888. break;
  3889. case TRAP_FIQ: {
  3890. //TEA_OUT(printf("TRAP_FIQ\n"));
  3891. state->Reg[15] += INSN_SIZE;
  3892. ARMul_Abort (state, ARMul_FIQV);
  3893. state->Reg[15] += INSN_SIZE;
  3894. }
  3895. break;
  3896. case TRAP_SETS_R15: {
  3897. //TEA_OUT(printf("TRAP_SETS_R15\n"));
  3898. /*if (state->Bank > 0) {
  3899. state->Cpsr = state->Spsr[state->Bank];
  3900. ARMul_CPSRAltered (state);
  3901. } */
  3902. WriteSR15 (state, state->Reg[15]);
  3903. }
  3904. break;
  3905. case TRAP_SET_CPSR: {
  3906. //TEA_OUT(printf("TRAP_SET_CPSR\n"));
  3907. //chy 2006-02-15 USERBANK=SYSTEMBANK=0
  3908. //chy 2006-02-16 should use Mode to test
  3909. //if (state->Bank > 0) {
  3910. if (state->Mode != USER26MODE && state->Mode != USER32MODE) {
  3911. //ARMul_CPSRAltered (state);
  3912. }
  3913. state->Reg[15] += INSN_SIZE;
  3914. }
  3915. break;
  3916. case TRAP_OUT: {
  3917. //TEA_OUT(printf("TRAP_OUT\n"));
  3918. goto out;
  3919. }
  3920. break;
  3921. case TRAP_BREAKPOINT: {
  3922. //TEA_OUT(printf("TRAP_BREAKPOINT\n"));
  3923. state->Reg[15] -= INSN_SIZE;
  3924. if (!ARMul_OSHandleSWI
  3925. (state, SWI_Breakpoint)) {
  3926. ARMul_Abort (state, ARMul_SWIV);
  3927. }
  3928. state->Reg[15] += INSN_SIZE;
  3929. }
  3930. break;
  3931. }
  3932. next:
  3933. if (state->Emulate == ONCE) {
  3934. state->Emulate = STOP;
  3935. break;
  3936. } else if (state->Emulate != RUN) {
  3937. break;
  3938. }
  3939. } while (!state->stop_simulator);
  3940. out:
  3941. state->Reg[15] -= INSN_SIZE;
  3942. return (state->Reg[15]);
  3943. }
  3944. #endif
  3945. //AJ2D--------------------------------------------------------------------------
  3946. #endif
  3947. //AJ2D--------------------------------------------------------------------------
  3948. /* This routine evaluates most Data Processing register RHS's with the S
  3949. bit clear. It is intended to be called from the macro DPRegRHS, which
  3950. filters the common case of an unshifted register with in line code. */
  3951. static ARMword
  3952. GetDPRegRHS (ARMul_State * state, ARMword instr) {
  3953. ARMword shamt, base;
  3954. base = RHSReg;
  3955. if (BIT (4)) {
  3956. /* Shift amount in a register. */
  3957. UNDEF_Shift;
  3958. INCPC;
  3959. #ifndef MODE32
  3960. if (base == 15)
  3961. base = ECC | ER15INT | R15PC | EMODE;
  3962. else
  3963. #endif
  3964. base = state->Reg[base];
  3965. ARMul_Icycles (state, 1, 0L);
  3966. shamt = state->Reg[BITS (8, 11)] & 0xff;
  3967. switch ((int) BITS (5, 6)) {
  3968. case LSL:
  3969. if (shamt == 0)
  3970. return (base);
  3971. else if (shamt >= 32)
  3972. return (0);
  3973. else
  3974. return (base << shamt);
  3975. case LSR:
  3976. if (shamt == 0)
  3977. return (base);
  3978. else if (shamt >= 32)
  3979. return (0);
  3980. else
  3981. return (base >> shamt);
  3982. case ASR:
  3983. if (shamt == 0)
  3984. return (base);
  3985. else if (shamt >= 32)
  3986. return ((ARMword) ((int) base >> 31L));
  3987. else
  3988. return ((ARMword)
  3989. (( int) base >> (int) shamt));
  3990. case ROR:
  3991. shamt &= 0x1f;
  3992. if (shamt == 0)
  3993. return (base);
  3994. else
  3995. return ((base << (32 - shamt)) |
  3996. (base >> shamt));
  3997. }
  3998. } else {
  3999. /* Shift amount is a constant. */
  4000. #ifndef MODE32
  4001. if (base == 15)
  4002. base = ECC | ER15INT | R15PC | EMODE;
  4003. else
  4004. #endif
  4005. base = state->Reg[base];
  4006. shamt = BITS (7, 11);
  4007. switch ((int) BITS (5, 6)) {
  4008. case LSL:
  4009. return (base << shamt);
  4010. case LSR:
  4011. if (shamt == 0)
  4012. return (0);
  4013. else
  4014. return (base >> shamt);
  4015. case ASR:
  4016. if (shamt == 0)
  4017. return ((ARMword) (( int) base >> 31L));
  4018. else
  4019. return ((ARMword)
  4020. (( int) base >> (int) shamt));
  4021. case ROR:
  4022. if (shamt == 0)
  4023. /* It's an RRX. */
  4024. return ((base >> 1) | (CFLAG << 31));
  4025. else
  4026. return ((base << (32 - shamt)) |
  4027. (base >> shamt));
  4028. }
  4029. }
  4030. return 0;
  4031. }
  4032. /* This routine evaluates most Logical Data Processing register RHS's
  4033. with the S bit set. It is intended to be called from the macro
  4034. DPSRegRHS, which filters the common case of an unshifted register
  4035. with in line code. */
  4036. static ARMword
  4037. GetDPSRegRHS (ARMul_State * state, ARMword instr) {
  4038. ARMword shamt, base;
  4039. base = RHSReg;
  4040. if (BIT (4)) {
  4041. /* Shift amount in a register. */
  4042. UNDEF_Shift;
  4043. INCPC;
  4044. #ifndef MODE32
  4045. if (base == 15)
  4046. base = ECC | ER15INT | R15PC | EMODE;
  4047. else
  4048. #endif
  4049. base = state->Reg[base];
  4050. ARMul_Icycles (state, 1, 0L);
  4051. shamt = state->Reg[BITS (8, 11)] & 0xff;
  4052. switch ((int) BITS (5, 6)) {
  4053. case LSL:
  4054. if (shamt == 0)
  4055. return (base);
  4056. else if (shamt == 32) {
  4057. ASSIGNC (base & 1);
  4058. return (0);
  4059. } else if (shamt > 32) {
  4060. CLEARC;
  4061. return (0);
  4062. } else {
  4063. ASSIGNC ((base >> (32 - shamt)) & 1);
  4064. return (base << shamt);
  4065. }
  4066. case LSR:
  4067. if (shamt == 0)
  4068. return (base);
  4069. else if (shamt == 32) {
  4070. ASSIGNC (base >> 31);
  4071. return (0);
  4072. } else if (shamt > 32) {
  4073. CLEARC;
  4074. return (0);
  4075. } else {
  4076. ASSIGNC ((base >> (shamt - 1)) & 1);
  4077. return (base >> shamt);
  4078. }
  4079. case ASR:
  4080. if (shamt == 0)
  4081. return (base);
  4082. else if (shamt >= 32) {
  4083. ASSIGNC (base >> 31L);
  4084. return ((ARMword) (( int) base >> 31L));
  4085. } else {
  4086. ASSIGNC ((ARMword)
  4087. (( int) base >>
  4088. (int) (shamt - 1)) & 1);
  4089. return ((ARMword)
  4090. ((int) base >> (int) shamt));
  4091. }
  4092. case ROR:
  4093. if (shamt == 0)
  4094. return (base);
  4095. shamt &= 0x1f;
  4096. if (shamt == 0) {
  4097. ASSIGNC (base >> 31);
  4098. return (base);
  4099. } else {
  4100. ASSIGNC ((base >> (shamt - 1)) & 1);
  4101. return ((base << (32 - shamt)) |
  4102. (base >> shamt));
  4103. }
  4104. }
  4105. } else {
  4106. /* Shift amount is a constant. */
  4107. #ifndef MODE32
  4108. if (base == 15)
  4109. base = ECC | ER15INT | R15PC | EMODE;
  4110. else
  4111. #endif
  4112. base = state->Reg[base];
  4113. shamt = BITS (7, 11);
  4114. switch ((int) BITS (5, 6)) {
  4115. case LSL:
  4116. ASSIGNC ((base >> (32 - shamt)) & 1);
  4117. return (base << shamt);
  4118. case LSR:
  4119. if (shamt == 0) {
  4120. ASSIGNC (base >> 31);
  4121. return (0);
  4122. } else {
  4123. ASSIGNC ((base >> (shamt - 1)) & 1);
  4124. return (base >> shamt);
  4125. }
  4126. case ASR:
  4127. if (shamt == 0) {
  4128. ASSIGNC (base >> 31L);
  4129. return ((ARMword) ((int) base >> 31L));
  4130. } else {
  4131. ASSIGNC ((ARMword)
  4132. ((int) base >>
  4133. (int) (shamt - 1)) & 1);
  4134. return ((ARMword)
  4135. (( int) base >> (int) shamt));
  4136. }
  4137. case ROR:
  4138. if (shamt == 0) {
  4139. /* It's an RRX. */
  4140. shamt = CFLAG;
  4141. ASSIGNC (base & 1);
  4142. return ((base >> 1) | (shamt << 31));
  4143. } else {
  4144. ASSIGNC ((base >> (shamt - 1)) & 1);
  4145. return ((base << (32 - shamt)) |
  4146. (base >> shamt));
  4147. }
  4148. }
  4149. }
  4150. return 0;
  4151. }
  4152. /* This routine handles writes to register 15 when the S bit is not set. */
  4153. static void
  4154. WriteR15 (ARMul_State * state, ARMword src) {
  4155. /* The ARM documentation states that the two least significant bits
  4156. are discarded when setting PC, except in the cases handled by
  4157. WriteR15Branch() below. It's probably an oversight: in THUMB
  4158. mode, the second least significant bit should probably not be
  4159. discarded. */
  4160. #ifdef MODET
  4161. if (TFLAG)
  4162. src &= 0xfffffffe;
  4163. else
  4164. #endif
  4165. src &= 0xfffffffc;
  4166. #ifdef MODE32
  4167. state->Reg[15] = src & PCBITS;
  4168. #else
  4169. state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE;
  4170. ARMul_R15Altered (state);
  4171. #endif
  4172. FLUSHPIPE;
  4173. }
  4174. /* This routine handles writes to register 15 when the S bit is set. */
  4175. static void
  4176. WriteSR15 (ARMul_State * state, ARMword src) {
  4177. #ifdef MODE32
  4178. if (state->Bank > 0) {
  4179. state->Cpsr = state->Spsr[state->Bank];
  4180. ARMul_CPSRAltered (state);
  4181. }
  4182. #ifdef MODET
  4183. if (TFLAG)
  4184. src &= 0xfffffffe;
  4185. else
  4186. #endif
  4187. src &= 0xfffffffc;
  4188. state->Reg[15] = src & PCBITS;
  4189. #else
  4190. #ifdef MODET
  4191. if (TFLAG)
  4192. /* ARMul_R15Altered would have to support it. */
  4193. abort ();
  4194. else
  4195. #endif
  4196. src &= 0xfffffffc;
  4197. if (state->Bank == USERBANK)
  4198. state->Reg[15] =
  4199. (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE;
  4200. else
  4201. state->Reg[15] = src;
  4202. ARMul_R15Altered (state);
  4203. #endif
  4204. FLUSHPIPE;
  4205. }
  4206. /* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM
  4207. will switch to Thumb mode if the least significant bit is set. */
  4208. static void
  4209. WriteR15Branch (ARMul_State * state, ARMword src) {
  4210. #ifdef MODET
  4211. if (src & 1) {
  4212. /* Thumb bit. */
  4213. SETT;
  4214. state->Reg[15] = src & 0xfffffffe;
  4215. } else {
  4216. CLEART;
  4217. state->Reg[15] = src & 0xfffffffc;
  4218. }
  4219. state->Cpsr = ARMul_GetCPSR (state);
  4220. FLUSHPIPE;
  4221. #else
  4222. WriteR15 (state, src);
  4223. #endif
  4224. }
  4225. /* This routine evaluates most Load and Store register RHS's. It is
  4226. intended to be called from the macro LSRegRHS, which filters the
  4227. common case of an unshifted register with in line code. */
  4228. static ARMword
  4229. GetLSRegRHS (ARMul_State * state, ARMword instr) {
  4230. ARMword shamt, base;
  4231. base = RHSReg;
  4232. #ifndef MODE32
  4233. if (base == 15)
  4234. /* Now forbidden, but ... */
  4235. base = ECC | ER15INT | R15PC | EMODE;
  4236. else
  4237. #endif
  4238. base = state->Reg[base];
  4239. shamt = BITS (7, 11);
  4240. switch ((int) BITS (5, 6)) {
  4241. case LSL:
  4242. return (base << shamt);
  4243. case LSR:
  4244. if (shamt == 0)
  4245. return (0);
  4246. else
  4247. return (base >> shamt);
  4248. case ASR:
  4249. if (shamt == 0)
  4250. return ((ARMword) (( int) base >> 31L));
  4251. else
  4252. return ((ARMword) (( int) base >> (int) shamt));
  4253. case ROR:
  4254. if (shamt == 0)
  4255. /* It's an RRX. */
  4256. return ((base >> 1) | (CFLAG << 31));
  4257. else
  4258. return ((base << (32 - shamt)) | (base >> shamt));
  4259. default:
  4260. break;
  4261. }
  4262. return 0;
  4263. }
  4264. /* This routine evaluates the ARM7T halfword and signed transfer RHS's. */
  4265. static ARMword
  4266. GetLS7RHS (ARMul_State * state, ARMword instr) {
  4267. if (BIT (22) == 0) {
  4268. /* Register. */
  4269. #ifndef MODE32
  4270. if (RHSReg == 15)
  4271. /* Now forbidden, but ... */
  4272. return ECC | ER15INT | R15PC | EMODE;
  4273. #endif
  4274. return state->Reg[RHSReg];
  4275. }
  4276. /* Immediate. */
  4277. return BITS (0, 3) | (BITS (8, 11) << 4);
  4278. }
  4279. /* This function does the work of loading a word for a LDR instruction. */
  4280. #define MEM_LOAD_LOG(description) if (skyeye_config.log.memlogon >= 1) { \
  4281. fprintf(skyeye_logfd, \
  4282. "m LOAD %s: N %llx :p %x :i %x :a %x :d %x\n", \
  4283. description, state->NumInstrs, state->pc, instr, \
  4284. address, dest); \
  4285. }
  4286. #define MEM_STORE_LOG(description) if (skyeye_config.log.memlogon >= 1) { \
  4287. fprintf(skyeye_logfd, \
  4288. "m STORE %s: N %llx :p %x :i %x :a %x :d %x\n", \
  4289. description, state->NumInstrs, state->pc, instr, \
  4290. address, DEST); \
  4291. }
  4292. static unsigned
  4293. LoadWord (ARMul_State * state, ARMword instr, ARMword address) {
  4294. ARMword dest;
  4295. BUSUSEDINCPCS;
  4296. #ifndef MODE32
  4297. if (ADDREXCEPT (address))
  4298. INTERNALABORT (address);
  4299. #endif
  4300. dest = ARMul_LoadWordN (state, address);
  4301. if (state->Aborted) {
  4302. TAKEABORT;
  4303. return state->lateabtSig;
  4304. }
  4305. if (address & 3)
  4306. dest = ARMul_Align (state, address, dest);
  4307. WRITEDESTB (dest);
  4308. ARMul_Icycles (state, 1, 0L);
  4309. //MEM_LOAD_LOG("WORD");
  4310. return (DESTReg != LHSReg);
  4311. }
  4312. #ifdef MODET
  4313. /* This function does the work of loading a halfword. */
  4314. static unsigned
  4315. LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address,
  4316. int signextend) {
  4317. ARMword dest;
  4318. BUSUSEDINCPCS;
  4319. #ifndef MODE32
  4320. if (ADDREXCEPT (address))
  4321. INTERNALABORT (address);
  4322. #endif
  4323. dest = ARMul_LoadHalfWord (state, address);
  4324. if (state->Aborted) {
  4325. TAKEABORT;
  4326. return state->lateabtSig;
  4327. }
  4328. UNDEF_LSRBPC;
  4329. if (signextend)
  4330. if (dest & 1 << (16 - 1))
  4331. dest = (dest & ((1 << 16) - 1)) - (1 << 16);
  4332. WRITEDEST (dest);
  4333. ARMul_Icycles (state, 1, 0L);
  4334. //MEM_LOAD_LOG("HALFWORD");
  4335. return (DESTReg != LHSReg);
  4336. }
  4337. #endif /* MODET */
  4338. /* This function does the work of loading a byte for a LDRB instruction. */
  4339. static unsigned
  4340. LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend) {
  4341. ARMword dest;
  4342. BUSUSEDINCPCS;
  4343. #ifndef MODE32
  4344. if (ADDREXCEPT (address))
  4345. INTERNALABORT (address);
  4346. #endif
  4347. dest = ARMul_LoadByte (state, address);
  4348. if (state->Aborted) {
  4349. TAKEABORT;
  4350. return state->lateabtSig;
  4351. }
  4352. UNDEF_LSRBPC;
  4353. if (signextend)
  4354. if (dest & 1 << (8 - 1))
  4355. dest = (dest & ((1 << 8) - 1)) - (1 << 8);
  4356. WRITEDEST (dest);
  4357. ARMul_Icycles (state, 1, 0L);
  4358. //MEM_LOAD_LOG("BYTE");
  4359. return (DESTReg != LHSReg);
  4360. }
  4361. /* This function does the work of loading two words for a LDRD instruction. */
  4362. static void
  4363. Handle_Load_Double (ARMul_State * state, ARMword instr) {
  4364. ARMword dest_reg;
  4365. ARMword addr_reg;
  4366. ARMword write_back = BIT (21);
  4367. ARMword immediate = BIT (22);
  4368. ARMword add_to_base = BIT (23);
  4369. ARMword pre_indexed = BIT (24);
  4370. ARMword offset;
  4371. ARMword addr;
  4372. ARMword sum;
  4373. ARMword base;
  4374. ARMword value1;
  4375. ARMword value2;
  4376. BUSUSEDINCPCS;
  4377. /* If the writeback bit is set, the pre-index bit must be clear. */
  4378. if (write_back && !pre_indexed) {
  4379. ARMul_UndefInstr (state, instr);
  4380. return;
  4381. }
  4382. /* Extract the base address register. */
  4383. addr_reg = LHSReg;
  4384. /* Extract the destination register and check it. */
  4385. dest_reg = DESTReg;
  4386. /* Destination register must be even. */
  4387. if ((dest_reg & 1)
  4388. /* Destination register cannot be LR. */
  4389. || (dest_reg == 14)) {
  4390. ARMul_UndefInstr (state, instr);
  4391. return;
  4392. }
  4393. /* Compute the base address. */
  4394. base = state->Reg[addr_reg];
  4395. /* Compute the offset. */
  4396. offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->
  4397. Reg[RHSReg];
  4398. /* Compute the sum of the two. */
  4399. if (add_to_base)
  4400. sum = base + offset;
  4401. else
  4402. sum = base - offset;
  4403. /* If this is a pre-indexed mode use the sum. */
  4404. if (pre_indexed)
  4405. addr = sum;
  4406. else
  4407. addr = base;
  4408. /* The address must be aligned on a 8 byte boundary. */
  4409. /*if (addr & 0x7) {
  4410. #ifdef ABORTS
  4411. ARMul_DATAABORT (addr);
  4412. #else
  4413. ARMul_UndefInstr (state, instr);
  4414. #endif
  4415. return;
  4416. }*/
  4417. /* Lets just forcibly align it for now */
  4418. //addr = (addr + 7) & ~7;
  4419. /* For pre indexed or post indexed addressing modes,
  4420. check that the destination registers do not overlap
  4421. the address registers. */
  4422. if ((!pre_indexed || write_back)
  4423. && (addr_reg == dest_reg || addr_reg == dest_reg + 1)) {
  4424. ARMul_UndefInstr (state, instr);
  4425. return;
  4426. }
  4427. /* Load the words. */
  4428. value1 = ARMul_LoadWordN (state, addr);
  4429. value2 = ARMul_LoadWordN (state, addr + 4);
  4430. /* Check for data aborts. */
  4431. if (state->Aborted) {
  4432. TAKEABORT;
  4433. return;
  4434. }
  4435. ARMul_Icycles (state, 2, 0L);
  4436. /* Store the values. */
  4437. state->Reg[dest_reg] = value1;
  4438. state->Reg[dest_reg + 1] = value2;
  4439. /* Do the post addressing and writeback. */
  4440. if (!pre_indexed)
  4441. addr = sum;
  4442. if (!pre_indexed || write_back)
  4443. state->Reg[addr_reg] = addr;
  4444. }
  4445. /* This function does the work of storing two words for a STRD instruction. */
  4446. static void
  4447. Handle_Store_Double (ARMul_State * state, ARMword instr) {
  4448. ARMword src_reg;
  4449. ARMword addr_reg;
  4450. ARMword write_back = BIT (21);
  4451. ARMword immediate = BIT (22);
  4452. ARMword add_to_base = BIT (23);
  4453. ARMword pre_indexed = BIT (24);
  4454. ARMword offset;
  4455. ARMword addr;
  4456. ARMword sum;
  4457. ARMword base;
  4458. BUSUSEDINCPCS;
  4459. /* If the writeback bit is set, the pre-index bit must be clear. */
  4460. if (write_back && !pre_indexed) {
  4461. ARMul_UndefInstr (state, instr);
  4462. return;
  4463. }
  4464. /* Extract the base address register. */
  4465. addr_reg = LHSReg;
  4466. /* Base register cannot be PC. */
  4467. if (addr_reg == 15) {
  4468. ARMul_UndefInstr (state, instr);
  4469. return;
  4470. }
  4471. /* Extract the source register. */
  4472. src_reg = DESTReg;
  4473. /* Source register must be even. */
  4474. if (src_reg & 1) {
  4475. ARMul_UndefInstr (state, instr);
  4476. return;
  4477. }
  4478. /* Compute the base address. */
  4479. base = state->Reg[addr_reg];
  4480. /* Compute the offset. */
  4481. offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->
  4482. Reg[RHSReg];
  4483. /* Compute the sum of the two. */
  4484. if (add_to_base)
  4485. sum = base + offset;
  4486. else
  4487. sum = base - offset;
  4488. /* If this is a pre-indexed mode use the sum. */
  4489. if (pre_indexed)
  4490. addr = sum;
  4491. else
  4492. addr = base;
  4493. /* The address must be aligned on a 8 byte boundary. */
  4494. /*if (addr & 0x7) {
  4495. #ifdef ABORTS
  4496. ARMul_DATAABORT (addr);
  4497. #else
  4498. ARMul_UndefInstr (state, instr);
  4499. #endif
  4500. return;
  4501. }*/
  4502. /* Lets just forcibly align it for now */
  4503. //addr = (addr + 7) & ~7;
  4504. /* For pre indexed or post indexed addressing modes,
  4505. check that the destination registers do not overlap
  4506. the address registers. */
  4507. if ((!pre_indexed || write_back)
  4508. && (addr_reg == src_reg || addr_reg == src_reg + 1)) {
  4509. ARMul_UndefInstr (state, instr);
  4510. return;
  4511. }
  4512. /* Load the words. */
  4513. ARMul_StoreWordN (state, addr, state->Reg[src_reg]);
  4514. ARMul_StoreWordN (state, addr + 4, state->Reg[src_reg + 1]);
  4515. if (state->Aborted) {
  4516. TAKEABORT;
  4517. return;
  4518. }
  4519. /* Do the post addressing and writeback. */
  4520. if (!pre_indexed)
  4521. addr = sum;
  4522. if (!pre_indexed || write_back)
  4523. state->Reg[addr_reg] = addr;
  4524. }
  4525. /* This function does the work of storing a word from a STR instruction. */
  4526. static unsigned
  4527. StoreWord (ARMul_State * state, ARMword instr, ARMword address) {
  4528. //MEM_STORE_LOG("WORD");
  4529. BUSUSEDINCPCN;
  4530. #ifndef MODE32
  4531. if (DESTReg == 15)
  4532. state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
  4533. #endif
  4534. #ifdef MODE32
  4535. ARMul_StoreWordN (state, address, DEST);
  4536. #else
  4537. if (VECTORACCESS (address) || ADDREXCEPT (address)) {
  4538. INTERNALABORT (address);
  4539. (void) ARMul_LoadWordN (state, address);
  4540. } else
  4541. ARMul_StoreWordN (state, address, DEST);
  4542. #endif
  4543. if (state->Aborted) {
  4544. TAKEABORT;
  4545. return state->lateabtSig;
  4546. }
  4547. return TRUE;
  4548. }
  4549. #ifdef MODET
  4550. /* This function does the work of storing a byte for a STRH instruction. */
  4551. static unsigned
  4552. StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address) {
  4553. //MEM_STORE_LOG("HALFWORD");
  4554. BUSUSEDINCPCN;
  4555. #ifndef MODE32
  4556. if (DESTReg == 15)
  4557. state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
  4558. #endif
  4559. #ifdef MODE32
  4560. ARMul_StoreHalfWord (state, address, DEST);
  4561. #else
  4562. if (VECTORACCESS (address) || ADDREXCEPT (address)) {
  4563. INTERNALABORT (address);
  4564. (void) ARMul_LoadHalfWord (state, address);
  4565. } else
  4566. ARMul_StoreHalfWord (state, address, DEST);
  4567. #endif
  4568. if (state->Aborted) {
  4569. TAKEABORT;
  4570. return state->lateabtSig;
  4571. }
  4572. return TRUE;
  4573. }
  4574. #endif /* MODET */
  4575. /* This function does the work of storing a byte for a STRB instruction. */
  4576. static unsigned
  4577. StoreByte (ARMul_State * state, ARMword instr, ARMword address) {
  4578. //MEM_STORE_LOG("BYTE");
  4579. BUSUSEDINCPCN;
  4580. #ifndef MODE32
  4581. if (DESTReg == 15)
  4582. state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
  4583. #endif
  4584. #ifdef MODE32
  4585. ARMul_StoreByte (state, address, DEST);
  4586. #else
  4587. if (VECTORACCESS (address) || ADDREXCEPT (address)) {
  4588. INTERNALABORT (address);
  4589. (void) ARMul_LoadByte (state, address);
  4590. } else
  4591. ARMul_StoreByte (state, address, DEST);
  4592. #endif
  4593. if (state->Aborted) {
  4594. TAKEABORT;
  4595. return state->lateabtSig;
  4596. }
  4597. //UNDEF_LSRBPC;
  4598. return TRUE;
  4599. }
  4600. /* This function does the work of loading the registers listed in an LDM
  4601. instruction, when the S bit is clear. The code here is always increment
  4602. after, it's up to the caller to get the input address correct and to
  4603. handle base register modification. */
  4604. static void
  4605. LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase) {
  4606. ARMword dest, temp;
  4607. //UNDEF_LSMNoRegs;
  4608. //UNDEF_LSMPCBase;
  4609. //UNDEF_LSMBaseInListWb;
  4610. BUSUSEDINCPCS;
  4611. #ifndef MODE32
  4612. if (ADDREXCEPT (address))
  4613. INTERNALABORT (address);
  4614. #endif
  4615. /*chy 2004-05-23 may write twice
  4616. if (BIT (21) && LHSReg != 15)
  4617. LSBase = WBBase;
  4618. */
  4619. /* N cycle first. */
  4620. for (temp = 0; !BIT (temp); temp++);
  4621. dest = ARMul_LoadWordN (state, address);
  4622. if (!state->abortSig && !state->Aborted)
  4623. state->Reg[temp++] = dest;
  4624. else if (!state->Aborted) {
  4625. //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
  4626. state->Aborted = ARMul_DataAbortV;
  4627. }
  4628. /*chy 2004-05-23 chy goto end*/
  4629. if (state->Aborted)
  4630. goto L_ldm_makeabort;
  4631. /* S cycles from here on. */
  4632. for (; temp < 16; temp++)
  4633. if (BIT (temp)) {
  4634. /* Load this register. */
  4635. address += 4;
  4636. dest = ARMul_LoadWordS (state, address);
  4637. if (!state->abortSig && !state->Aborted)
  4638. state->Reg[temp] = dest;
  4639. else if (!state->Aborted) {
  4640. /*XScale_set_fsr_far (state,
  4641. ARMul_CP15_R5_ST_ALIGN,
  4642. address);*/
  4643. state->Aborted = ARMul_DataAbortV;
  4644. }
  4645. /*chy 2004-05-23 chy goto end */
  4646. if (state->Aborted)
  4647. goto L_ldm_makeabort;
  4648. }
  4649. if (BIT (15) && !state->Aborted)
  4650. /* PC is in the reg list. */
  4651. WriteR15Branch (state, PC);
  4652. /* To write back the final register. */
  4653. /* ARMul_Icycles (state, 1, 0L);*/
  4654. /*chy 2004-05-23, see below
  4655. if (state->Aborted)
  4656. {
  4657. if (BIT (21) && LHSReg != 15)
  4658. LSBase = WBBase;
  4659. TAKEABORT;
  4660. }
  4661. */
  4662. /*chy 2004-05-23 should compare the Abort Models*/
  4663. L_ldm_makeabort:
  4664. /* To write back the final register. */
  4665. ARMul_Icycles (state, 1, 0L);
  4666. /* chy 2005-11-24, bug found by benjl@cse.unsw.edu.au, etc */
  4667. /*
  4668. if (state->Aborted)
  4669. {
  4670. if (BIT (21) && LHSReg != 15)
  4671. if (!(state->abortSig && state->Aborted && state->lateabtSig == LOW))
  4672. LSBase = WBBase;
  4673. TAKEABORT;
  4674. }else if (BIT (21) && LHSReg != 15)
  4675. LSBase = WBBase;
  4676. */
  4677. if (state->Aborted) {
  4678. if (BIT (21) && LHSReg != 15) {
  4679. if (!(state->abortSig)) {
  4680. }
  4681. }
  4682. TAKEABORT;
  4683. } else if (BIT (21) && LHSReg != 15) {
  4684. LSBase = WBBase;
  4685. }
  4686. /* chy 2005-11-24, over */
  4687. }
  4688. /* This function does the work of loading the registers listed in an LDM
  4689. instruction, when the S bit is set. The code here is always increment
  4690. after, it's up to the caller to get the input address correct and to
  4691. handle base register modification. */
  4692. static void
  4693. LoadSMult (ARMul_State * state,
  4694. ARMword instr, ARMword address, ARMword WBBase) {
  4695. ARMword dest, temp;
  4696. //UNDEF_LSMNoRegs;
  4697. //UNDEF_LSMPCBase;
  4698. //UNDEF_LSMBaseInListWb;
  4699. BUSUSEDINCPCS;
  4700. #ifndef MODE32
  4701. if (ADDREXCEPT (address))
  4702. INTERNALABORT (address);
  4703. #endif
  4704. /* chy 2004-05-23, may write twice
  4705. if (BIT (21) && LHSReg != 15)
  4706. LSBase = WBBase;
  4707. */
  4708. if (!BIT (15) && state->Bank != USERBANK) {
  4709. /* Temporary reg bank switch. */
  4710. (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
  4711. UNDEF_LSMUserBankWb;
  4712. }
  4713. /* N cycle first. */
  4714. for (temp = 0; !BIT (temp); temp++);
  4715. dest = ARMul_LoadWordN (state, address);
  4716. if (!state->abortSig)
  4717. state->Reg[temp++] = dest;
  4718. else if (!state->Aborted) {
  4719. //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
  4720. state->Aborted = ARMul_DataAbortV;
  4721. }
  4722. /*chy 2004-05-23 chy goto end*/
  4723. if (state->Aborted)
  4724. goto L_ldm_s_makeabort;
  4725. /* S cycles from here on. */
  4726. for (; temp < 16; temp++)
  4727. if (BIT (temp)) {
  4728. /* Load this register. */
  4729. address += 4;
  4730. dest = ARMul_LoadWordS (state, address);
  4731. if (!state->abortSig && !state->Aborted)
  4732. state->Reg[temp] = dest;
  4733. else if (!state->Aborted) {
  4734. /*XScale_set_fsr_far (state,
  4735. ARMul_CP15_R5_ST_ALIGN,
  4736. address);*/
  4737. state->Aborted = ARMul_DataAbortV;
  4738. }
  4739. /*chy 2004-05-23 chy goto end */
  4740. if (state->Aborted)
  4741. goto L_ldm_s_makeabort;
  4742. }
  4743. /*chy 2004-05-23 label of ldm_s_makeabort*/
  4744. L_ldm_s_makeabort:
  4745. /*chy 2004-06-06 LSBase process should be here, not in the end of this function. Because ARMul_CPSRAltered maybe change R13(SP) R14(lr). If not, simulate INSTR ldmia sp!,[....pc]^ error.*/
  4746. /*chy 2004-05-23 should compare the Abort Models*/
  4747. if (state->Aborted) {
  4748. if (BIT (21) && LHSReg != 15)
  4749. if (!
  4750. (state->abortSig && state->Aborted
  4751. && state->lateabtSig == LOW))
  4752. LSBase = WBBase;
  4753. TAKEABORT;
  4754. } else if (BIT (21) && LHSReg != 15)
  4755. LSBase = WBBase;
  4756. if (BIT (15) && !state->Aborted) {
  4757. /* PC is in the reg list. */
  4758. #ifdef MODE32
  4759. //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
  4760. if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
  4761. state->Cpsr = GETSPSR (state->Bank);
  4762. ARMul_CPSRAltered (state);
  4763. }
  4764. WriteR15 (state, PC);
  4765. #else
  4766. //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
  4767. if (state->Mode == USER26MODE || state->Mode == USER32MODE ) {
  4768. /* Protect bits in user mode. */
  4769. ASSIGNN ((state->Reg[15] & NBIT) != 0);
  4770. ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
  4771. ASSIGNC ((state->Reg[15] & CBIT) != 0);
  4772. ASSIGNV ((state->Reg[15] & VBIT) != 0);
  4773. } else
  4774. ARMul_R15Altered (state);
  4775. FLUSHPIPE;
  4776. #endif
  4777. }
  4778. //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
  4779. if (!BIT (15) && state->Mode != USER26MODE
  4780. && state->Mode != USER32MODE )
  4781. /* Restore the correct bank. */
  4782. (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
  4783. /* To write back the final register. */
  4784. ARMul_Icycles (state, 1, 0L);
  4785. /* chy 2004-05-23, see below
  4786. if (state->Aborted)
  4787. {
  4788. if (BIT (21) && LHSReg != 15)
  4789. LSBase = WBBase;
  4790. TAKEABORT;
  4791. }
  4792. */
  4793. }
  4794. /* This function does the work of storing the registers listed in an STM
  4795. instruction, when the S bit is clear. The code here is always increment
  4796. after, it's up to the caller to get the input address correct and to
  4797. handle base register modification. */
  4798. static void
  4799. StoreMult (ARMul_State * state,
  4800. ARMword instr, ARMword address, ARMword WBBase) {
  4801. ARMword temp;
  4802. UNDEF_LSMNoRegs;
  4803. UNDEF_LSMPCBase;
  4804. UNDEF_LSMBaseInListWb;
  4805. if (!TFLAG)
  4806. /* N-cycle, increment the PC and update the NextInstr state. */
  4807. BUSUSEDINCPCN;
  4808. #ifndef MODE32
  4809. if (VECTORACCESS (address) || ADDREXCEPT (address))
  4810. INTERNALABORT (address);
  4811. if (BIT (15))
  4812. PATCHR15;
  4813. #endif
  4814. /* N cycle first. */
  4815. for (temp = 0; !BIT (temp); temp++);
  4816. #ifdef MODE32
  4817. ARMul_StoreWordN (state, address, state->Reg[temp++]);
  4818. #else
  4819. if (state->Aborted) {
  4820. (void) ARMul_LoadWordN (state, address);
  4821. /* Fake the Stores as Loads. */
  4822. for (; temp < 16; temp++)
  4823. if (BIT (temp)) {
  4824. /* Save this register. */
  4825. address += 4;
  4826. (void) ARMul_LoadWordS (state, address);
  4827. }
  4828. if (BIT (21) && LHSReg != 15)
  4829. LSBase = WBBase;
  4830. TAKEABORT;
  4831. return;
  4832. } else
  4833. ARMul_StoreWordN (state, address, state->Reg[temp++]);
  4834. #endif
  4835. if (state->abortSig && !state->Aborted) {
  4836. //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
  4837. state->Aborted = ARMul_DataAbortV;
  4838. }
  4839. //chy 2004-05-23, needn't store other when aborted
  4840. if (state->Aborted)
  4841. goto L_stm_takeabort;
  4842. /* S cycles from here on. */
  4843. for (; temp < 16; temp++)
  4844. if (BIT (temp)) {
  4845. /* Save this register. */
  4846. address += 4;
  4847. ARMul_StoreWordS (state, address, state->Reg[temp]);
  4848. if (state->abortSig && !state->Aborted) {
  4849. /*XScale_set_fsr_far (state,
  4850. ARMul_CP15_R5_ST_ALIGN,
  4851. address);*/
  4852. state->Aborted = ARMul_DataAbortV;
  4853. }
  4854. //chy 2004-05-23, needn't store other when aborted
  4855. if (state->Aborted)
  4856. goto L_stm_takeabort;
  4857. }
  4858. //chy 2004-05-23,should compare the Abort Models
  4859. L_stm_takeabort:
  4860. if (BIT (21) && LHSReg != 15) {
  4861. if (!
  4862. (state->abortSig && state->Aborted
  4863. && state->lateabtSig == LOW))
  4864. LSBase = WBBase;
  4865. }
  4866. if (state->Aborted)
  4867. TAKEABORT;
  4868. }
  4869. /* This function does the work of storing the registers listed in an STM
  4870. instruction when the S bit is set. The code here is always increment
  4871. after, it's up to the caller to get the input address correct and to
  4872. handle base register modification. */
  4873. static void
  4874. StoreSMult (ARMul_State * state,
  4875. ARMword instr, ARMword address, ARMword WBBase) {
  4876. ARMword temp;
  4877. UNDEF_LSMNoRegs;
  4878. UNDEF_LSMPCBase;
  4879. UNDEF_LSMBaseInListWb;
  4880. BUSUSEDINCPCN;
  4881. #ifndef MODE32
  4882. if (VECTORACCESS (address) || ADDREXCEPT (address))
  4883. INTERNALABORT (address);
  4884. if (BIT (15))
  4885. PATCHR15;
  4886. #endif
  4887. if (state->Bank != USERBANK) {
  4888. /* Force User Bank. */
  4889. (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
  4890. UNDEF_LSMUserBankWb;
  4891. }
  4892. for (temp = 0; !BIT (temp); temp++); /* N cycle first. */
  4893. #ifdef MODE32
  4894. ARMul_StoreWordN (state, address, state->Reg[temp++]);
  4895. #else
  4896. if (state->Aborted) {
  4897. (void) ARMul_LoadWordN (state, address);
  4898. for (; temp < 16; temp++)
  4899. /* Fake the Stores as Loads. */
  4900. if (BIT (temp)) {
  4901. /* Save this register. */
  4902. address += 4;
  4903. (void) ARMul_LoadWordS (state, address);
  4904. }
  4905. if (BIT (21) && LHSReg != 15)
  4906. LSBase = WBBase;
  4907. TAKEABORT;
  4908. return;
  4909. } else
  4910. ARMul_StoreWordN (state, address, state->Reg[temp++]);
  4911. #endif
  4912. if (state->abortSig && !state->Aborted) {
  4913. //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
  4914. state->Aborted = ARMul_DataAbortV;
  4915. }
  4916. //chy 2004-05-23, needn't store other when aborted
  4917. if (state->Aborted)
  4918. goto L_stm_s_takeabort;
  4919. /* S cycles from here on. */
  4920. for (; temp < 16; temp++)
  4921. if (BIT (temp)) {
  4922. /* Save this register. */
  4923. address += 4;
  4924. ARMul_StoreWordS (state, address, state->Reg[temp]);
  4925. if (state->abortSig && !state->Aborted) {
  4926. /*XScale_set_fsr_far (state,
  4927. ARMul_CP15_R5_ST_ALIGN,
  4928. address);*/
  4929. state->Aborted = ARMul_DataAbortV;
  4930. }
  4931. //chy 2004-05-23, needn't store other when aborted
  4932. if (state->Aborted)
  4933. goto L_stm_s_takeabort;
  4934. }
  4935. //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
  4936. if (state->Mode != USER26MODE && state->Mode != USER32MODE )
  4937. /* Restore the correct bank. */
  4938. (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
  4939. //chy 2004-05-23,should compare the Abort Models
  4940. L_stm_s_takeabort:
  4941. if (BIT (21) && LHSReg != 15) {
  4942. if (!
  4943. (state->abortSig && state->Aborted
  4944. && state->lateabtSig == LOW))
  4945. LSBase = WBBase;
  4946. }
  4947. if (state->Aborted)
  4948. TAKEABORT;
  4949. }
  4950. /* This function does the work of adding two 32bit values
  4951. together, and calculating if a carry has occurred. */
  4952. static ARMword
  4953. Add32 (ARMword a1, ARMword a2, int *carry) {
  4954. ARMword result = (a1 + a2);
  4955. unsigned int uresult = (unsigned int) result;
  4956. unsigned int ua1 = (unsigned int) a1;
  4957. /* If (result == RdLo) and (state->Reg[nRdLo] == 0),
  4958. or (result > RdLo) then we have no carry. */
  4959. if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1))
  4960. *carry = 1;
  4961. else
  4962. *carry = 0;
  4963. return result;
  4964. }
  4965. /* This function does the work of multiplying
  4966. two 32bit values to give a 64bit result. */
  4967. static unsigned
  4968. Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc) {
  4969. /* Operand register numbers. */
  4970. int nRdHi, nRdLo, nRs, nRm;
  4971. ARMword RdHi = 0, RdLo = 0, Rm;
  4972. /* Cycle count. */
  4973. int scount;
  4974. nRdHi = BITS (16, 19);
  4975. nRdLo = BITS (12, 15);
  4976. nRs = BITS (8, 11);
  4977. nRm = BITS (0, 3);
  4978. /* Needed to calculate the cycle count. */
  4979. Rm = state->Reg[nRm];
  4980. /* Check for illegal operand combinations first. */
  4981. if (nRdHi != 15
  4982. && nRdLo != 15
  4983. && nRs != 15
  4984. //&& nRm != 15 && nRdHi != nRdLo && nRdHi != nRm && nRdLo != nRm) {
  4985. && nRm != 15 && nRdHi != nRdLo ) {
  4986. /* Intermediate results. */
  4987. ARMword lo, mid1, mid2, hi;
  4988. int carry;
  4989. ARMword Rs = state->Reg[nRs];
  4990. int sign = 0;
  4991. if (msigned) {
  4992. /* Compute sign of result and adjust operands if necessary. */
  4993. sign = (Rm ^ Rs) & 0x80000000;
  4994. if (((signed int) Rm) < 0)
  4995. Rm = -Rm;
  4996. if (((signed int) Rs) < 0)
  4997. Rs = -Rs;
  4998. }
  4999. /* We can split the 32x32 into four 16x16 operations. This
  5000. ensures that we do not lose precision on 32bit only hosts. */
  5001. lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF));
  5002. mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
  5003. mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF));
  5004. hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
  5005. /* We now need to add all of these results together, taking
  5006. care to propogate the carries from the additions. */
  5007. RdLo = Add32 (lo, (mid1 << 16), &carry);
  5008. RdHi = carry;
  5009. RdLo = Add32 (RdLo, (mid2 << 16), &carry);
  5010. RdHi += (carry + ((mid1 >> 16) & 0xFFFF) +
  5011. ((mid2 >> 16) & 0xFFFF) + hi);
  5012. if (sign) {
  5013. /* Negate result if necessary. */
  5014. RdLo = ~RdLo;
  5015. RdHi = ~RdHi;
  5016. if (RdLo == 0xFFFFFFFF) {
  5017. RdLo = 0;
  5018. RdHi += 1;
  5019. } else
  5020. RdLo += 1;
  5021. }
  5022. state->Reg[nRdLo] = RdLo;
  5023. state->Reg[nRdHi] = RdHi;
  5024. } else {
  5025. fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS, instr=0x%x\n", instr);
  5026. }
  5027. if (scc)
  5028. /* Ensure that both RdHi and RdLo are used to compute Z,
  5029. but don't let RdLo's sign bit make it to N. */
  5030. ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
  5031. /* The cycle count depends on whether the instruction is a signed or
  5032. unsigned multiply, and what bits are clear in the multiplier. */
  5033. if (msigned && (Rm & ((unsigned) 1 << 31)))
  5034. /* Invert the bits to make the check against zero. */
  5035. Rm = ~Rm;
  5036. if ((Rm & 0xFFFFFF00) == 0)
  5037. scount = 1;
  5038. else if ((Rm & 0xFFFF0000) == 0)
  5039. scount = 2;
  5040. else if ((Rm & 0xFF000000) == 0)
  5041. scount = 3;
  5042. else
  5043. scount = 4;
  5044. return 2 + scount;
  5045. }
  5046. /* This function does the work of multiplying two 32bit
  5047. values and adding a 64bit value to give a 64bit result. */
  5048. static unsigned
  5049. MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc) {
  5050. unsigned scount;
  5051. ARMword RdLo, RdHi;
  5052. int nRdHi, nRdLo;
  5053. int carry = 0;
  5054. nRdHi = BITS (16, 19);
  5055. nRdLo = BITS (12, 15);
  5056. RdHi = state->Reg[nRdHi];
  5057. RdLo = state->Reg[nRdLo];
  5058. scount = Multiply64 (state, instr, msigned, LDEFAULT);
  5059. RdLo = Add32 (RdLo, state->Reg[nRdLo], &carry);
  5060. RdHi = (RdHi + state->Reg[nRdHi]) + carry;
  5061. state->Reg[nRdLo] = RdLo;
  5062. state->Reg[nRdHi] = RdHi;
  5063. if (scc)
  5064. /* Ensure that both RdHi and RdLo are used to compute Z,
  5065. but don't let RdLo's sign bit make it to N. */
  5066. ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
  5067. /* Extra cycle for addition. */
  5068. return scount + 1;
  5069. }
  5070. /* Attempt to emulate an ARMv6 instruction.
  5071. Returns non-zero upon success. */
  5072. static int handle_v6_insn(ARMul_State* state, ARMword instr) {
  5073. switch (BITS(20, 27)) {
  5074. case 0x03:
  5075. printf ("Unhandled v6 insn: ldr\n");
  5076. break;
  5077. case 0x04: // UMAAL
  5078. {
  5079. const u8 rm_idx = BITS(8, 11);
  5080. const u8 rn_idx = BITS(0, 3);
  5081. const u8 rd_lo_idx = BITS(12, 15);
  5082. const u8 rd_hi_idx = BITS(16, 19);
  5083. const u32 rm_val = state->Reg[rm_idx];
  5084. const u32 rn_val = state->Reg[rn_idx];
  5085. const u32 rd_lo_val = state->Reg[rd_lo_idx];
  5086. const u32 rd_hi_val = state->Reg[rd_hi_idx];
  5087. const u64 result = (rn_val * rm_val) + rd_lo_val + rd_hi_val;
  5088. state->Reg[rd_lo_idx] = (result & 0xFFFFFFFF);
  5089. state->Reg[rd_hi_idx] = ((result >> 32) & 0xFFFFFFFF);
  5090. return 1;
  5091. }
  5092. break;
  5093. case 0x06:
  5094. printf ("Unhandled v6 insn: mls/str\n");
  5095. break;
  5096. case 0x16:
  5097. printf ("Unhandled v6 insn: smi\n");
  5098. break;
  5099. case 0x18:
  5100. if (BITS(4, 7) == 0x9) {
  5101. /* strex */
  5102. u32 l = LHSReg;
  5103. u32 r = RHSReg;
  5104. u32 lhs = LHS;
  5105. bool enter = false;
  5106. if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true;
  5107. //StoreWord(state, lhs, RHS)
  5108. if (state->Aborted) {
  5109. TAKEABORT;
  5110. }
  5111. if (enter) {
  5112. ARMul_StoreWordS(state, lhs, RHS);
  5113. state->Reg[DESTReg] = 0;
  5114. }
  5115. else {
  5116. state->Reg[DESTReg] = 1;
  5117. }
  5118. return 1;
  5119. }
  5120. printf ("Unhandled v6 insn: strex\n");
  5121. break;
  5122. case 0x19:
  5123. /* ldrex */
  5124. if (BITS(4, 7) == 0x9) {
  5125. u32 lhs = LHS;
  5126. state->currentexaddr = lhs;
  5127. state->currentexval = ARMul_ReadWord(state, lhs);
  5128. LoadWord(state, instr, lhs);
  5129. return 1;
  5130. }
  5131. printf ("Unhandled v6 insn: ldrex\n");
  5132. break;
  5133. case 0x1a:
  5134. printf ("Unhandled v6 insn: strexd\n");
  5135. break;
  5136. case 0x1b:
  5137. printf ("Unhandled v6 insn: ldrexd\n");
  5138. break;
  5139. case 0x1c:
  5140. if (BITS(4, 7) == 0x9) {
  5141. /* strexb */
  5142. u32 lhs = LHS;
  5143. bool enter = false;
  5144. if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true;
  5145. BUSUSEDINCPCN;
  5146. if (state->Aborted) {
  5147. TAKEABORT;
  5148. }
  5149. if (enter) {
  5150. ARMul_StoreByte(state, lhs, RHS);
  5151. state->Reg[DESTReg] = 0;
  5152. }
  5153. else {
  5154. state->Reg[DESTReg] = 1;
  5155. }
  5156. //printf("In %s, strexb not implemented\n", __FUNCTION__);
  5157. UNDEF_LSRBPC;
  5158. /* WRITESDEST (dest); */
  5159. return 1;
  5160. }
  5161. printf ("Unhandled v6 insn: strexb\n");
  5162. break;
  5163. case 0x1d:
  5164. if ((BITS(4, 7)) == 0x9) {
  5165. /* ldrexb */
  5166. u32 lhs = LHS;
  5167. LoadByte(state, instr, lhs, LUNSIGNED);
  5168. state->currentexaddr = lhs;
  5169. state->currentexval = (u32)ARMul_ReadByte(state, lhs);
  5170. //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]);
  5171. //printf("ldrexb\n");
  5172. //printf("instr is %x rm is %d\n", instr, BITS(16, 19));
  5173. //exit(-1);
  5174. //printf("In %s, ldrexb not implemented\n", __FUNCTION__);
  5175. return 1;
  5176. }
  5177. printf ("Unhandled v6 insn: ldrexb\n");
  5178. break;
  5179. case 0x1e:
  5180. printf ("Unhandled v6 insn: strexh\n");
  5181. break;
  5182. case 0x1f:
  5183. printf ("Unhandled v6 insn: ldrexh\n");
  5184. break;
  5185. case 0x30:
  5186. printf ("Unhandled v6 insn: movw\n");
  5187. break;
  5188. case 0x32:
  5189. printf ("Unhandled v6 insn: nop/sev/wfe/wfi/yield\n");
  5190. break;
  5191. case 0x34:
  5192. printf ("Unhandled v6 insn: movt\n");
  5193. break;
  5194. case 0x3f:
  5195. printf ("Unhandled v6 insn: rbit\n");
  5196. break;
  5197. case 0x61: // SADD16, SASX, SSAX, and SSUB16
  5198. if ((instr & 0xFF0) == 0xf10 || (instr & 0xFF0) == 0xf30 ||
  5199. (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf70)
  5200. {
  5201. const u8 rd_idx = BITS(12, 15);
  5202. const u8 rm_idx = BITS(0, 3);
  5203. const u8 rn_idx = BITS(16, 19);
  5204. const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
  5205. const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF);
  5206. const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
  5207. const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
  5208. s32 lo_result;
  5209. s32 hi_result;
  5210. // SADD16
  5211. if ((instr & 0xFF0) == 0xf10) {
  5212. lo_result = (rn_lo + rm_lo);
  5213. hi_result = (rn_hi + rm_hi);
  5214. }
  5215. // SASX
  5216. else if ((instr & 0xFF0) == 0xf30) {
  5217. lo_result = (rn_lo - rm_hi);
  5218. hi_result = (rn_hi + rm_lo);
  5219. }
  5220. // SSAX
  5221. else if ((instr & 0xFF0) == 0xf50) {
  5222. lo_result = (rn_lo + rm_hi);
  5223. hi_result = (rn_hi - rm_lo);
  5224. }
  5225. // SSUB16
  5226. else {
  5227. lo_result = (rn_lo - rm_lo);
  5228. hi_result = (rn_hi - rm_hi);
  5229. }
  5230. state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
  5231. if (lo_result >= 0) {
  5232. state->GEFlag |= (1 << 16);
  5233. state->GEFlag |= (1 << 17);
  5234. } else {
  5235. state->GEFlag &= ~(1 << 16);
  5236. state->GEFlag &= ~(1 << 17);
  5237. }
  5238. if (hi_result >= 0) {
  5239. state->GEFlag |= (1 << 18);
  5240. state->GEFlag |= (1 << 19);
  5241. } else {
  5242. state->GEFlag &= ~(1 << 18);
  5243. state->GEFlag &= ~(1 << 19);
  5244. }
  5245. return 1;
  5246. }
  5247. // SADD8/SSUB8
  5248. else if ((instr & 0xFF0) == 0xf90 || (instr & 0xFF0) == 0xff0)
  5249. {
  5250. const u8 rd_idx = BITS(12, 15);
  5251. const u8 rm_idx = BITS(0, 3);
  5252. const u8 rn_idx = BITS(16, 19);
  5253. const u32 rm_val = state->Reg[rm_idx];
  5254. const u32 rn_val = state->Reg[rn_idx];
  5255. s32 lo_val1, lo_val2;
  5256. s32 hi_val1, hi_val2;
  5257. // SADD8
  5258. if ((instr & 0xFF0) == 0xf90) {
  5259. lo_val1 = (s32)(s8)(rn_val & 0xFF) + (s32)(s8)(rm_val & 0xFF);
  5260. lo_val2 = (s32)(s8)((rn_val >> 8) & 0xFF) + (s32)(s8)((rm_val >> 8) & 0xFF);
  5261. hi_val1 = (s32)(s8)((rn_val >> 16) & 0xFF) + (s32)(s8)((rm_val >> 16) & 0xFF);
  5262. hi_val2 = (s32)(s8)((rn_val >> 24) & 0xFF) + (s32)(s8)((rm_val >> 24) & 0xFF);
  5263. }
  5264. // SSUB8
  5265. else {
  5266. lo_val1 = (s32)(s8)(rn_val & 0xFF) - (s32)(s8)(rm_val & 0xFF);
  5267. lo_val2 = (s32)(s8)((rn_val >> 8) & 0xFF) - (s32)(s8)((rm_val >> 8) & 0xFF);
  5268. hi_val1 = (s32)(s8)((rn_val >> 16) & 0xFF) - (s32)(s8)((rm_val >> 16) & 0xFF);
  5269. hi_val2 = (s32)(s8)((rn_val >> 24) & 0xFF) - (s32)(s8)((rm_val >> 24) & 0xFF);
  5270. }
  5271. if (lo_val1 >= 0)
  5272. state->GEFlag |= (1 << 16);
  5273. else
  5274. state->GEFlag &= ~(1 << 16);
  5275. if (lo_val2 >= 0)
  5276. state->GEFlag |= (1 << 17);
  5277. else
  5278. state->GEFlag &= ~(1 << 17);
  5279. if (hi_val1 >= 0)
  5280. state->GEFlag |= (1 << 18);
  5281. else
  5282. state->GEFlag &= ~(1 << 18);
  5283. if (hi_val2 >= 0)
  5284. state->GEFlag |= (1 << 19);
  5285. else
  5286. state->GEFlag &= ~(1 << 19);
  5287. state->Reg[rd_idx] = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24));
  5288. return 1;
  5289. }
  5290. else {
  5291. printf("Unhandled v6 insn: %08x", instr);
  5292. }
  5293. break;
  5294. case 0x62: // QADD16, QASX, QSAX, QSUB16, QADD8, and QSUB8
  5295. {
  5296. const u8 op2 = BITS(5, 7);
  5297. const u8 rd_idx = BITS(12, 15);
  5298. const u8 rn_idx = BITS(16, 19);
  5299. const u8 rm_idx = BITS(0, 3);
  5300. const u16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
  5301. const u16 rm_hi = ((state->Reg[rm_idx] >> 0x10) & 0xFFFF);
  5302. const u16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
  5303. const u16 rn_hi = ((state->Reg[rn_idx] >> 0x10) & 0xFFFF);
  5304. u16 lo_result = 0;
  5305. u16 hi_result = 0;
  5306. // QADD16
  5307. if (op2 == 0x00) {
  5308. lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
  5309. hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
  5310. }
  5311. // QASX
  5312. else if (op2 == 0x01) {
  5313. lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
  5314. hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
  5315. }
  5316. // QSAX
  5317. else if (op2 == 0x02) {
  5318. lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
  5319. hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
  5320. }
  5321. // QSUB16
  5322. else if (op2 == 0x03) {
  5323. lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
  5324. hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
  5325. }
  5326. // QADD8
  5327. else if (op2 == 0x04) {
  5328. lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
  5329. ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
  5330. hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
  5331. ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
  5332. }
  5333. // QSUB8
  5334. else if (op2 == 0x07) {
  5335. lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
  5336. ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
  5337. hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
  5338. ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
  5339. }
  5340. state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
  5341. return 1;
  5342. }
  5343. break;
  5344. case 0x63:
  5345. printf ("Unhandled v6 insn: shadd/shsub\n");
  5346. break;
  5347. case 0x65:
  5348. {
  5349. u32 rd = (instr >> 12) & 0xF;
  5350. u32 rn = (instr >> 16) & 0xF;
  5351. u32 rm = (instr >> 0) & 0xF;
  5352. u32 from = state->Reg[rn];
  5353. u32 to = state->Reg[rm];
  5354. if ((instr & 0xFF0) == 0xF10 || (instr & 0xFF0) == 0xF70) { // UADD16/USUB16
  5355. u32 h1, h2;
  5356. state->Cpsr &= 0xfff0ffff;
  5357. if ((instr & 0x0F0) == 0x070) { // USUB16
  5358. h1 = ((u16)from - (u16)to);
  5359. h2 = ((u16)(from >> 16) - (u16)(to >> 16));
  5360. if (!(h1 & 0xffff0000))
  5361. state->GEFlag |= (3 << 16);
  5362. else
  5363. state->GEFlag &= ~(3 << 16);
  5364. if (!(h2 & 0xffff0000))
  5365. state->GEFlag |= (3 << 18);
  5366. else
  5367. state->GEFlag &= ~(3 << 18);
  5368. }
  5369. else { // UADD16
  5370. h1 = ((u16)from + (u16)to);
  5371. h2 = ((u16)(from >> 16) + (u16)(to >> 16));
  5372. if (h1 & 0xffff0000)
  5373. state->GEFlag |= (3 << 16);
  5374. else
  5375. state->GEFlag &= ~(3 << 16);
  5376. if (h2 & 0xffff0000)
  5377. state->GEFlag |= (3 << 18);
  5378. else
  5379. state->GEFlag &= ~(3 << 18);
  5380. }
  5381. state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16));
  5382. return 1;
  5383. }
  5384. else
  5385. if ((instr & 0xFF0) == 0xF90 || (instr & 0xFF0) == 0xFF0) { // UADD8/USUB8
  5386. u32 b1, b2, b3, b4;
  5387. state->Cpsr &= 0xfff0ffff;
  5388. if ((instr & 0x0F0) == 0x0F0) { // USUB8
  5389. b1 = ((u8)from - (u8)to);
  5390. b2 = ((u8)(from >> 8) - (u8)(to >> 8));
  5391. b3 = ((u8)(from >> 16) - (u8)(to >> 16));
  5392. b4 = ((u8)(from >> 24) - (u8)(to >> 24));
  5393. if (!(b1 & 0xffffff00))
  5394. state->GEFlag |= (1 << 16);
  5395. else
  5396. state->GEFlag &= ~(1 << 16);
  5397. if (!(b2 & 0xffffff00))
  5398. state->GEFlag |= (1 << 17);
  5399. else
  5400. state->GEFlag &= ~(1 << 17);
  5401. if (!(b3 & 0xffffff00))
  5402. state->GEFlag |= (1 << 18);
  5403. else
  5404. state->GEFlag &= ~(1 << 18);
  5405. if (!(b4 & 0xffffff00))
  5406. state->GEFlag |= (1 << 19);
  5407. else
  5408. state->GEFlag &= ~(1 << 19);
  5409. }
  5410. else { // UADD8
  5411. b1 = ((u8)from + (u8)to);
  5412. b2 = ((u8)(from >> 8) + (u8)(to >> 8));
  5413. b3 = ((u8)(from >> 16) + (u8)(to >> 16));
  5414. b4 = ((u8)(from >> 24) + (u8)(to >> 24));
  5415. if (b1 & 0xffffff00)
  5416. state->GEFlag |= (1 << 16);
  5417. else
  5418. state->GEFlag &= ~(1 << 16);
  5419. if (b2 & 0xffffff00)
  5420. state->GEFlag |= (1 << 17);
  5421. else
  5422. state->GEFlag &= ~(1 << 17);
  5423. if (b3 & 0xffffff00)
  5424. state->GEFlag |= (1 << 18);
  5425. else
  5426. state->GEFlag &= ~(1 << 18);
  5427. if (b4 & 0xffffff00)
  5428. state->GEFlag |= (1 << 19);
  5429. else
  5430. state->GEFlag &= ~(1 << 19);
  5431. }
  5432. state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24);
  5433. return 1;
  5434. }
  5435. }
  5436. printf("Unhandled v6 insn: uasx/usax\n");
  5437. break;
  5438. case 0x66: // UQADD16, UQASX, UQSAX, UQSUB16, UQADD8, and UQSUB8
  5439. {
  5440. const u8 rd_idx = BITS(12, 15);
  5441. const u8 rm_idx = BITS(0, 3);
  5442. const u8 rn_idx = BITS(16, 19);
  5443. const u8 op2 = BITS(5, 7);
  5444. const u32 rm_val = state->Reg[rm_idx];
  5445. const u32 rn_val = state->Reg[rn_idx];
  5446. u16 lo_val = 0;
  5447. u16 hi_val = 0;
  5448. // UQADD16
  5449. if (op2 == 0x00) {
  5450. lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
  5451. hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
  5452. }
  5453. // UQASX
  5454. else if (op2 == 0x01) {
  5455. lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
  5456. hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
  5457. }
  5458. // UQSAX
  5459. else if (op2 == 0x02) {
  5460. lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
  5461. hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
  5462. }
  5463. // UQSUB16
  5464. else if (op2 == 0x03) {
  5465. lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
  5466. hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
  5467. }
  5468. // UQADD8
  5469. else if (op2 == 0x04) {
  5470. lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
  5471. ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
  5472. hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
  5473. ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
  5474. }
  5475. // UQSUB8
  5476. else {
  5477. lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
  5478. ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
  5479. hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
  5480. ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
  5481. }
  5482. state->Reg[rd_idx] = ((lo_val & 0xFFFF) | hi_val << 16);
  5483. return 1;
  5484. }
  5485. break;
  5486. case 0x67: // UHADD16, UHASX, UHSAX, UHSUB16, UHADD8, and UHSUB8.
  5487. {
  5488. const u8 op2 = BITS(5, 7);
  5489. const u8 rm_idx = BITS(0, 3);
  5490. const u8 rn_idx = BITS(16, 19);
  5491. const u8 rd_idx = BITS(12, 15);
  5492. const u32 rm_val = state->Reg[rm_idx];
  5493. const u32 rn_val = state->Reg[rn_idx];
  5494. if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
  5495. {
  5496. u32 lo_val = 0;
  5497. u32 hi_val = 0;
  5498. // UHADD16
  5499. if (op2 == 0x00) {
  5500. lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
  5501. hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
  5502. }
  5503. // UHASX
  5504. else if (op2 == 0x01) {
  5505. lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
  5506. hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
  5507. }
  5508. // UHSAX
  5509. else if (op2 == 0x02) {
  5510. lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
  5511. hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
  5512. }
  5513. // UHSUB16
  5514. else if (op2 == 0x03) {
  5515. lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
  5516. hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
  5517. }
  5518. lo_val >>= 1;
  5519. hi_val >>= 1;
  5520. state->Reg[rd_idx] = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
  5521. return 1;
  5522. }
  5523. else if (op2 == 0x04 || op2 == 0x07) {
  5524. u32 sum1;
  5525. u32 sum2;
  5526. u32 sum3;
  5527. u32 sum4;
  5528. // UHADD8
  5529. if (op2 == 0x04) {
  5530. sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
  5531. sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
  5532. sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
  5533. sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
  5534. }
  5535. // UHSUB8
  5536. else {
  5537. sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
  5538. sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
  5539. sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
  5540. sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
  5541. }
  5542. sum1 >>= 1;
  5543. sum2 >>= 1;
  5544. sum3 >>= 1;
  5545. sum4 >>= 1;
  5546. state->Reg[rd_idx] = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
  5547. return 1;
  5548. }
  5549. }
  5550. break;
  5551. case 0x68:
  5552. {
  5553. u32 rd = (instr >> 12) & 0xF;
  5554. u32 rn = (instr >> 16) & 0xF;
  5555. u32 rm = (instr >> 0) & 0xF;
  5556. u32 from = state->Reg[rn];
  5557. u32 to = state->Reg[rm];
  5558. u32 cpsr = ARMul_GetCPSR(state);
  5559. if ((instr & 0xFF0) == 0xFB0) { // SEL
  5560. u32 result;
  5561. if (cpsr & (1 << 16))
  5562. result = from & 0xff;
  5563. else
  5564. result = to & 0xff;
  5565. if (cpsr & (1 << 17))
  5566. result |= from & 0x0000ff00;
  5567. else
  5568. result |= to & 0x0000ff00;
  5569. if (cpsr & (1 << 18))
  5570. result |= from & 0x00ff0000;
  5571. else
  5572. result |= to & 0x00ff0000;
  5573. if (cpsr & (1 << 19))
  5574. result |= from & 0xff000000;
  5575. else
  5576. result |= to & 0xff000000;
  5577. state->Reg[rd] = result;
  5578. return 1;
  5579. }
  5580. }
  5581. printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n");
  5582. break;
  5583. case 0x6a: // SSAT, SSAT16, SXTB, and SXTAB
  5584. {
  5585. const u8 op2 = BITS(5, 7);
  5586. // SSAT16
  5587. if (op2 == 0x01) {
  5588. const u8 rd_idx = BITS(12, 15);
  5589. const u8 rn_idx = BITS(0, 3);
  5590. const u8 num_bits = BITS(16, 19) + 1;
  5591. const s16 min = -(0x8000 >> (16 - num_bits));
  5592. const s16 max = (0x7FFF >> (16 - num_bits));
  5593. s16 rn_lo = (state->Reg[rn_idx]);
  5594. s16 rn_hi = (state->Reg[rn_idx] >> 16);
  5595. if (rn_lo > max) {
  5596. rn_lo = max;
  5597. SETQ;
  5598. } else if (rn_lo < min) {
  5599. rn_lo = min;
  5600. SETQ;
  5601. }
  5602. if (rn_hi > max) {
  5603. rn_hi = max;
  5604. SETQ;
  5605. } else if (rn_hi < min) {
  5606. rn_hi = min;
  5607. SETQ;
  5608. }
  5609. state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16);
  5610. return 1;
  5611. }
  5612. else if (op2 == 0x03) {
  5613. const u8 rotation = BITS(10, 11) * 8;
  5614. u32 rm = ((state->Reg[BITS(0, 3)] >> rotation) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotation)) & 0xFF) & 0xFF);
  5615. if (rm & 0x80)
  5616. rm |= 0xffffff00;
  5617. // SXTB, otherwise SXTAB
  5618. if (BITS(16, 19) == 0xf)
  5619. state->Reg[BITS(12, 15)] = rm;
  5620. else
  5621. state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
  5622. return 1;
  5623. }
  5624. else {
  5625. printf("Unimplemented op: SSAT");
  5626. }
  5627. }
  5628. break;
  5629. case 0x6b: // REV, REV16, SXTH, and SXTAH
  5630. {
  5631. const u8 op2 = BITS(5, 7);
  5632. // REV
  5633. if (op2 == 0x01) {
  5634. DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
  5635. return 1;
  5636. }
  5637. // REV16
  5638. else if (op2 == 0x05) {
  5639. DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
  5640. return 1;
  5641. }
  5642. else if (op2 == 0x03) {
  5643. const u8 rotate = BITS(10, 11) * 8;
  5644. u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
  5645. if (rm & 0x8000)
  5646. rm |= 0xffff0000;
  5647. // SXTH, otherwise SXTAH
  5648. if (BITS(16, 19) == 15)
  5649. state->Reg[BITS(12, 15)] = rm;
  5650. else
  5651. state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
  5652. return 1;
  5653. }
  5654. }
  5655. break;
  5656. case 0x6c: // UXTB16 and UXTAB16
  5657. {
  5658. const u8 rm_idx = BITS(0, 3);
  5659. const u8 rn_idx = BITS(16, 19);
  5660. const u8 rd_idx = BITS(12, 15);
  5661. const u32 rm_val = state->Reg[rm_idx];
  5662. const u32 rn_val = state->Reg[rn_idx];
  5663. const u32 rotation = BITS(10, 11) * 8;
  5664. const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
  5665. // UXTB16
  5666. if ((instr & 0xf03f0) == 0xf0070) {
  5667. state->Reg[rd_idx] = rotated_rm & 0x00FF00FF;
  5668. }
  5669. else { // UXTAB16
  5670. const u8 lo_rotated = (rotated_rm & 0xFF);
  5671. const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
  5672. const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
  5673. const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
  5674. state->Reg[rd_idx] = ((hi_result << 16) | (lo_result & 0xFFFF));
  5675. }
  5676. return 1;
  5677. }
  5678. break;
  5679. case 0x6e: // USAT, USAT16, UXTB, and UXTAB
  5680. {
  5681. const u8 op2 = BITS(5, 7);
  5682. // USAT16
  5683. if (op2 == 0x01) {
  5684. const u8 rd_idx = BITS(12, 15);
  5685. const u8 rn_idx = BITS(0, 3);
  5686. const u8 num_bits = BITS(16, 19);
  5687. const s16 max = 0xFFFF >> (16 - num_bits);
  5688. s16 rn_lo = (state->Reg[rn_idx]);
  5689. s16 rn_hi = (state->Reg[rn_idx] >> 16);
  5690. if (max < rn_lo) {
  5691. rn_lo = max;
  5692. SETQ;
  5693. } else if (rn_lo < 0) {
  5694. rn_lo = 0;
  5695. SETQ;
  5696. }
  5697. if (max < rn_hi) {
  5698. rn_hi = max;
  5699. SETQ;
  5700. } else if (rn_hi < 0) {
  5701. rn_hi = 0;
  5702. SETQ;
  5703. }
  5704. state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
  5705. return 1;
  5706. }
  5707. else if (op2 == 0x03) {
  5708. const u8 rotate = BITS(10, 11) * 8;
  5709. const u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFF) & 0xFF);
  5710. if (BITS(16, 19) == 0xf)
  5711. /* UXTB */
  5712. state->Reg[BITS(12, 15)] = rm;
  5713. else
  5714. /* UXTAB */
  5715. state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
  5716. return 1;
  5717. }
  5718. else {
  5719. printf("Unimplemented op: USAT");
  5720. }
  5721. }
  5722. break;
  5723. case 0x6f: // UXTH, UXTAH, and REVSH.
  5724. {
  5725. const u8 op2 = BITS(5, 7);
  5726. // REVSH
  5727. if (op2 == 0x05) {
  5728. DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
  5729. if (DEST & 0x8000)
  5730. DEST |= 0xffff0000;
  5731. return 1;
  5732. }
  5733. // UXTH and UXTAH
  5734. else if (op2 == 0x03) {
  5735. const u8 rotate = BITS(10, 11) * 8;
  5736. const ARMword rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
  5737. // UXTH
  5738. if (BITS(16, 19) == 0xf) {
  5739. state->Reg[BITS(12, 15)] = rm;
  5740. }
  5741. // UXTAH
  5742. else {
  5743. state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
  5744. }
  5745. return 1;
  5746. }
  5747. }
  5748. case 0x70:
  5749. // ichfly
  5750. // SMUAD, SMUSD, SMLAD, and SMLSD
  5751. if ((instr & 0xf0d0) == 0xf010 || (instr & 0xf0d0) == 0xf050 ||
  5752. (instr & 0xd0) == 0x10 || (instr & 0xd0) == 0x50)
  5753. {
  5754. const u8 rd_idx = BITS(16, 19);
  5755. const u8 rn_idx = BITS(0, 3);
  5756. const u8 rm_idx = BITS(8, 11);
  5757. const u8 ra_idx = BITS(12, 15);
  5758. const bool do_swap = (BIT(5) == 1);
  5759. u32 rm_val = state->Reg[rm_idx];
  5760. const u32 rn_val = state->Reg[rn_idx];
  5761. if (do_swap)
  5762. rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
  5763. const s16 rm_lo = (rm_val & 0xFFFF);
  5764. const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
  5765. const s16 rn_lo = (rn_val & 0xFFFF);
  5766. const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
  5767. const u32 product1 = (rn_lo * rm_lo);
  5768. const u32 product2 = (rn_hi * rm_hi);
  5769. // SMUAD and SMLAD
  5770. if (BIT(6) == 0) {
  5771. state->Reg[rd_idx] = product1 + product2;
  5772. if (BITS(12, 15) != 15) {
  5773. state->Reg[rd_idx] += state->Reg[ra_idx];
  5774. if (ARMul_AddOverflowQ(product1 + product2, state->Reg[ra_idx]))
  5775. SETQ;
  5776. }
  5777. if (ARMul_AddOverflowQ(product1, product2))
  5778. SETQ;
  5779. }
  5780. // SMUSD and SMLSD
  5781. else {
  5782. state->Reg[rd_idx] = product1 - product2;
  5783. if (BITS(12, 15) != 15) {
  5784. state->Reg[rd_idx] += state->Reg[ra_idx];
  5785. if (ARMul_AddOverflowQ(product1 - product2, state->Reg[ra_idx]))
  5786. SETQ;
  5787. }
  5788. }
  5789. return 1;
  5790. }
  5791. break;
  5792. case 0x74: // SMLALD and SMLSLD
  5793. {
  5794. const u8 rm_idx = BITS(8, 11);
  5795. const u8 rn_idx = BITS(0, 3);
  5796. const u8 rdlo_idx = BITS(12, 15);
  5797. const u8 rdhi_idx = BITS(16, 19);
  5798. const bool do_swap = (BIT(5) == 1);
  5799. const u32 rdlo_val = state->Reg[rdlo_idx];
  5800. const u32 rdhi_val = state->Reg[rdhi_idx];
  5801. const u32 rn_val = state->Reg[rn_idx];
  5802. u32 rm_val = state->Reg[rm_idx];
  5803. if (do_swap)
  5804. rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
  5805. const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
  5806. const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
  5807. s64 result;
  5808. // SMLALD
  5809. if (BIT(6) == 0) {
  5810. result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
  5811. }
  5812. // SMLSLD
  5813. else {
  5814. result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
  5815. }
  5816. state->Reg[rdlo_idx] = (result & 0xFFFFFFFF);
  5817. state->Reg[rdhi_idx] = ((result >> 32) & 0xFFFFFFFF);
  5818. return 1;
  5819. }
  5820. break;
  5821. case 0x75: // SMMLA, SMMUL, and SMMLS
  5822. {
  5823. const u8 rm_idx = BITS(8, 11);
  5824. const u8 rn_idx = BITS(0, 3);
  5825. const u8 ra_idx = BITS(12, 15);
  5826. const u8 rd_idx = BITS(16, 19);
  5827. const bool do_round = (BIT(5) == 1);
  5828. const u32 rm_val = state->Reg[rm_idx];
  5829. const u32 rn_val = state->Reg[rn_idx];
  5830. // Assume SMMUL by default.
  5831. s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
  5832. if (ra_idx != 15) {
  5833. const u32 ra_val = state->Reg[ra_idx];
  5834. // SMMLA, otherwise SMMLS
  5835. if (BIT(6) == 0)
  5836. result += ((s64)ra_val << 32);
  5837. else
  5838. result = ((s64)ra_val << 32) - result;
  5839. }
  5840. if (do_round)
  5841. result += 0x80000000;
  5842. state->Reg[rd_idx] = ((result >> 32) & 0xFFFFFFFF);
  5843. return 1;
  5844. }
  5845. break;
  5846. case 0x78:
  5847. if (BITS(20, 24) == 0x18)
  5848. {
  5849. const u8 rm_idx = BITS(8, 11);
  5850. const u8 rn_idx = BITS(0, 3);
  5851. const u8 rd_idx = BITS(16, 19);
  5852. const u32 rm_val = state->Reg[rm_idx];
  5853. const u32 rn_val = state->Reg[rn_idx];
  5854. const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
  5855. const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
  5856. const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
  5857. const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
  5858. u32 finalDif = (diff1 + diff2 + diff3 + diff4);
  5859. // Op is USADA8 if true.
  5860. const u8 ra_idx = BITS(12, 15);
  5861. if (ra_idx != 15)
  5862. finalDif += state->Reg[ra_idx];
  5863. state->Reg[rd_idx] = finalDif;
  5864. return 1;
  5865. }
  5866. break;
  5867. case 0x7a:
  5868. printf ("Unhandled v6 insn: usbfx\n");
  5869. break;
  5870. case 0x7c:
  5871. printf ("Unhandled v6 insn: bfc/bfi\n");
  5872. break;
  5873. case 0x84:
  5874. printf ("Unhandled v6 insn: srs\n");
  5875. break;
  5876. default:
  5877. break;
  5878. }
  5879. printf("Unhandled v6 insn: UNKNOWN: %08x %08X\n", instr, BITS(20, 27));
  5880. return 0;
  5881. }