armemu.c 140 KB

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