| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947 |
- // Copyright 2012 Michael Kang, 2014 Citra Emulator Project
- // Licensed under GPLv2 or any later version
- // Refer to the license.txt file included.
- #define CITRA_IGNORE_EXIT(x)
- #include <algorithm>
- #include <cstdio>
- #include "common/logging/log.h"
- #include "common/profiler.h"
- #include "core/memory.h"
- #include "core/hle/svc.h"
- #include "core/arm/disassembler/arm_disasm.h"
- #include "core/arm/dyncom/arm_dyncom_dec.h"
- #include "core/arm/dyncom/arm_dyncom_interpreter.h"
- #include "core/arm/dyncom/arm_dyncom_thumb.h"
- #include "core/arm/dyncom/arm_dyncom_run.h"
- #include "core/arm/skyeye_common/armstate.h"
- #include "core/arm/skyeye_common/armsupp.h"
- #include "core/arm/skyeye_common/vfp/vfp.h"
- Common::Profiling::TimingCategory profile_execute("DynCom::Execute");
- Common::Profiling::TimingCategory profile_decode("DynCom::Decode");
- enum {
- COND = (1 << 0),
- NON_BRANCH = (1 << 1),
- DIRECT_BRANCH = (1 << 2),
- INDIRECT_BRANCH = (1 << 3),
- CALL = (1 << 4),
- RET = (1 << 5),
- END_OF_PAGE = (1 << 6),
- THUMB = (1 << 7)
- };
- #define RM BITS(sht_oper, 0, 3)
- #define RS BITS(sht_oper, 8, 11)
- #define glue(x, y) x ## y
- #define DPO(s) glue(DataProcessingOperands, s)
- #define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i))
- #define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i))
- #define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
- #define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
- typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper);
- static int CondPassed(ARMul_State* cpu, unsigned int cond) {
- const u32 NFLAG = cpu->NFlag;
- const u32 ZFLAG = cpu->ZFlag;
- const u32 CFLAG = cpu->CFlag;
- const u32 VFLAG = cpu->VFlag;
- int temp = 0;
- switch (cond) {
- case 0x0:
- temp = ZFLAG;
- break;
- case 0x1: // NE
- temp = !ZFLAG;
- break;
- case 0x2: // CS
- temp = CFLAG;
- break;
- case 0x3: // CC
- temp = !CFLAG;
- break;
- case 0x4: // MI
- temp = NFLAG;
- break;
- case 0x5: // PL
- temp = !NFLAG;
- break;
- case 0x6: // VS
- temp = VFLAG;
- break;
- case 0x7: // VC
- temp = !VFLAG;
- break;
- case 0x8: // HI
- temp = (CFLAG && !ZFLAG);
- break;
- case 0x9: // LS
- temp = (!CFLAG || ZFLAG);
- break;
- case 0xa: // GE
- temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
- break;
- case 0xb: // LT
- temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
- break;
- case 0xc: // GT
- temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG));
- break;
- case 0xd: // LE
- temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
- break;
- case 0xe: // AL
- temp = 1;
- break;
- case 0xf:
- temp = 1;
- break;
- }
- return temp;
- }
- static unsigned int DPO(Immediate)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int immed_8 = BITS(sht_oper, 0, 7);
- unsigned int rotate_imm = BITS(sht_oper, 8, 11);
- unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);
- if (rotate_imm == 0)
- cpu->shifter_carry_out = cpu->CFlag;
- else
- cpu->shifter_carry_out = BIT(shifter_operand, 31);
- return shifter_operand;
- }
- static unsigned int DPO(Register)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- return shifter_operand;
- }
- static unsigned int DPO(LogicalShiftLeftByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
- int shift_imm = BITS(sht_oper, 7, 11);
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand;
- if (shift_imm == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else {
- shifter_operand = rm << shift_imm;
- cpu->shifter_carry_out = BIT(rm, 32 - shift_imm);
- }
- return shifter_operand;
- }
- static unsigned int DPO(LogicalShiftLeftByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
- int shifter_operand;
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 7) < 32) {
- shifter_operand = rm << BITS(rs, 0, 7);
- cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7));
- } else if (BITS(rs, 0, 7) == 32) {
- shifter_operand = 0;
- cpu->shifter_carry_out = BIT(rm, 0);
- } else {
- shifter_operand = 0;
- cpu->shifter_carry_out = 0;
- }
- return shifter_operand;
- }
- static unsigned int DPO(LogicalShiftRightByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand;
- int shift_imm = BITS(sht_oper, 7, 11);
- if (shift_imm == 0) {
- shifter_operand = 0;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = rm >> shift_imm;
- cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
- }
- return shifter_operand;
- }
- static unsigned int DPO(LogicalShiftRightByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand;
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 7) < 32) {
- shifter_operand = rm >> BITS(rs, 0, 7);
- cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
- } else if (BITS(rs, 0, 7) == 32) {
- shifter_operand = 0;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = 0;
- cpu->shifter_carry_out = 0;
- }
- return shifter_operand;
- }
- static unsigned int DPO(ArithmeticShiftRightByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand;
- int shift_imm = BITS(sht_oper, 7, 11);
- if (shift_imm == 0) {
- if (BIT(rm, 31) == 0)
- shifter_operand = 0;
- else
- shifter_operand = 0xFFFFFFFF;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = static_cast<int>(rm) >> shift_imm;
- cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
- }
- return shifter_operand;
- }
- static unsigned int DPO(ArithmeticShiftRightByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand;
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 7) < 32) {
- shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7);
- cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
- } else {
- if (BIT(rm, 31) == 0)
- shifter_operand = 0;
- else
- shifter_operand = 0xffffffff;
- cpu->shifter_carry_out = BIT(rm, 31);
- }
- return shifter_operand;
- }
- static unsigned int DPO(RotateRightByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int shifter_operand;
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- int shift_imm = BITS(sht_oper, 7, 11);
- if (shift_imm == 0) {
- shifter_operand = (cpu->CFlag << 31) | (rm >> 1);
- cpu->shifter_carry_out = BIT(rm, 0);
- } else {
- shifter_operand = ROTATE_RIGHT_32(rm, shift_imm);
- cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
- }
- return shifter_operand;
- }
- static unsigned int DPO(RotateRightByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- unsigned int shifter_operand;
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 4) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4));
- cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1);
- }
- return shifter_operand;
- }
- typedef void (*get_addr_fp_t)(ARMul_State *cpu, unsigned int inst, unsigned int &virt_addr);
- struct ldst_inst {
- unsigned int inst;
- get_addr_fp_t get_addr;
- };
- #define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0)
- #define LnSWoUB(s) glue(LnSWoUB, s)
- #define MLnS(s) glue(MLnS, s)
- #define LdnStM(s) glue(LdnStM, s)
- #define W_BIT BIT(inst, 21)
- #define U_BIT BIT(inst, 23)
- #define I_BIT BIT(inst, 25)
- #define P_BIT BIT(inst, 24)
- #define OFFSET_12 BITS(inst, 0, 11)
- static void LnSWoUB(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr;
- if (U_BIT)
- addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
- else
- addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
- virt_addr = addr;
- }
- static void LnSWoUB(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- unsigned int addr;
- if (U_BIT)
- addr = rn + rm;
- else
- addr = rn - rm;
- virt_addr = addr;
- }
- static void LnSWoUB(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
- if (U_BIT)
- cpu->Reg[Rn] += OFFSET_12;
- else
- cpu->Reg[Rn] -= OFFSET_12;
- virt_addr = addr;
- }
- static void LnSWoUB(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr;
- if (U_BIT)
- addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
- else
- addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
- virt_addr = addr;
- if (CondPassed(cpu, BITS(inst, 28, 31)))
- cpu->Reg[Rn] = addr;
- }
- static void MLnS(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int addr;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- if (U_BIT)
- addr = rn + rm;
- else
- addr = rn - rm;
- virt_addr = addr;
- if (CondPassed(cpu, BITS(inst, 28, 31)))
- cpu->Reg[Rn] = addr;
- }
- static void LnSWoUB(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- unsigned int addr;
- if (U_BIT)
- addr = rn + rm;
- else
- addr = rn - rm;
- virt_addr = addr;
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- cpu->Reg[Rn] = addr;
- }
- }
- static void LnSWoUB(ScaledRegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int shift = BITS(inst, 5, 6);
- unsigned int shift_imm = BITS(inst, 7, 11);
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int index = 0;
- unsigned int addr;
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- switch (shift) {
- case 0:
- index = rm << shift_imm;
- break;
- case 1:
- if (shift_imm == 0) {
- index = 0;
- } else {
- index = rm >> shift_imm;
- }
- break;
- case 2:
- if (shift_imm == 0) { // ASR #32
- if (BIT(rm, 31) == 1)
- index = 0xFFFFFFFF;
- else
- index = 0;
- } else {
- index = static_cast<int>(rm) >> shift_imm;
- }
- break;
- case 3:
- if (shift_imm == 0) {
- index = (cpu->CFlag << 31) | (rm >> 1);
- } else {
- index = ROTATE_RIGHT_32(rm, shift_imm);
- }
- break;
- }
- if (U_BIT)
- addr = rn + index;
- else
- addr = rn - index;
- virt_addr = addr;
- if (CondPassed(cpu, BITS(inst, 28, 31)))
- cpu->Reg[Rn] = addr;
- }
- static void LnSWoUB(ScaledRegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int shift = BITS(inst, 5, 6);
- unsigned int shift_imm = BITS(inst, 7, 11);
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int index = 0;
- unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- switch (shift) {
- case 0:
- index = rm << shift_imm;
- break;
- case 1:
- if (shift_imm == 0) {
- index = 0;
- } else {
- index = rm >> shift_imm;
- }
- break;
- case 2:
- if (shift_imm == 0) { // ASR #32
- if (BIT(rm, 31) == 1)
- index = 0xFFFFFFFF;
- else
- index = 0;
- } else {
- index = static_cast<int>(rm) >> shift_imm;
- }
- break;
- case 3:
- if (shift_imm == 0) {
- index = (cpu->CFlag << 31) | (rm >> 1);
- } else {
- index = ROTATE_RIGHT_32(rm, shift_imm);
- }
- break;
- }
- virt_addr = addr;
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- if (U_BIT)
- cpu->Reg[Rn] += index;
- else
- cpu->Reg[Rn] -= index;
- }
- }
- static void LnSWoUB(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- virt_addr = CHECK_READ_REG15_WA(cpu, Rn);
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- if (U_BIT) {
- cpu->Reg[Rn] += rm;
- } else {
- cpu->Reg[Rn] -= rm;
- }
- }
- }
- static void MLnS(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int immedL = BITS(inst, 0, 3);
- unsigned int immedH = BITS(inst, 8, 11);
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr;
- unsigned int offset_8 = (immedH << 4) | immedL;
- if (U_BIT)
- addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8;
- else
- addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8;
- virt_addr = addr;
- }
- static void MLnS(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int addr;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- if (U_BIT)
- addr = rn + rm;
- else
- addr = rn - rm;
- virt_addr = addr;
- }
- static void MLnS(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int immedH = BITS(inst, 8, 11);
- unsigned int immedL = BITS(inst, 0, 3);
- unsigned int addr;
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int offset_8 = (immedH << 4) | immedL;
- if (U_BIT)
- addr = rn + offset_8;
- else
- addr = rn - offset_8;
- virt_addr = addr;
- if (CondPassed(cpu, BITS(inst, 28, 31)))
- cpu->Reg[Rn] = addr;
- }
- static void MLnS(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int immedH = BITS(inst, 8, 11);
- unsigned int immedL = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- virt_addr = rn;
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- unsigned int offset_8 = (immedH << 4) | immedL;
- if (U_BIT)
- rn += offset_8;
- else
- rn -= offset_8;
- cpu->Reg[Rn] = rn;
- }
- }
- static void MLnS(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- virt_addr = CHECK_READ_REG15_WA(cpu, Rn);
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- if (U_BIT)
- cpu->Reg[Rn] += rm;
- else
- cpu->Reg[Rn] -= rm;
- }
- }
- static void LdnStM(DecrementBefore)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- int count = 0;
- while (i) {
- if (i & 1) count++;
- i = i >> 1;
- }
- virt_addr = CHECK_READ_REG15_WA(cpu, Rn) - count * 4;
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21))
- cpu->Reg[Rn] -= count * 4;
- }
- static void LdnStM(IncrementBefore)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- int count = 0;
- while (i) {
- if (i & 1) count++;
- i = i >> 1;
- }
- virt_addr = CHECK_READ_REG15_WA(cpu, Rn) + 4;
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21))
- cpu->Reg[Rn] += count * 4;
- }
- static void LdnStM(IncrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- int count = 0;
- while(i) {
- if (i & 1) count++;
- i = i >> 1;
- }
- virt_addr = CHECK_READ_REG15_WA(cpu, Rn);
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21))
- cpu->Reg[Rn] += count * 4;
- }
- static void LdnStM(DecrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- int count = 0;
- while(i) {
- if(i & 1) count++;
- i = i >> 1;
- }
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int start_addr = rn - count * 4 + 4;
- virt_addr = start_addr;
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
- cpu->Reg[Rn] -= count * 4;
- }
- }
- static void LnSWoUB(ScaledRegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int shift = BITS(inst, 5, 6);
- unsigned int shift_imm = BITS(inst, 7, 11);
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int index = 0;
- unsigned int addr;
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- switch (shift) {
- case 0:
- index = rm << shift_imm;
- break;
- case 1:
- if (shift_imm == 0) {
- index = 0;
- } else {
- index = rm >> shift_imm;
- }
- break;
- case 2:
- if (shift_imm == 0) { // ASR #32
- if (BIT(rm, 31) == 1)
- index = 0xFFFFFFFF;
- else
- index = 0;
- } else {
- index = static_cast<int>(rm) >> shift_imm;
- }
- break;
- case 3:
- if (shift_imm == 0) {
- index = (cpu->CFlag << 31) | (rm >> 1);
- } else {
- index = ROTATE_RIGHT_32(rm, shift_imm);
- }
- break;
- }
- if (U_BIT) {
- addr = rn + index;
- } else
- addr = rn - index;
- virt_addr = addr;
- }
- struct arm_inst {
- unsigned int idx;
- unsigned int cond;
- int br;
- char component[0];
- };
- struct generic_arm_inst {
- u32 Ra;
- u32 Rm;
- u32 Rn;
- u32 Rd;
- u8 op1;
- u8 op2;
- };
- struct adc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct add_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct orr_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct and_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct eor_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct bbl_inst {
- unsigned int L;
- int signed_immed_24;
- unsigned int next_addr;
- unsigned int jmp_addr;
- };
- struct bx_inst {
- unsigned int Rm;
- };
- struct blx_inst {
- union {
- int32_t signed_immed_24;
- uint32_t Rm;
- } val;
- unsigned int inst;
- };
- struct clz_inst {
- unsigned int Rm;
- unsigned int Rd;
- };
- struct cps_inst {
- unsigned int imod0;
- unsigned int imod1;
- unsigned int mmod;
- unsigned int A, I, F;
- unsigned int mode;
- };
- struct clrex_inst {
- };
- struct cpy_inst {
- unsigned int Rm;
- unsigned int Rd;
- };
- struct bic_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct sub_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct tst_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct cmn_inst {
- unsigned int I;
- unsigned int Rn;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct teq_inst {
- unsigned int I;
- unsigned int Rn;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct stm_inst {
- unsigned int inst;
- };
- struct bkpt_inst {
- u32 imm;
- };
- struct stc_inst {
- };
- struct ldc_inst {
- };
- struct swi_inst {
- unsigned int num;
- };
- struct cmp_inst {
- unsigned int I;
- unsigned int Rn;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct mov_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct mvn_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct rev_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int op1;
- unsigned int op2;
- };
- struct rsb_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct rsc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct sbc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
- };
- struct mul_inst {
- unsigned int S;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
- };
- struct smul_inst {
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
- unsigned int x;
- unsigned int y;
- };
- struct umull_inst {
- unsigned int S;
- unsigned int RdHi;
- unsigned int RdLo;
- unsigned int Rs;
- unsigned int Rm;
- };
- struct smlad_inst {
- unsigned int m;
- unsigned int Rm;
- unsigned int Rd;
- unsigned int Ra;
- unsigned int Rn;
- unsigned int op1;
- unsigned int op2;
- };
- struct smla_inst {
- unsigned int x;
- unsigned int y;
- unsigned int Rm;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rn;
- };
- struct smlalxy_inst {
- unsigned int x;
- unsigned int y;
- unsigned int RdLo;
- unsigned int RdHi;
- unsigned int Rm;
- unsigned int Rn;
- };
- struct ssat_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int imm5;
- unsigned int sat_imm;
- unsigned int shift_type;
- };
- struct umaal_inst {
- unsigned int Rn;
- unsigned int Rm;
- unsigned int RdHi;
- unsigned int RdLo;
- };
- struct umlal_inst {
- unsigned int S;
- unsigned int Rm;
- unsigned int Rs;
- unsigned int RdHi;
- unsigned int RdLo;
- };
- struct smlal_inst {
- unsigned int S;
- unsigned int Rm;
- unsigned int Rs;
- unsigned int RdHi;
- unsigned int RdLo;
- };
- struct smlald_inst {
- unsigned int RdLo;
- unsigned int RdHi;
- unsigned int Rm;
- unsigned int Rn;
- unsigned int swap;
- unsigned int op1;
- unsigned int op2;
- };
- struct mla_inst {
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
- };
- struct mrc_inst {
- unsigned int opcode_1;
- unsigned int opcode_2;
- unsigned int cp_num;
- unsigned int crn;
- unsigned int crm;
- unsigned int Rd;
- unsigned int inst;
- };
- struct mcr_inst {
- unsigned int opcode_1;
- unsigned int opcode_2;
- unsigned int cp_num;
- unsigned int crn;
- unsigned int crm;
- unsigned int Rd;
- unsigned int inst;
- };
- struct mcrr_inst {
- unsigned int opcode_1;
- unsigned int cp_num;
- unsigned int crm;
- unsigned int rt;
- unsigned int rt2;
- };
- struct mrs_inst {
- unsigned int R;
- unsigned int Rd;
- };
- struct msr_inst {
- unsigned int field_mask;
- unsigned int R;
- unsigned int inst;
- };
- struct pld_inst {
- };
- struct sxtb_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
- };
- struct sxtab_inst {
- unsigned int Rd;
- unsigned int Rn;
- unsigned int Rm;
- unsigned rotate;
- };
- struct sxtah_inst {
- unsigned int Rd;
- unsigned int Rn;
- unsigned int Rm;
- unsigned int rotate;
- };
- struct sxth_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
- };
- struct uxtab_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int rotate;
- unsigned int Rm;
- };
- struct uxtah_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int rotate;
- unsigned int Rm;
- };
- struct uxth_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
- };
- struct cdp_inst {
- unsigned int opcode_1;
- unsigned int CRn;
- unsigned int CRd;
- unsigned int cp_num;
- unsigned int opcode_2;
- unsigned int CRm;
- unsigned int inst;
- };
- struct uxtb_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
- };
- struct swp_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int Rm;
- };
- struct setend_inst {
- unsigned int set_bigend;
- };
- struct b_2_thumb {
- unsigned int imm;
- };
- struct b_cond_thumb {
- unsigned int imm;
- unsigned int cond;
- };
- struct bl_1_thumb {
- unsigned int imm;
- };
- struct bl_2_thumb {
- unsigned int imm;
- };
- struct blx_1_thumb {
- unsigned int imm;
- unsigned int instr;
- };
- struct pkh_inst {
- unsigned int Rm;
- unsigned int Rn;
- unsigned int Rd;
- unsigned char imm;
- };
- typedef arm_inst * ARM_INST_PTR;
- #define CACHE_BUFFER_SIZE (64 * 1024 * 2000)
- static char inst_buf[CACHE_BUFFER_SIZE];
- static int top = 0;
- static inline void *AllocBuffer(unsigned int size) {
- int start = top;
- top += size;
- if (top > CACHE_BUFFER_SIZE) {
- LOG_ERROR(Core_ARM11, "inst_buf is full");
- CITRA_IGNORE_EXIT(-1);
- }
- return (void *)&inst_buf[start];
- }
- static shtop_fp_t get_shtop(unsigned int inst) {
- if (BIT(inst, 25)) {
- return DPO(Immediate);
- } else if (BITS(inst, 4, 11) == 0) {
- return DPO(Register);
- } else if (BITS(inst, 4, 6) == 0) {
- return DPO(LogicalShiftLeftByImmediate);
- } else if (BITS(inst, 4, 7) == 1) {
- return DPO(LogicalShiftLeftByRegister);
- } else if (BITS(inst, 4, 6) == 2) {
- return DPO(LogicalShiftRightByImmediate);
- } else if (BITS(inst, 4, 7) == 3) {
- return DPO(LogicalShiftRightByRegister);
- } else if (BITS(inst, 4, 6) == 4) {
- return DPO(ArithmeticShiftRightByImmediate);
- } else if (BITS(inst, 4, 7) == 5) {
- return DPO(ArithmeticShiftRightByRegister);
- } else if (BITS(inst, 4, 6) == 6) {
- return DPO(RotateRightByImmediate);
- } else if (BITS(inst, 4, 7) == 7) {
- return DPO(RotateRightByRegister);
- }
- return nullptr;
- }
- static get_addr_fp_t get_calc_addr_op(unsigned int inst) {
- if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
- return LnSWoUB(ImmediateOffset);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
- return LnSWoUB(RegisterOffset);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
- return LnSWoUB(ScaledRegisterOffset);
- } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) {
- return LnSWoUB(ImmediatePreIndexed);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) {
- return LnSWoUB(RegisterPreIndexed);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) {
- return LnSWoUB(ScaledRegisterPreIndexed);
- } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) {
- return LnSWoUB(ImmediatePostIndexed);
- } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
- return LnSWoUB(RegisterPostIndexed);
- } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
- return LnSWoUB(ScaledRegisterPostIndexed);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
- return MLnS(ImmediateOffset);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
- return MLnS(RegisterOffset);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
- return MLnS(ImmediatePreIndexed);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
- return MLnS(RegisterPreIndexed);
- } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
- return MLnS(ImmediatePostIndexed);
- } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
- return MLnS(RegisterPostIndexed);
- } else if (BITS(inst, 23, 27) == 0x11) {
- return LdnStM(IncrementAfter);
- } else if (BITS(inst, 23, 27) == 0x13) {
- return LdnStM(IncrementBefore);
- } else if (BITS(inst, 23, 27) == 0x10) {
- return LdnStM(DecrementAfter);
- } else if (BITS(inst, 23, 27) == 0x12) {
- return LdnStM(DecrementBefore);
- }
- return nullptr;
- }
- #define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s)
- static ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
- adc_inst *inst_cream = (adc_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst));
- add_inst *inst_cream = (add_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst));
- and_inst *inst_cream = (and_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index)
- {
- #define POSBRANCH ((inst & 0x7fffff) << 2)
- #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2)
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst));
- bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
- if (BIT(inst, 24))
- inst_base->br = CALL;
- if (BITS(inst, 28, 31) <= 0xe)
- inst_base->br |= COND;
- inst_cream->L = BIT(inst, 24);
- inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst));
- bic_inst *inst_cream = (bic_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bkpt_inst));
- bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->imm = (BITS(inst, 8, 19) << 4) | BITS(inst, 0, 3);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst));
- blx_inst *inst_cream = (blx_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = INDIRECT_BRANCH;
- inst_cream->inst = inst;
- if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
- inst_cream->val.Rm = BITS(inst, 0, 3);
- } else {
- inst_cream->val.signed_immed_24 = BITS(inst, 0, 23);
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
- bx_inst *inst_cream = (bx_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = INDIRECT_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(bx)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index) {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
- cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->CRm = BITS(inst, 0, 3);
- inst_cream->CRd = BITS(inst, 12, 15);
- inst_cream->CRn = BITS(inst, 16, 19);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->opcode_1 = BITS(inst, 20, 23);
- inst_cream->inst = inst;
- LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst));
- clz_inst *inst_cream = (clz_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst));
- cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst));
- cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst));
- cps_inst *inst_cream = (cps_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->imod0 = BIT(inst, 18);
- inst_cream->imod1 = BIT(inst, 19);
- inst_cream->mmod = BIT(inst, 17);
- inst_cream->A = BIT(inst, 8);
- inst_cream->I = BIT(inst, 7);
- inst_cream->F = BIT(inst, 6);
- inst_cream->mode = BITS(inst, 0, 4);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
- mov_inst *inst_cream = (mov_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst));
- eor_inst *inst_cream = (eor_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- if (BIT(inst, 15)) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
- sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->rotate = BITS(inst, 10, 11);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
- uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst));
- uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index)
- {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- if (BITS(inst, 25, 27) == 2) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
- } else if (BITS(inst, 25, 27) == 3) {
- inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed);
- } else {
- DEBUG_MSG;
- }
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = (BITS(inst, 12, 15) == 15) ? INDIRECT_BRANCH : NON_BRANCH; // Branch if dest is R15
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(ldrex)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexh)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(ldrex)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexd)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(ldrex)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index)
- {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- if (BITS(inst, 25, 27) == 2) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
- } else if (BITS(inst, 25, 27) == 3) {
- inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed);
- } else {
- // Reaching this would indicate the thumb version
- // of this instruction, however the 3DS CPU doesn't
- // support this variant (the 3DS CPU is only ARMv6K,
- // while this variant is added in ARMv6T2).
- // So it's sufficient for citra to not implement this.
- DEBUG_MSG;
- }
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst));
- mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->crn = BITS(inst, 16, 19);
- inst_cream->crm = BITS(inst, 0, 3);
- inst_cream->opcode_1 = BITS(inst, 21, 23);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->inst = inst;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mcrr_inst));
- mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->crm = BITS(inst, 0, 3);
- inst_cream->opcode_1 = BITS(inst, 4, 7);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->rt = BITS(inst, 12, 15);
- inst_cream->rt2 = BITS(inst, 16, 19);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst));
- mla_inst *inst_cream = (mla_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 12, 15);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
- mov_inst *inst_cream = (mov_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst));
- mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->crn = BITS(inst, 16, 19);
- inst_cream->crm = BITS(inst, 0, 3);
- inst_cream->opcode_1 = BITS(inst, 21, 23);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->inst = inst;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(mcrr)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst));
- mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->R = BIT(inst, 22);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst));
- msr_inst *inst_cream = (msr_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->field_mask = BITS(inst, 16, 19);
- inst_cream->R = BIT(inst, 22);
- inst_cream->inst = inst;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst));
- mul_inst *inst_cream = (mul_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst));
- mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst));
- orr_inst *inst_cream = (orr_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- // NOP introduced in ARMv6K.
- static ARM_INST_PTR INTERPRETER_TRANSLATE(nop)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst));
- pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->imm = BITS(inst, 7, 11);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(pkhbt)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->op1 = BITS(inst, 21, 22);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(qadd)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(qadd)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(qadd)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
- rev_inst* const inst_cream = (rev_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(rev)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(rev)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
- inst_base->cond = AL;
- inst_base->idx = index;
- inst_base->br = INDIRECT_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst));
- rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst));
- rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
- sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(setend_inst));
- setend_inst* const inst_cream = (setend_inst*)inst_base->component;
- inst_base->cond = AL;
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->set_bigend = BIT(inst, 9);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sev)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
- smla_inst *inst_cream = (smla_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->x = BIT(inst, 5);
- inst_cream->y = BIT(inst, 6);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rn = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->m = BIT(inst, 5);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Ra = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(smlad)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(smlad)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(smlad)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
- umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlalxy_inst));
- smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->x = BIT(inst, 5);
- inst_cream->y = BIT(inst, 6);
- inst_cream->RdLo = BITS(inst, 12, 15);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->Rn = BITS(inst, 0, 4);
- inst_cream->Rm = BITS(inst, 8, 11);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Ra = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->m = BIT(inst, 6);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlald_inst));
- smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->RdLo = BITS(inst, 12, 15);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->swap = BIT(inst, 5);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(smlald)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->m = BIT(inst, 5);
- inst_cream->Ra = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(smmla)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(smmla)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
- smul_inst *inst_cream = (smul_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->x = BIT(inst, 5);
- inst_cream->y = BIT(inst, 6);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
- umull_inst *inst_cream = (umull_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->m = BIT(inst, 6);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 16, 19);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
- inst_base->cond = AL;
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst));
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->imm5 = BITS(inst, 7, 11);
- inst_cream->sat_imm = BITS(inst, 16, 20);
- inst_cream->shift_type = BIT(inst, 6);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst));
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->sat_imm = BITS(inst, 16, 19);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
- sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->rotate = BITS(inst, 10, 11);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
- uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
- uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index)
- {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- if (BITS(inst, 25, 27) == 2) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
- } else if (BITS(inst, 25, 27) == 3) {
- inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed);
- } else {
- DEBUG_MSG;
- }
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(strex)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(strexh)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(strex)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(strexd)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(strex)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index)
- {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- if (BITS(inst, 25, 27) == 2) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
- } else if (BITS(inst, 25, 27) == 3) {
- inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed);
- } else {
- // Reaching this would indicate the thumb version
- // of this instruction, however the 3DS CPU doesn't
- // support this variant (the 3DS CPU is only ARMv6K,
- // while this variant is added in ARMv6T2).
- // So it's sufficient for citra to not implement this.
- DEBUG_MSG;
- }
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst));
- sub_inst *inst_cream = (sub_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst));
- swi_inst *inst_cream = (swi_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->num = BITS(inst, 0, 23);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
- swp_inst *inst_cream = (swp_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
- swp_inst *inst_cream = (swp_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
- sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
- sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(sxtab16)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index) {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
- sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
- teq_inst *inst_cream = (teq_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst));
- tst_inst *inst_cream = (tst_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst));
- umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->RdLo = BITS(inst, 12, 15);
- inst_cream->RdHi = BITS(inst, 16, 19);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
- umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
- umull_inst *inst_cream = (umull_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb));
- b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
- inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0);
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb));
- b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
- inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0));
- inst_cream->cond = ((tinst >> 8) & 0xf);
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb));
- bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
- inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0));
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb));
- bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
- inst_cream->imm = (tinst & 0x07FF) << 1;
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index)
- {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb));
- blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
- inst_cream->imm = (tinst & 0x07FF) << 1;
- inst_cream->instr = tinst;
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->op1 = BITS(inst, 20, 24);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Ra = BITS(inst, 12, 15);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(usada8)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(ssat)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(ssat16)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
- uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index)
- {
- return INTERPRETER_TRANSLATE(uxtab16)(inst, index);
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(wfe)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(wfi)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
- }
- static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index)
- {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
- }
- // Floating point VFPv3 structures and instructions
- #define VFP_INTERPRETER_STRUCT
- #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
- #undef VFP_INTERPRETER_STRUCT
- #define VFP_INTERPRETER_TRANS
- #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
- #undef VFP_INTERPRETER_TRANS
- typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
- const transop_fp_t arm_instruction_trans[] = {
- INTERPRETER_TRANSLATE(vmla),
- INTERPRETER_TRANSLATE(vmls),
- INTERPRETER_TRANSLATE(vnmla),
- INTERPRETER_TRANSLATE(vnmla),
- INTERPRETER_TRANSLATE(vnmls),
- INTERPRETER_TRANSLATE(vnmul),
- INTERPRETER_TRANSLATE(vmul),
- INTERPRETER_TRANSLATE(vadd),
- INTERPRETER_TRANSLATE(vsub),
- INTERPRETER_TRANSLATE(vdiv),
- INTERPRETER_TRANSLATE(vmovi),
- INTERPRETER_TRANSLATE(vmovr),
- INTERPRETER_TRANSLATE(vabs),
- INTERPRETER_TRANSLATE(vneg),
- INTERPRETER_TRANSLATE(vsqrt),
- INTERPRETER_TRANSLATE(vcmp),
- INTERPRETER_TRANSLATE(vcmp2),
- INTERPRETER_TRANSLATE(vcvtbds),
- INTERPRETER_TRANSLATE(vcvtbff),
- INTERPRETER_TRANSLATE(vcvtbfi),
- INTERPRETER_TRANSLATE(vmovbrs),
- INTERPRETER_TRANSLATE(vmsr),
- INTERPRETER_TRANSLATE(vmovbrc),
- INTERPRETER_TRANSLATE(vmrs),
- INTERPRETER_TRANSLATE(vmovbcr),
- INTERPRETER_TRANSLATE(vmovbrrss),
- INTERPRETER_TRANSLATE(vmovbrrd),
- INTERPRETER_TRANSLATE(vstr),
- INTERPRETER_TRANSLATE(vpush),
- INTERPRETER_TRANSLATE(vstm),
- INTERPRETER_TRANSLATE(vpop),
- INTERPRETER_TRANSLATE(vldr),
- INTERPRETER_TRANSLATE(vldm),
- INTERPRETER_TRANSLATE(srs),
- INTERPRETER_TRANSLATE(rfe),
- INTERPRETER_TRANSLATE(bkpt),
- INTERPRETER_TRANSLATE(blx),
- INTERPRETER_TRANSLATE(cps),
- INTERPRETER_TRANSLATE(pld),
- INTERPRETER_TRANSLATE(setend),
- INTERPRETER_TRANSLATE(clrex),
- INTERPRETER_TRANSLATE(rev16),
- INTERPRETER_TRANSLATE(usad8),
- INTERPRETER_TRANSLATE(sxtb),
- INTERPRETER_TRANSLATE(uxtb),
- INTERPRETER_TRANSLATE(sxth),
- INTERPRETER_TRANSLATE(sxtb16),
- INTERPRETER_TRANSLATE(uxth),
- INTERPRETER_TRANSLATE(uxtb16),
- INTERPRETER_TRANSLATE(cpy),
- INTERPRETER_TRANSLATE(uxtab),
- INTERPRETER_TRANSLATE(ssub8),
- INTERPRETER_TRANSLATE(shsub8),
- INTERPRETER_TRANSLATE(ssubaddx),
- INTERPRETER_TRANSLATE(strex),
- INTERPRETER_TRANSLATE(strexb),
- INTERPRETER_TRANSLATE(swp),
- INTERPRETER_TRANSLATE(swpb),
- INTERPRETER_TRANSLATE(ssub16),
- INTERPRETER_TRANSLATE(ssat16),
- INTERPRETER_TRANSLATE(shsubaddx),
- INTERPRETER_TRANSLATE(qsubaddx),
- INTERPRETER_TRANSLATE(shaddsubx),
- INTERPRETER_TRANSLATE(shadd8),
- INTERPRETER_TRANSLATE(shadd16),
- INTERPRETER_TRANSLATE(sel),
- INTERPRETER_TRANSLATE(saddsubx),
- INTERPRETER_TRANSLATE(sadd8),
- INTERPRETER_TRANSLATE(sadd16),
- INTERPRETER_TRANSLATE(shsub16),
- INTERPRETER_TRANSLATE(umaal),
- INTERPRETER_TRANSLATE(uxtab16),
- INTERPRETER_TRANSLATE(usubaddx),
- INTERPRETER_TRANSLATE(usub8),
- INTERPRETER_TRANSLATE(usub16),
- INTERPRETER_TRANSLATE(usat16),
- INTERPRETER_TRANSLATE(usada8),
- INTERPRETER_TRANSLATE(uqsubaddx),
- INTERPRETER_TRANSLATE(uqsub8),
- INTERPRETER_TRANSLATE(uqsub16),
- INTERPRETER_TRANSLATE(uqaddsubx),
- INTERPRETER_TRANSLATE(uqadd8),
- INTERPRETER_TRANSLATE(uqadd16),
- INTERPRETER_TRANSLATE(sxtab),
- INTERPRETER_TRANSLATE(uhsubaddx),
- INTERPRETER_TRANSLATE(uhsub8),
- INTERPRETER_TRANSLATE(uhsub16),
- INTERPRETER_TRANSLATE(uhaddsubx),
- INTERPRETER_TRANSLATE(uhadd8),
- INTERPRETER_TRANSLATE(uhadd16),
- INTERPRETER_TRANSLATE(uaddsubx),
- INTERPRETER_TRANSLATE(uadd8),
- INTERPRETER_TRANSLATE(uadd16),
- INTERPRETER_TRANSLATE(sxtah),
- INTERPRETER_TRANSLATE(sxtab16),
- INTERPRETER_TRANSLATE(qadd8),
- INTERPRETER_TRANSLATE(bxj),
- INTERPRETER_TRANSLATE(clz),
- INTERPRETER_TRANSLATE(uxtah),
- INTERPRETER_TRANSLATE(bx),
- INTERPRETER_TRANSLATE(rev),
- INTERPRETER_TRANSLATE(blx),
- INTERPRETER_TRANSLATE(revsh),
- INTERPRETER_TRANSLATE(qadd),
- INTERPRETER_TRANSLATE(qadd16),
- INTERPRETER_TRANSLATE(qaddsubx),
- INTERPRETER_TRANSLATE(ldrex),
- INTERPRETER_TRANSLATE(qdadd),
- INTERPRETER_TRANSLATE(qdsub),
- INTERPRETER_TRANSLATE(qsub),
- INTERPRETER_TRANSLATE(ldrexb),
- INTERPRETER_TRANSLATE(qsub8),
- INTERPRETER_TRANSLATE(qsub16),
- INTERPRETER_TRANSLATE(smuad),
- INTERPRETER_TRANSLATE(smmul),
- INTERPRETER_TRANSLATE(smusd),
- INTERPRETER_TRANSLATE(smlsd),
- INTERPRETER_TRANSLATE(smlsld),
- INTERPRETER_TRANSLATE(smmla),
- INTERPRETER_TRANSLATE(smmls),
- INTERPRETER_TRANSLATE(smlald),
- INTERPRETER_TRANSLATE(smlad),
- INTERPRETER_TRANSLATE(smlaw),
- INTERPRETER_TRANSLATE(smulw),
- INTERPRETER_TRANSLATE(pkhtb),
- INTERPRETER_TRANSLATE(pkhbt),
- INTERPRETER_TRANSLATE(smul),
- INTERPRETER_TRANSLATE(smlalxy),
- INTERPRETER_TRANSLATE(smla),
- INTERPRETER_TRANSLATE(mcrr),
- INTERPRETER_TRANSLATE(mrrc),
- INTERPRETER_TRANSLATE(cmp),
- INTERPRETER_TRANSLATE(tst),
- INTERPRETER_TRANSLATE(teq),
- INTERPRETER_TRANSLATE(cmn),
- INTERPRETER_TRANSLATE(smull),
- INTERPRETER_TRANSLATE(umull),
- INTERPRETER_TRANSLATE(umlal),
- INTERPRETER_TRANSLATE(smlal),
- INTERPRETER_TRANSLATE(mul),
- INTERPRETER_TRANSLATE(mla),
- INTERPRETER_TRANSLATE(ssat),
- INTERPRETER_TRANSLATE(usat),
- INTERPRETER_TRANSLATE(mrs),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(and),
- INTERPRETER_TRANSLATE(bic),
- INTERPRETER_TRANSLATE(ldm),
- INTERPRETER_TRANSLATE(eor),
- INTERPRETER_TRANSLATE(add),
- INTERPRETER_TRANSLATE(rsb),
- INTERPRETER_TRANSLATE(rsc),
- INTERPRETER_TRANSLATE(sbc),
- INTERPRETER_TRANSLATE(adc),
- INTERPRETER_TRANSLATE(sub),
- INTERPRETER_TRANSLATE(orr),
- INTERPRETER_TRANSLATE(mvn),
- INTERPRETER_TRANSLATE(mov),
- INTERPRETER_TRANSLATE(stm),
- INTERPRETER_TRANSLATE(ldm),
- INTERPRETER_TRANSLATE(ldrsh),
- INTERPRETER_TRANSLATE(stm),
- INTERPRETER_TRANSLATE(ldm),
- INTERPRETER_TRANSLATE(ldrsb),
- INTERPRETER_TRANSLATE(strd),
- INTERPRETER_TRANSLATE(ldrh),
- INTERPRETER_TRANSLATE(strh),
- INTERPRETER_TRANSLATE(ldrd),
- INTERPRETER_TRANSLATE(strt),
- INTERPRETER_TRANSLATE(strbt),
- INTERPRETER_TRANSLATE(ldrbt),
- INTERPRETER_TRANSLATE(ldrt),
- INTERPRETER_TRANSLATE(mrc),
- INTERPRETER_TRANSLATE(mcr),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(ldrb),
- INTERPRETER_TRANSLATE(strb),
- INTERPRETER_TRANSLATE(ldr),
- INTERPRETER_TRANSLATE(ldrcond),
- INTERPRETER_TRANSLATE(str),
- INTERPRETER_TRANSLATE(cdp),
- INTERPRETER_TRANSLATE(stc),
- INTERPRETER_TRANSLATE(ldc),
- INTERPRETER_TRANSLATE(ldrexd),
- INTERPRETER_TRANSLATE(strexd),
- INTERPRETER_TRANSLATE(ldrexh),
- INTERPRETER_TRANSLATE(strexh),
- INTERPRETER_TRANSLATE(nop),
- INTERPRETER_TRANSLATE(yield),
- INTERPRETER_TRANSLATE(wfe),
- INTERPRETER_TRANSLATE(wfi),
- INTERPRETER_TRANSLATE(sev),
- INTERPRETER_TRANSLATE(swi),
- INTERPRETER_TRANSLATE(bbl),
- // All the thumb instructions should be placed the end of table
- INTERPRETER_TRANSLATE(b_2_thumb),
- INTERPRETER_TRANSLATE(b_cond_thumb),
- INTERPRETER_TRANSLATE(bl_1_thumb),
- INTERPRETER_TRANSLATE(bl_2_thumb),
- INTERPRETER_TRANSLATE(blx_1_thumb)
- };
- enum {
- FETCH_SUCCESS,
- FETCH_FAILURE
- };
- static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) {
- // Check if in Thumb mode
- ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size);
- if (ret == ThumbDecodeStatus::BRANCH) {
- int inst_index;
- int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
- u32 tinstr = GetThumbInstruction(inst, addr);
- switch ((tinstr & 0xF800) >> 11) {
- case 26:
- case 27:
- if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
- inst_index = table_length - 4;
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- } else {
- LOG_ERROR(Core_ARM11, "thumb decoder error");
- }
- break;
- case 28:
- // Branch 2, unconditional branch
- inst_index = table_length - 5;
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
- case 8:
- case 29:
- // For BLX 1 thumb instruction
- inst_index = table_length - 1;
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
- case 30:
- // For BL 1 thumb instruction
- inst_index = table_length - 3;
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
- case 31:
- // For BL 2 thumb instruction
- inst_index = table_length - 2;
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
- default:
- ret = ThumbDecodeStatus::UNDEFINED;
- break;
- }
- }
- return ret;
- }
- enum {
- KEEP_GOING,
- FETCH_EXCEPTION
- };
- static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) {
- Common::Profiling::ScopeTimer timer_decode(profile_decode);
- // Decode instruction, get index
- // Allocate memory and init InsCream
- // Go on next, until terminal instruction
- // Save start addr of basicblock in CreamCache
- ARM_INST_PTR inst_base = nullptr;
- unsigned int inst, inst_size = 4;
- int idx;
- int ret = NON_BRANCH;
- int size = 0; // instruction size of basic block
- bb_start = top;
- u32 phys_addr = addr;
- u32 pc_start = cpu->Reg[15];
- while (ret == NON_BRANCH) {
- inst = Memory::Read32(phys_addr & 0xFFFFFFFC);
- size++;
- // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM instruction
- if (cpu->TFlag) {
- uint32_t arm_inst;
- ThumbDecodeStatus state = DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base);
- // We have translated the Thumb branch instruction in the Thumb decoder
- if (state == ThumbDecodeStatus::BRANCH) {
- goto translated;
- }
- inst = arm_inst;
- }
- if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) {
- std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst);
- LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst);
- LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
- CITRA_IGNORE_EXIT(-1);
- }
- inst_base = arm_instruction_trans[idx](inst, idx);
- translated:
- phys_addr += inst_size;
- if ((phys_addr & 0xfff) == 0) {
- inst_base->br = END_OF_PAGE;
- }
- ret = inst_base->br;
- };
- cpu->instruction_cache[pc_start] = bb_start;
- return KEEP_GOING;
- }
- static int clz(unsigned int x) {
- int n;
- if (x == 0) return (32);
- n = 1;
- if ((x >> 16) == 0) { n = n + 16; x = x << 16;}
- if ((x >> 24) == 0) { n = n + 8; x = x << 8;}
- if ((x >> 28) == 0) { n = n + 4; x = x << 4;}
- if ((x >> 30) == 0) { n = n + 2; x = x << 2;}
- n = n - (x >> 31);
- return n;
- }
- unsigned InterpreterMainLoop(ARMul_State* cpu) {
- Common::Profiling::ScopeTimer timer_execute(profile_execute);
- #undef RM
- #undef RS
- #define CRn inst_cream->crn
- #define OPCODE_1 inst_cream->opcode_1
- #define OPCODE_2 inst_cream->opcode_2
- #define CRm inst_cream->crm
- #define RD cpu->Reg[inst_cream->Rd]
- #define RD2 cpu->Reg[inst_cream->Rd + 1]
- #define RN cpu->Reg[inst_cream->Rn]
- #define RM cpu->Reg[inst_cream->Rm]
- #define RS cpu->Reg[inst_cream->Rs]
- #define RDHI cpu->Reg[inst_cream->RdHi]
- #define RDLO cpu->Reg[inst_cream->RdLo]
- #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4)
- #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
- #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
- #define FETCH_INST if (inst_base->br != NON_BRANCH) goto DISPATCH; \
- inst_base = (arm_inst *)&inst_buf[ptr]
- #define INC_PC(l) ptr += sizeof(arm_inst) + l
- #define INC_PC_STUB ptr += sizeof(arm_inst)
- // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
- // clunky switch statement.
- #if defined __GNUC__ || defined __clang__
- #define GOTO_NEXT_INST \
- if (num_instrs >= cpu->NumInstrsToExecute) goto END; \
- num_instrs++; \
- goto *InstLabel[inst_base->idx]
- #else
- #define GOTO_NEXT_INST \
- if (num_instrs >= cpu->NumInstrsToExecute) goto END; \
- num_instrs++; \
- switch(inst_base->idx) { \
- case 0: goto VMLA_INST; \
- case 1: goto VMLS_INST; \
- case 2: goto VNMLA_INST; \
- case 3: goto VNMLA_INST; \
- case 4: goto VNMLS_INST; \
- case 5: goto VNMUL_INST; \
- case 6: goto VMUL_INST; \
- case 7: goto VADD_INST; \
- case 8: goto VSUB_INST; \
- case 9: goto VDIV_INST; \
- case 10: goto VMOVI_INST; \
- case 11: goto VMOVR_INST; \
- case 12: goto VABS_INST; \
- case 13: goto VNEG_INST; \
- case 14: goto VSQRT_INST; \
- case 15: goto VCMP_INST; \
- case 16: goto VCMP2_INST; \
- case 17: goto VCVTBDS_INST; \
- case 18: goto VCVTBFF_INST; \
- case 19: goto VCVTBFI_INST; \
- case 20: goto VMOVBRS_INST; \
- case 21: goto VMSR_INST; \
- case 22: goto VMOVBRC_INST; \
- case 23: goto VMRS_INST; \
- case 24: goto VMOVBCR_INST; \
- case 25: goto VMOVBRRSS_INST; \
- case 26: goto VMOVBRRD_INST; \
- case 27: goto VSTR_INST; \
- case 28: goto VPUSH_INST; \
- case 29: goto VSTM_INST; \
- case 30: goto VPOP_INST; \
- case 31: goto VLDR_INST; \
- case 32: goto VLDM_INST ; \
- case 33: goto SRS_INST; \
- case 34: goto RFE_INST; \
- case 35: goto BKPT_INST; \
- case 36: goto BLX_INST; \
- case 37: goto CPS_INST; \
- case 38: goto PLD_INST; \
- case 39: goto SETEND_INST; \
- case 40: goto CLREX_INST; \
- case 41: goto REV16_INST; \
- case 42: goto USAD8_INST; \
- case 43: goto SXTB_INST; \
- case 44: goto UXTB_INST; \
- case 45: goto SXTH_INST; \
- case 46: goto SXTB16_INST; \
- case 47: goto UXTH_INST; \
- case 48: goto UXTB16_INST; \
- case 49: goto CPY_INST; \
- case 50: goto UXTAB_INST; \
- case 51: goto SSUB8_INST; \
- case 52: goto SHSUB8_INST; \
- case 53: goto SSUBADDX_INST; \
- case 54: goto STREX_INST; \
- case 55: goto STREXB_INST; \
- case 56: goto SWP_INST; \
- case 57: goto SWPB_INST; \
- case 58: goto SSUB16_INST; \
- case 59: goto SSAT16_INST; \
- case 60: goto SHSUBADDX_INST; \
- case 61: goto QSUBADDX_INST; \
- case 62: goto SHADDSUBX_INST; \
- case 63: goto SHADD8_INST; \
- case 64: goto SHADD16_INST; \
- case 65: goto SEL_INST; \
- case 66: goto SADDSUBX_INST; \
- case 67: goto SADD8_INST; \
- case 68: goto SADD16_INST; \
- case 69: goto SHSUB16_INST; \
- case 70: goto UMAAL_INST; \
- case 71: goto UXTAB16_INST; \
- case 72: goto USUBADDX_INST; \
- case 73: goto USUB8_INST; \
- case 74: goto USUB16_INST; \
- case 75: goto USAT16_INST; \
- case 76: goto USADA8_INST; \
- case 77: goto UQSUBADDX_INST; \
- case 78: goto UQSUB8_INST; \
- case 79: goto UQSUB16_INST; \
- case 80: goto UQADDSUBX_INST; \
- case 81: goto UQADD8_INST; \
- case 82: goto UQADD16_INST; \
- case 83: goto SXTAB_INST; \
- case 84: goto UHSUBADDX_INST; \
- case 85: goto UHSUB8_INST; \
- case 86: goto UHSUB16_INST; \
- case 87: goto UHADDSUBX_INST; \
- case 88: goto UHADD8_INST; \
- case 89: goto UHADD16_INST; \
- case 90: goto UADDSUBX_INST; \
- case 91: goto UADD8_INST; \
- case 92: goto UADD16_INST; \
- case 93: goto SXTAH_INST; \
- case 94: goto SXTAB16_INST; \
- case 95: goto QADD8_INST; \
- case 96: goto BXJ_INST; \
- case 97: goto CLZ_INST; \
- case 98: goto UXTAH_INST; \
- case 99: goto BX_INST; \
- case 100: goto REV_INST; \
- case 101: goto BLX_INST; \
- case 102: goto REVSH_INST; \
- case 103: goto QADD_INST; \
- case 104: goto QADD16_INST; \
- case 105: goto QADDSUBX_INST; \
- case 106: goto LDREX_INST; \
- case 107: goto QDADD_INST; \
- case 108: goto QDSUB_INST; \
- case 109: goto QSUB_INST; \
- case 110: goto LDREXB_INST; \
- case 111: goto QSUB8_INST; \
- case 112: goto QSUB16_INST; \
- case 113: goto SMUAD_INST; \
- case 114: goto SMMUL_INST; \
- case 115: goto SMUSD_INST; \
- case 116: goto SMLSD_INST; \
- case 117: goto SMLSLD_INST; \
- case 118: goto SMMLA_INST; \
- case 119: goto SMMLS_INST; \
- case 120: goto SMLALD_INST; \
- case 121: goto SMLAD_INST; \
- case 122: goto SMLAW_INST; \
- case 123: goto SMULW_INST; \
- case 124: goto PKHTB_INST; \
- case 125: goto PKHBT_INST; \
- case 126: goto SMUL_INST; \
- case 127: goto SMLALXY_INST; \
- case 128: goto SMLA_INST; \
- case 129: goto MCRR_INST; \
- case 130: goto MRRC_INST; \
- case 131: goto CMP_INST; \
- case 132: goto TST_INST; \
- case 133: goto TEQ_INST; \
- case 134: goto CMN_INST; \
- case 135: goto SMULL_INST; \
- case 136: goto UMULL_INST; \
- case 137: goto UMLAL_INST; \
- case 138: goto SMLAL_INST; \
- case 139: goto MUL_INST; \
- case 140: goto MLA_INST; \
- case 141: goto SSAT_INST; \
- case 142: goto USAT_INST; \
- case 143: goto MRS_INST; \
- case 144: goto MSR_INST; \
- case 145: goto AND_INST; \
- case 146: goto BIC_INST; \
- case 147: goto LDM_INST; \
- case 148: goto EOR_INST; \
- case 149: goto ADD_INST; \
- case 150: goto RSB_INST; \
- case 151: goto RSC_INST; \
- case 152: goto SBC_INST; \
- case 153: goto ADC_INST; \
- case 154: goto SUB_INST; \
- case 155: goto ORR_INST; \
- case 156: goto MVN_INST; \
- case 157: goto MOV_INST; \
- case 158: goto STM_INST; \
- case 159: goto LDM_INST; \
- case 160: goto LDRSH_INST; \
- case 161: goto STM_INST; \
- case 162: goto LDM_INST; \
- case 163: goto LDRSB_INST; \
- case 164: goto STRD_INST; \
- case 165: goto LDRH_INST; \
- case 166: goto STRH_INST; \
- case 167: goto LDRD_INST; \
- case 168: goto STRT_INST; \
- case 169: goto STRBT_INST; \
- case 170: goto LDRBT_INST; \
- case 171: goto LDRT_INST; \
- case 172: goto MRC_INST; \
- case 173: goto MCR_INST; \
- case 174: goto MSR_INST; \
- case 175: goto MSR_INST; \
- case 176: goto MSR_INST; \
- case 177: goto MSR_INST; \
- case 178: goto MSR_INST; \
- case 179: goto LDRB_INST; \
- case 180: goto STRB_INST; \
- case 181: goto LDR_INST; \
- case 182: goto LDRCOND_INST ; \
- case 183: goto STR_INST; \
- case 184: goto CDP_INST; \
- case 185: goto STC_INST; \
- case 186: goto LDC_INST; \
- case 187: goto LDREXD_INST; \
- case 188: goto STREXD_INST; \
- case 189: goto LDREXH_INST; \
- case 190: goto STREXH_INST; \
- case 191: goto NOP_INST; \
- case 192: goto YIELD_INST; \
- case 193: goto WFE_INST; \
- case 194: goto WFI_INST; \
- case 195: goto SEV_INST; \
- case 196: goto SWI_INST; \
- case 197: goto BBL_INST; \
- case 198: goto B_2_THUMB ; \
- case 199: goto B_COND_THUMB ; \
- case 200: goto BL_1_THUMB ; \
- case 201: goto BL_2_THUMB ; \
- case 202: goto BLX_1_THUMB ; \
- case 203: goto DISPATCH; \
- case 204: goto INIT_INST_LENGTH; \
- case 205: goto END; \
- }
- #endif
- #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0)
- #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1)
- #define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out)
- #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \
- (cpu->NFlag << 31) | \
- (cpu->ZFlag << 30) | \
- (cpu->CFlag << 29) | \
- (cpu->VFlag << 28) | \
- (cpu->TFlag << 5)
- #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \
- cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \
- cpu->CFlag = (cpu->Cpsr >> 29) & 1; \
- cpu->VFlag = (cpu->Cpsr >> 28) & 1; \
- cpu->TFlag = (cpu->Cpsr >> 5) & 1;
- #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
- #define PC (cpu->Reg[15])
- // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
- // to a clunky switch statement.
- #if defined __GNUC__ || defined __clang__
- void *InstLabel[] = {
- &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST,
- &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST,
- &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST,
- &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST,
- &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
- &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
- &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
- &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST,
- &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST,
- &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST,
- &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST,
- &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST,
- &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST,
- &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLALXY_INST,&&SMLA_INST,
- &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST,
- &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST,
- &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST,
- &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,
- &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST,
- &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST, &&LDREXD_INST,
- &&STREXD_INST,&&LDREXH_INST,&&STREXH_INST, &&NOP_INST, &&YIELD_INST, &&WFE_INST, &&WFI_INST, &&SEV_INST, &&SWI_INST,&&BBL_INST,
- &&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,
- &&INIT_INST_LENGTH,&&END
- };
- #endif
- arm_inst* inst_base;
- unsigned int addr;
- unsigned int phys_addr;
- unsigned int num_instrs = 0;
- int ptr;
- LOAD_NZCVT;
- DISPATCH:
- {
- if (!cpu->NirqSig) {
- if (!(cpu->Cpsr & 0x80)) {
- goto END;
- }
- }
- if (cpu->TFlag)
- cpu->Reg[15] &= 0xfffffffe;
- else
- cpu->Reg[15] &= 0xfffffffc;
- phys_addr = cpu->Reg[15];
- // Find the cached instruction cream, otherwise translate it...
- auto itr = cpu->instruction_cache.find(cpu->Reg[15]);
- if (itr != cpu->instruction_cache.end()) {
- ptr = itr->second;
- } else {
- if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
- goto END;
- }
- inst_base = (arm_inst *)&inst_buf[ptr];
- GOTO_NEXT_INST;
- }
- ADC_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- adc_inst* const inst_cream = (adc_inst*)inst_base->component;
- bool carry;
- bool overflow;
- RD = AddWithCarry(RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(adc_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(adc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- ADD_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- add_inst* const inst_cream = (add_inst*)inst_base->component;
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
- bool carry;
- bool overflow;
- RD = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(add_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(add_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- AND_INST:
- {
- and_inst *inst_cream = (and_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
- RD = lop & rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(and_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(and_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- BBL_INST:
- {
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
- if (inst_cream->L) {
- LINK_RTN_ADDR;
- }
- SET_PC;
- INC_PC(sizeof(bbl_inst));
- goto DISPATCH;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bbl_inst));
- goto DISPATCH;
- }
- BIC_INST:
- {
- bic_inst *inst_cream = (bic_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- u32 lop = RN;
- if (inst_cream->Rn == 15) {
- lop += 2 * cpu->GetInstructionSize();
- }
- u32 rop = SHIFTER_OPERAND;
- RD = lop & (~rop);
- if ((inst_cream->S) && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(bic_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bic_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- BKPT_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
- LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bkpt_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- BLX_INST:
- {
- blx_inst *inst_cream = (blx_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- unsigned int inst = inst_cream->inst;
- if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
- cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
- if(cpu->TFlag)
- cpu->Reg[14] |= 0x1;
- cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe;
- cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1;
- } else {
- cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
- cpu->TFlag = 0x1;
- int signed_int = inst_cream->val.signed_immed_24;
- signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int;
- signed_int = signed_int << 2;
- cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1);
- }
- INC_PC(sizeof(blx_inst));
- goto DISPATCH;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(blx_inst));
- goto DISPATCH;
- }
- BX_INST:
- BXJ_INST:
- {
- // Note that only the 'fail' case of BXJ is emulated. This is because
- // the facilities for Jazelle emulation are not implemented.
- //
- // According to the ARM documentation on BXJ, if setting the J bit in the APSR
- // fails, then BXJ functions identically like a regular BX instruction.
- //
- // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle.
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- bx_inst* const inst_cream = (bx_inst*)inst_base->component;
- u32 address = RM;
- if (inst_cream->Rm == 15)
- address += 2 * cpu->GetInstructionSize();
- cpu->TFlag = address & 1;
- cpu->Reg[15] = address & 0xfffffffe;
- INC_PC(sizeof(bx_inst));
- goto DISPATCH;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bx_inst));
- goto DISPATCH;
- }
- CDP_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- // Undefined instruction here
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cdp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CLREX_INST:
- {
- cpu->UnsetExclusiveMemoryAddress();
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(clrex_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CLZ_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- clz_inst* inst_cream = (clz_inst*)inst_base->component;
- RD = clz(RM);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(clz_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CMN_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- cmn_inst* const inst_cream = (cmn_inst*)inst_base->component;
- bool carry;
- bool overflow;
- u32 result = AddWithCarry(RN, SHIFTER_OPERAND, 0, &carry, &overflow);
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cmn_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CMP_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- cmp_inst* const inst_cream = (cmp_inst*)inst_base->component;
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
- bool carry;
- bool overflow;
- u32 result = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cmp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CPS_INST:
- {
- cps_inst *inst_cream = (cps_inst *)inst_base->component;
- uint32_t aif_val = 0;
- uint32_t aif_mask = 0;
- if (cpu->InAPrivilegedMode()) {
- if (inst_cream->imod1) {
- if (inst_cream->A) {
- aif_val |= (inst_cream->imod0 << 8);
- aif_mask |= 1 << 8;
- }
- if (inst_cream->I) {
- aif_val |= (inst_cream->imod0 << 7);
- aif_mask |= 1 << 7;
- }
- if (inst_cream->F) {
- aif_val |= (inst_cream->imod0 << 6);
- aif_mask |= 1 << 6;
- }
- aif_mask = ~aif_mask;
- cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
- }
- if (inst_cream->mmod) {
- cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
- cpu->ChangePrivilegeMode(inst_cream->mode);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cps_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CPY_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- mov_inst* inst_cream = (mov_inst*)inst_base->component;
- RD = SHIFTER_OPERAND;
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mov_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mov_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- EOR_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- eor_inst* inst_cream = (eor_inst*)inst_base->component;
- u32 lop = RN;
- if (inst_cream->Rn == 15) {
- lop += 2 * cpu->GetInstructionSize();
- }
- u32 rop = SHIFTER_OPERAND;
- RD = lop ^ rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(eor_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(eor_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDC_INST:
- {
- // Instruction not implemented
- //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDM_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int inst = inst_cream->inst;
- if (BIT(inst, 22) && !BIT(inst, 15)) {
- for (int i = 0; i < 13; i++) {
- if(BIT(inst, i)) {
- cpu->Reg[i] = cpu->ReadMemory32(addr);
- addr += 4;
- }
- }
- if (BIT(inst, 13)) {
- if (cpu->Mode == USER32MODE)
- cpu->Reg[13] = cpu->ReadMemory32(addr);
- else
- cpu->Reg_usr[0] = cpu->ReadMemory32(addr);
- addr += 4;
- }
- if (BIT(inst, 14)) {
- if (cpu->Mode == USER32MODE)
- cpu->Reg[14] = cpu->ReadMemory32(addr);
- else
- cpu->Reg_usr[1] = cpu->ReadMemory32(addr);
- addr += 4;
- }
- } else if (!BIT(inst, 22)) {
- for(int i = 0; i < 16; i++ ){
- if(BIT(inst, i)){
- unsigned int ret = cpu->ReadMemory32(addr);
- // For armv5t, should enter thumb when bits[0] is non-zero.
- if(i == 15){
- cpu->TFlag = ret & 0x1;
- ret &= 0xFFFFFFFE;
- }
- cpu->Reg[i] = ret;
- addr += 4;
- }
- }
- } else if (BIT(inst, 22) && BIT(inst, 15)) {
- for(int i = 0; i < 15; i++ ){
- if(BIT(inst, i)){
- cpu->Reg[i] = cpu->ReadMemory32(addr);
- addr += 4;
- }
- }
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- }
- cpu->Reg[15] = cpu->ReadMemory32(addr);
- }
- if (BIT(inst, 15)) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SXTH_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- sxth_inst* inst_cream = (sxth_inst*)inst_base->component;
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
- if (BIT(operand2, 15)) {
- operand2 |= 0xffff0000;
- } else {
- operand2 &= 0xffff;
- }
- RD = operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxth_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDR_INST:
- {
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->ReadMemory32(addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- // For armv5t, should enter thumb when bits[0] is non-zero.
- cpu->TFlag = value & 0x1;
- cpu->Reg[15] &= 0xFFFFFFFE;
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRCOND_INST:
- {
- if (CondPassed(cpu, inst_base->cond)) {
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->ReadMemory32(addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- // For armv5t, should enter thumb when bits[0] is non-zero.
- cpu->TFlag = value & 0x1;
- cpu->Reg[15] &= 0xFFFFFFFE;
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTH_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- uxth_inst* inst_cream = (uxth_inst*)inst_base->component;
- RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxth_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTAH_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- uxtah_inst* inst_cream = (uxtah_inst*)inst_base->component;
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtah_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read8(addr);
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRBT_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read8(addr);
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRD_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0)
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- // The 3DS doesn't have LPAE (Large Physical Access Extension), so it
- // wouldn't do this as a single read.
- cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = cpu->ReadMemory32(addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = cpu->ReadMemory32(addr + 4);
- // No dispatch since this operation should not modify R15
- }
- cpu->Reg[15] += 4;
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDREX_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
- cpu->SetExclusiveMemoryAddress(read_addr);
- RD = cpu->ReadMemory32(read_addr);
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(generic_arm_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDREXB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
- cpu->SetExclusiveMemoryAddress(read_addr);
- RD = Memory::Read8(read_addr);
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(generic_arm_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDREXH_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
- cpu->SetExclusiveMemoryAddress(read_addr);
- RD = cpu->ReadMemory16(read_addr);
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(generic_arm_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDREXD_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
- cpu->SetExclusiveMemoryAddress(read_addr);
- RD = cpu->ReadMemory32(read_addr);
- RD2 = cpu->ReadMemory32(read_addr + 4);
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(generic_arm_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRH_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr);
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRSB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = Memory::Read8(addr);
- if (BIT(value, 7)) {
- value |= 0xffffff00;
- }
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRSH_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->ReadMemory16(addr);
- if (BIT(value, 15)) {
- value |= 0xffff0000;
- }
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRT_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->ReadMemory32(addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MCR_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- mcr_inst* inst_cream = (mcr_inst*)inst_base->component;
- unsigned int inst = inst_cream->inst;
- if (inst_cream->Rd == 15) {
- DEBUG_MSG;
- } else {
- if (inst_cream->cp_num == 15)
- cpu->WriteCP15Register(RD, CRn, OPCODE_1, CRm, OPCODE_2);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mcr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MCRR_INST:
- {
- // Stubbed, as the MPCore doesn't have any registers that are accessible
- // through this instruction.
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
- LOG_ERROR(Core_ARM11, "MCRR executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u",
- inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mcrr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MLA_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- mla_inst* inst_cream = (mla_inst*)inst_base->component;
- uint64_t rm = RM;
- uint64_t rs = RS;
- uint64_t rn = RN;
- RD = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff);
- if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mla_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mla_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MOV_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- mov_inst* inst_cream = (mov_inst*)inst_base->component;
- RD = SHIFTER_OPERAND;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mov_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mov_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MRC_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- mrc_inst* inst_cream = (mrc_inst*)inst_base->component;
- unsigned int inst = inst_cream->inst;
- if (inst_cream->Rd == 15) {
- DEBUG_MSG;
- }
- if (inst_cream->inst == 0xeef04a10) {
- // Undefined instruction fmrx
- RD = 0x20000000;
- CITRA_IGNORE_EXIT(-1);
- goto END;
- } else {
- if (inst_cream->cp_num == 15)
- RD = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mrc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MRRC_INST:
- {
- // Stubbed, as the MPCore doesn't have any registers that are accessible
- // through this instruction.
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
- LOG_ERROR(Core_ARM11, "MRRC executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u",
- inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mcrr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MRS_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- mrs_inst* inst_cream = (mrs_inst*)inst_base->component;
- if (inst_cream->R) {
- RD = cpu->Spsr_copy;
- } else {
- SAVE_NZCVT;
- RD = cpu->Cpsr;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mrs_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MSR_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- msr_inst* inst_cream = (msr_inst*)inst_base->component;
- const uint32_t UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
- unsigned int inst = inst_cream->inst;
- unsigned int operand;
- if (BIT(inst, 25)) {
- int rot_imm = BITS(inst, 8, 11) * 2;
- operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
- } else {
- operand = cpu->Reg[BITS(inst, 0, 3)];
- }
- uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0)
- | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
- uint32_t mask = 0;
- if (!inst_cream->R) {
- if (cpu->InAPrivilegedMode()) {
- if ((operand & StateMask) != 0) {
- /// UNPREDICTABLE
- DEBUG_MSG;
- } else
- mask = byte_mask & (UserMask | PrivMask);
- } else {
- mask = byte_mask & UserMask;
- }
- SAVE_NZCVT;
- cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- } else {
- if (CurrentModeHasSPSR) {
- mask = byte_mask & (UserMask | PrivMask | StateMask);
- cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
- }
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(msr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MUL_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- mul_inst* inst_cream = (mul_inst*)inst_base->component;
- uint64_t rm = RM;
- uint64_t rs = RS;
- RD = static_cast<uint32_t>((rm * rs) & 0xffffffff);
- if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mul_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mul_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MVN_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- mvn_inst* const inst_cream = (mvn_inst*)inst_base->component;
- RD = ~SHIFTER_OPERAND;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mvn_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mvn_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- ORR_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- orr_inst* const inst_cream = (orr_inst*)inst_base->component;
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
- RD = lop | rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(orr_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(orr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- NOP_INST:
- {
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- PKHBT_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
- RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(pkh_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- PKHTB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
- int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
- RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(pkh_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- PLD_INST:
- {
- // Not implemented. PLD is a hint instruction, so it's optional.
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(pld_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- QADD_INST:
- QDADD_INST:
- QDSUB_INST:
- QSUB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u8 op1 = inst_cream->op1;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- u32 result = 0;
- // QADD
- if (op1 == 0x00) {
- result = rm_val + rn_val;
- if (AddOverflow(rm_val, rn_val, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- }
- // QSUB
- else if (op1 == 0x01) {
- result = rm_val - rn_val;
- if (SubOverflow(rm_val, rn_val, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- }
- // QDADD
- else if (op1 == 0x02) {
- u32 mul = (rn_val * 2);
- if (AddOverflow(rn_val, rn_val, rn_val * 2)) {
- mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- result = mul + rm_val;
- if (AddOverflow(rm_val, mul, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- }
- // QDSUB
- else if (op1 == 0x03) {
- u32 mul = (rn_val * 2);
- if (AddOverflow(rn_val, rn_val, mul)) {
- mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- result = rm_val - mul;
- if (SubOverflow(rm_val, mul, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- }
- RD = result;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- QADD8_INST:
- QADD16_INST:
- QADDSUBX_INST:
- QSUB8_INST:
- QSUB16_INST:
- QSUBADDX_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u16 rm_lo = (RM & 0xFFFF);
- const u16 rm_hi = ((RM >> 16) & 0xFFFF);
- const u16 rn_lo = (RN & 0xFFFF);
- const u16 rn_hi = ((RN >> 16) & 0xFFFF);
- const u8 op2 = inst_cream->op2;
- u16 lo_result = 0;
- u16 hi_result = 0;
- // QADD16
- if (op2 == 0x00) {
- lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
- hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
- }
- // QASX
- else if (op2 == 0x01) {
- lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
- hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
- }
- // QSAX
- else if (op2 == 0x02) {
- lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
- hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
- }
- // QSUB16
- else if (op2 == 0x03) {
- lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
- hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
- }
- // QADD8
- else if (op2 == 0x04) {
- lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
- ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
- hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
- ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
- }
- // QSUB8
- else if (op2 == 0x07) {
- lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
- ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
- hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
- ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
- }
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- REV_INST:
- REV16_INST:
- REVSH_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- rev_inst* const inst_cream = (rev_inst*)inst_base->component;
- const u8 op1 = inst_cream->op1;
- const u8 op2 = inst_cream->op2;
- // REV
- if (op1 == 0x03 && op2 == 0x01) {
- RD = ((RM & 0xFF) << 24) | (((RM >> 8) & 0xFF) << 16) | (((RM >> 16) & 0xFF) << 8) | ((RM >> 24) & 0xFF);
- }
- // REV16
- else if (op1 == 0x03 && op2 == 0x05) {
- RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8) | ((RM & 0xFF0000) << 8) | ((RM & 0xFF000000) >> 8);
- }
- // REVSH
- else if (op1 == 0x07 && op2 == 0x05) {
- RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8);
- if (RD & 0x8000)
- RD |= 0xffff0000;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(rev_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- RFE_INST:
- {
- // RFE is unconditional
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
- u32 address = 0;
- inst_cream->get_addr(cpu, inst_cream->inst, address);
- cpu->Cpsr = cpu->ReadMemory32(address);
- cpu->Reg[15] = cpu->ReadMemory32(address + 4);
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- RSB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- rsb_inst* const inst_cream = (rsb_inst*)inst_base->component;
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
- bool carry;
- bool overflow;
- RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, 1, &carry, &overflow);
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(rsb_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(rsb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- RSC_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- rsc_inst* const inst_cream = (rsc_inst*)inst_base->component;
- bool carry;
- bool overflow;
- RD = AddWithCarry(~RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(rsc_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(rsc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SADD8_INST:
- SSUB8_INST:
- SADD16_INST:
- SADDSUBX_INST:
- SSUBADDX_INST:
- SSUB16_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u8 op2 = inst_cream->op2;
- if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
- const s16 rn_lo = (RN & 0xFFFF);
- const s16 rn_hi = ((RN >> 16) & 0xFFFF);
- const s16 rm_lo = (RM & 0xFFFF);
- const s16 rm_hi = ((RM >> 16) & 0xFFFF);
- s32 lo_result = 0;
- s32 hi_result = 0;
- // SADD16
- if (inst_cream->op2 == 0x00) {
- lo_result = (rn_lo + rm_lo);
- hi_result = (rn_hi + rm_hi);
- }
- // SASX
- else if (op2 == 0x01) {
- lo_result = (rn_lo - rm_hi);
- hi_result = (rn_hi + rm_lo);
- }
- // SSAX
- else if (op2 == 0x02) {
- lo_result = (rn_lo + rm_hi);
- hi_result = (rn_hi - rm_lo);
- }
- // SSUB16
- else if (op2 == 0x03) {
- lo_result = (rn_lo - rm_lo);
- hi_result = (rn_hi - rm_hi);
- }
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
- if (lo_result >= 0) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
- if (hi_result >= 0) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- else if (op2 == 0x04 || op2 == 0x07) {
- s32 lo_val1, lo_val2;
- s32 hi_val1, hi_val2;
- // SADD8
- if (op2 == 0x04) {
- lo_val1 = (s32)(s8)(RN & 0xFF) + (s32)(s8)(RM & 0xFF);
- lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) + (s32)(s8)((RM >> 8) & 0xFF);
- hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) + (s32)(s8)((RM >> 16) & 0xFF);
- hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) + (s32)(s8)((RM >> 24) & 0xFF);
- }
- // SSUB8
- else {
- lo_val1 = (s32)(s8)(RN & 0xFF) - (s32)(s8)(RM & 0xFF);
- lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) - (s32)(s8)((RM >> 8) & 0xFF);
- hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) - (s32)(s8)((RM >> 16) & 0xFF);
- hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) - (s32)(s8)((RM >> 24) & 0xFF);
- }
- RD = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24));
- if (lo_val1 >= 0)
- cpu->Cpsr |= (1 << 16);
- else
- cpu->Cpsr &= ~(1 << 16);
- if (lo_val2 >= 0)
- cpu->Cpsr |= (1 << 17);
- else
- cpu->Cpsr &= ~(1 << 17);
- if (hi_val1 >= 0)
- cpu->Cpsr |= (1 << 18);
- else
- cpu->Cpsr &= ~(1 << 18);
- if (hi_val2 >= 0)
- cpu->Cpsr |= (1 << 19);
- else
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SBC_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- sbc_inst* const inst_cream = (sbc_inst*)inst_base->component;
- bool carry;
- bool overflow;
- RD = AddWithCarry(RN, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(sbc_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sbc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SEL_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u32 to = RM;
- const u32 from = RN;
- const u32 cpsr = cpu->Cpsr;
- u32 result;
- if (cpsr & (1 << 16))
- result = from & 0xff;
- else
- result = to & 0xff;
- if (cpsr & (1 << 17))
- result |= from & 0x0000ff00;
- else
- result |= to & 0x0000ff00;
- if (cpsr & (1 << 18))
- result |= from & 0x00ff0000;
- else
- result |= to & 0x00ff0000;
- if (cpsr & (1 << 19))
- result |= from & 0xff000000;
- else
- result |= to & 0xff000000;
- RD = result;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SETEND_INST:
- {
- // SETEND is unconditional
- setend_inst* const inst_cream = (setend_inst*)inst_base->component;
- const bool big_endian = (inst_cream->set_bigend == 1);
- if (big_endian)
- cpu->Cpsr |= (1 << 9);
- else
- cpu->Cpsr &= ~(1 << 9);
- LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE");
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(setend_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SEV_INST:
- {
- // Stubbed, as SEV is a hint instruction.
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM11, "SEV executed.");
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SHADD8_INST:
- SHADD16_INST:
- SHADDSUBX_INST:
- SHSUB8_INST:
- SHSUB16_INST:
- SHSUBADDX_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u8 op2 = inst_cream->op2;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
- s32 lo_result = 0;
- s32 hi_result = 0;
- // SHADD16
- if (op2 == 0x00) {
- lo_result = ((s16)(rn_val & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- }
- // SHASX
- else if (op2 == 0x01) {
- lo_result = ((s16)(rn_val & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
- }
- // SHSAX
- else if (op2 == 0x02) {
- lo_result = ((s16)(rn_val & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
- }
- // SHSUB16
- else if (op2 == 0x03) {
- lo_result = ((s16)(rn_val & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- }
- RD = ((lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16));
- }
- else if (op2 == 0x04 || op2 == 0x07) {
- s16 lo_val1, lo_val2;
- s16 hi_val1, hi_val2;
- // SHADD8
- if (op2 == 0x04) {
- lo_val1 = ((s8)(rn_val & 0xFF) + (s8)(rm_val & 0xFF)) >> 1;
- lo_val2 = ((s8)((rn_val >> 8) & 0xFF) + (s8)((rm_val >> 8) & 0xFF)) >> 1;
- hi_val1 = ((s8)((rn_val >> 16) & 0xFF) + (s8)((rm_val >> 16) & 0xFF)) >> 1;
- hi_val2 = ((s8)((rn_val >> 24) & 0xFF) + (s8)((rm_val >> 24) & 0xFF)) >> 1;
- }
- // SHSUB8
- else {
- lo_val1 = ((s8)(rn_val & 0xFF) - (s8)(rm_val & 0xFF)) >> 1;
- lo_val2 = ((s8)((rn_val >> 8) & 0xFF) - (s8)((rm_val >> 8) & 0xFF)) >> 1;
- hi_val1 = ((s8)((rn_val >> 16) & 0xFF) - (s8)((rm_val >> 16) & 0xFF)) >> 1;
- hi_val2 = ((s8)((rn_val >> 24) & 0xFF) - (s8)((rm_val >> 24) & 0xFF)) >> 1;
- }
- RD = (lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMLA_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- smla_inst* inst_cream = (smla_inst*)inst_base->component;
- int32_t operand1, operand2;
- if (inst_cream->x == 0)
- operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
- else
- operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
- if (inst_cream->y == 0)
- operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
- else
- operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
- RD = operand1 * operand2 + RN;
- if (AddOverflow(operand1 * operand2, RN, RD))
- cpu->Cpsr |= (1 << 27);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smla_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMLAD_INST:
- SMLSD_INST:
- SMUAD_INST:
- SMUSD_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- const u8 op2 = inst_cream->op2;
- u32 rm_val = cpu->Reg[inst_cream->Rm];
- const u32 rn_val = cpu->Reg[inst_cream->Rn];
- if (inst_cream->m)
- rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
- const s16 rm_lo = (rm_val & 0xFFFF);
- const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
- const s16 rn_lo = (rn_val & 0xFFFF);
- const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
- const u32 product1 = (rn_lo * rm_lo);
- const u32 product2 = (rn_hi * rm_hi);
- // SMUAD and SMLAD
- if (BIT(op2, 1) == 0) {
- RD = (product1 + product2);
- if (inst_cream->Ra != 15) {
- RD += cpu->Reg[inst_cream->Ra];
- if (ARMul_AddOverflowQ(product1 + product2, cpu->Reg[inst_cream->Ra]))
- cpu->Cpsr |= (1 << 27);
- }
- if (ARMul_AddOverflowQ(product1, product2))
- cpu->Cpsr |= (1 << 27);
- }
- // SMUSD and SMLSD
- else {
- RD = (product1 - product2);
- if (inst_cream->Ra != 15) {
- RD += cpu->Reg[inst_cream->Ra];
- if (ARMul_AddOverflowQ(product1 - product2, cpu->Reg[inst_cream->Ra]))
- cpu->Cpsr |= (1 << 27);
- }
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMLAL_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
- long long int rm = RM;
- long long int rs = RS;
- if (BIT(rm, 31)) {
- rm |= 0xffffffff00000000LL;
- }
- if (BIT(rs, 31)) {
- rs |= 0xffffffff00000000LL;
- }
- long long int rst = rm * rs;
- long long int rdhi32 = RDHI;
- long long int hilo = (rdhi32 << 32) + RDLO;
- rst += hilo;
- RDLO = BITS(rst, 0, 31);
- RDHI = BITS(rst, 32, 63);
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umlal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMLALXY_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component;
- u64 operand1 = RN;
- u64 operand2 = RM;
- if (inst_cream->x != 0)
- operand1 >>= 16;
- if (inst_cream->y != 0)
- operand2 >>= 16;
- operand1 &= 0xFFFF;
- if (operand1 & 0x8000)
- operand1 -= 65536;
- operand2 &= 0xFFFF;
- if (operand2 & 0x8000)
- operand2 -= 65536;
- u64 dest = ((u64)RDHI << 32 | RDLO) + (operand1 * operand2);
- RDLO = (dest & 0xFFFFFFFF);
- RDHI = ((dest >> 32) & 0xFFFFFFFF);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlalxy_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMLAW_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- const u32 ra_val = cpu->Reg[inst_cream->Ra];
- const bool high = (inst_cream->m == 1);
- const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF);
- const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16);
- RD = BITS(result, 16, 47);
- if ((result >> 16) != (s32)RD)
- cpu->Cpsr |= (1 << 27);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMLALD_INST:
- SMLSLD_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
- const bool do_swap = (inst_cream->swap == 1);
- const u32 rdlo_val = RDLO;
- const u32 rdhi_val = RDHI;
- const u32 rn_val = RN;
- u32 rm_val = RM;
- if (do_swap)
- rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
- const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
- const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
- s64 result;
- // SMLALD
- if (BIT(inst_cream->op2, 1) == 0) {
- result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
- }
- // SMLSLD
- else {
- result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
- }
- RDLO = (result & 0xFFFFFFFF);
- RDHI = ((result >> 32) & 0xFFFFFFFF);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlald_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMMLA_INST:
- SMMLS_INST:
- SMMUL_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- const bool do_round = (inst_cream->m == 1);
- // Assume SMMUL by default.
- s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
- if (inst_cream->Ra != 15) {
- const u32 ra_val = cpu->Reg[inst_cream->Ra];
- // SMMLA, otherwise SMMLS
- if (BIT(inst_cream->op2, 1) == 0)
- result += ((s64)ra_val << 32);
- else
- result = ((s64)ra_val << 32) - result;
- }
- if (do_round)
- result += 0x80000000;
- RD = ((result >> 32) & 0xFFFFFFFF);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMUL_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- smul_inst* inst_cream = (smul_inst*)inst_base->component;
- uint32_t operand1, operand2;
- if (inst_cream->x == 0)
- operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
- else
- operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
- if (inst_cream->y == 0)
- operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
- else
- operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
- RD = operand1 * operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smul_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMULL_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- umull_inst* inst_cream = (umull_inst*)inst_base->component;
- int64_t rm = RM;
- int64_t rs = RS;
- if (BIT(rm, 31)) {
- rm |= 0xffffffff00000000LL;
- }
- if (BIT(rs, 31)) {
- rs |= 0xffffffff00000000LL;
- }
- int64_t rst = rm * rs;
- RDHI = BITS(rst, 32, 63);
- RDLO = BITS(rst, 0, 31);
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umull_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMULW_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- s16 rm = (inst_cream->m == 1) ? ((RM >> 16) & 0xFFFF) : (RM & 0xFFFF);
- s64 result = (s64)rm * (s64)(s32)RN;
- RD = BITS(result, 16, 47);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SRS_INST:
- {
- // SRS is unconditional
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
- u32 address = 0;
- inst_cream->get_addr(cpu, inst_cream->inst, address);
- cpu->WriteMemory32(address + 0, cpu->Reg[14]);
- cpu->WriteMemory32(address + 4, cpu->Spsr_copy);
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SSAT_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- u8 shift_type = inst_cream->shift_type;
- u8 shift_amount = inst_cream->imm5;
- u32 rn_val = RN;
- // 32-bit ASR is encoded as an amount of 0.
- if (shift_type == 1 && shift_amount == 0)
- shift_amount = 31;
- if (shift_type == 0)
- rn_val <<= shift_amount;
- else if (shift_type == 1)
- rn_val = ((s32)rn_val >> shift_amount);
- bool saturated = false;
- rn_val = ARMul_SignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
- if (saturated)
- cpu->Cpsr |= (1 << 27);
- RD = rn_val;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SSAT16_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- const u8 saturate_to = inst_cream->sat_imm;
- bool sat1 = false;
- bool sat2 = false;
- RD = (ARMul_SignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) |
- ARMul_SignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16;
- if (sat1 || sat2)
- cpu->Cpsr |= (1 << 27);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STC_INST:
- {
- // Instruction not implemented
- //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(stc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STM_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- unsigned int inst = inst_cream->inst;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int old_RN = cpu->Reg[Rn];
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- if (BIT(inst_cream->inst, 22) == 1) {
- for (int i = 0; i < 13; i++) {
- if (BIT(inst_cream->inst, i)) {
- cpu->WriteMemory32(addr, cpu->Reg[i]);
- addr += 4;
- }
- }
- if (BIT(inst_cream->inst, 13)) {
- if (cpu->Mode == USER32MODE)
- cpu->WriteMemory32(addr, cpu->Reg[13]);
- else
- cpu->WriteMemory32(addr, cpu->Reg_usr[0]);
- addr += 4;
- }
- if (BIT(inst_cream->inst, 14)) {
- if (cpu->Mode == USER32MODE)
- cpu->WriteMemory32(addr, cpu->Reg[14]);
- else
- cpu->WriteMemory32(addr, cpu->Reg_usr[1]);
- addr += 4;
- }
- if (BIT(inst_cream->inst, 15)) {
- cpu->WriteMemory32(addr, cpu->Reg_usr[1] + 8);
- }
- } else {
- for (int i = 0; i < 15; i++) {
- if (BIT(inst_cream->inst, i)) {
- if (i == Rn)
- cpu->WriteMemory32(addr, old_RN);
- else
- cpu->WriteMemory32(addr, cpu->Reg[i]);
- addr += 4;
- }
- }
- // Check PC reg
- if (BIT(inst_cream->inst, 15))
- cpu->WriteMemory32(addr, cpu->Reg_usr[1] + 8);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SXTB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component;
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
- if (BIT(operand2, 7)) {
- operand2 |= 0xffffff00;
- } else {
- operand2 &= 0xff;
- }
- RD = operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxtb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STR_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
- cpu->WriteMemory32(addr, value);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component;
- RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTAB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- uxtab_inst* inst_cream = (uxtab_inst*)inst_base->component;
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
- Memory::Write8(addr, value);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRBT_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
- Memory::Write8(addr, value);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRD_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- // The 3DS doesn't have the Large Physical Access Extension (LPAE)
- // so STRD wouldn't store these as a single write.
- cpu->WriteMemory32(addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
- cpu->WriteMemory32(addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STREX_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
- cpu->WriteMemory32(write_addr, RM);
- RD = 0;
- } else {
- // Failed to write due to mutex access
- RD = 1;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STREXB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
- Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]);
- RD = 0;
- } else {
- // Failed to write due to mutex access
- RD = 1;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STREXD_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
- const u32 rt = cpu->Reg[inst_cream->Rm + 0];
- const u32 rt2 = cpu->Reg[inst_cream->Rm + 1];
- u64 value;
- if (cpu->InBigEndianMode())
- value = (((u64)rt << 32) | rt2);
- else
- value = (((u64)rt2 << 32) | rt);
- cpu->WriteMemory64(write_addr, value);
- RD = 0;
- }
- else {
- // Failed to write due to mutex access
- RD = 1;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STREXH_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
- cpu->WriteMemory16(write_addr, RM);
- RD = 0;
- } else {
- // Failed to write due to mutex access
- RD = 1;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRH_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
- cpu->WriteMemory16(addr, value);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRT_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
- cpu->WriteMemory32(addr, value);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SUB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- sub_inst* const inst_cream = (sub_inst*)inst_base->component;
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 8;
- bool carry;
- bool overflow;
- RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(sub_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sub_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SWI_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- swi_inst* const inst_cream = (swi_inst*)inst_base->component;
- SVC::CallSVC(inst_cream->num & 0xFFFF);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(swi_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SWP_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- swp_inst* inst_cream = (swp_inst*)inst_base->component;
- addr = RN;
- unsigned int value = cpu->ReadMemory32(addr);
- cpu->WriteMemory32(addr, RM);
- RD = value;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(swp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SWPB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- swp_inst* inst_cream = (swp_inst*)inst_base->component;
- addr = RN;
- unsigned int value = Memory::Read8(addr);
- Memory::Write8(addr, (RM & 0xFF));
- RD = value;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(swp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SXTAB_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- sxtab_inst* inst_cream = (sxtab_inst*)inst_base->component;
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
- // Sign extend for byte
- operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SXTAB16_INST:
- SXTB16_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
- const u8 rotation = inst_cream->rotate * 8;
- u32 rm_val = RM;
- u32 rn_val = RN;
- if (rotation)
- rm_val = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
- // SXTB16
- if (inst_cream->Rn == 15) {
- u32 lo = (u32)(s8)rm_val;
- u32 hi = (u32)(s8)(rm_val >> 16);
- RD = (lo | (hi << 16));
- }
- // SXTAB16
- else {
- u32 lo = (rn_val & 0xFFFF) + (u32)(s8)(rm_val & 0xFF);
- u32 hi = ((rn_val >> 16) & 0xFFFF) + (u32)(s8)((rm_val >> 16) & 0xFF);
- RD = (lo | (hi << 16));
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SXTAH_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- sxtah_inst* inst_cream = (sxtah_inst*)inst_base->component;
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
- // Sign extend for half
- operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2;
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxtah_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- TEQ_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- teq_inst* const inst_cream = (teq_inst*)inst_base->component;
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
- if (inst_cream->Rn == 15)
- lop += cpu->GetInstructionSize() * 2;
- u32 result = lop ^ rop;
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- UPDATE_CFLAG_WITH_SC;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(teq_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- TST_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- tst_inst* const inst_cream = (tst_inst*)inst_base->component;
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
- if (inst_cream->Rn == 15)
- lop += cpu->GetInstructionSize() * 2;
- u32 result = lop & rop;
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- UPDATE_CFLAG_WITH_SC;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(tst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UADD8_INST:
- UADD16_INST:
- UADDSUBX_INST:
- USUB8_INST:
- USUB16_INST:
- USUBADDX_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u8 op2 = inst_cream->op2;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- s32 lo_result = 0;
- s32 hi_result = 0;
- // UADD16
- if (op2 == 0x00) {
- lo_result = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- if (lo_result & 0xFFFF0000) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
- if (hi_result & 0xFFFF0000) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // UASX
- else if (op2 == 0x01) {
- lo_result = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
- if (lo_result >= 0) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
- if (hi_result >= 0x10000) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // USAX
- else if (op2 == 0x02) {
- lo_result = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
- if (lo_result >= 0x10000) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
- if (hi_result >= 0) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // USUB16
- else if (op2 == 0x03) {
- lo_result = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- if ((lo_result & 0xFFFF0000) == 0) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
- if ((hi_result & 0xFFFF0000) == 0) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // UADD8
- else if (op2 == 0x04) {
- s16 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
- s16 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
- s16 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
- s16 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
- if (sum1 >= 0x100)
- cpu->Cpsr |= (1 << 16);
- else
- cpu->Cpsr &= ~(1 << 16);
- if (sum2 >= 0x100)
- cpu->Cpsr |= (1 << 17);
- else
- cpu->Cpsr &= ~(1 << 17);
- if (sum3 >= 0x100)
- cpu->Cpsr |= (1 << 18);
- else
- cpu->Cpsr &= ~(1 << 18);
- if (sum4 >= 0x100)
- cpu->Cpsr |= (1 << 19);
- else
- cpu->Cpsr &= ~(1 << 19);
- lo_result = ((sum1 & 0xFF) | (sum2 & 0xFF) << 8);
- hi_result = ((sum3 & 0xFF) | (sum4 & 0xFF) << 8);
- }
- // USUB8
- else if (op2 == 0x07) {
- s16 diff1 = (rn_val & 0xFF) - (rm_val & 0xFF);
- s16 diff2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
- s16 diff3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
- s16 diff4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
- if (diff1 >= 0)
- cpu->Cpsr |= (1 << 16);
- else
- cpu->Cpsr &= ~(1 << 16);
- if (diff2 >= 0)
- cpu->Cpsr |= (1 << 17);
- else
- cpu->Cpsr &= ~(1 << 17);
- if (diff3 >= 0)
- cpu->Cpsr |= (1 << 18);
- else
- cpu->Cpsr &= ~(1 << 18);
- if (diff4 >= 0)
- cpu->Cpsr |= (1 << 19);
- else
- cpu->Cpsr &= ~(1 << 19);
- lo_result = (diff1 & 0xFF) | ((diff2 & 0xFF) << 8);
- hi_result = (diff3 & 0xFF) | ((diff4 & 0xFF) << 8);
- }
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UHADD8_INST:
- UHADD16_INST:
- UHADDSUBX_INST:
- UHSUBADDX_INST:
- UHSUB8_INST:
- UHSUB16_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- const u8 op2 = inst_cream->op2;
- if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
- {
- u32 lo_val = 0;
- u32 hi_val = 0;
- // UHADD16
- if (op2 == 0x00) {
- lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- }
- // UHASX
- else if (op2 == 0x01) {
- lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
- }
- // UHSAX
- else if (op2 == 0x02) {
- lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
- }
- // UHSUB16
- else if (op2 == 0x03) {
- lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- }
- lo_val >>= 1;
- hi_val >>= 1;
- RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
- }
- else if (op2 == 0x04 || op2 == 0x07) {
- u32 sum1;
- u32 sum2;
- u32 sum3;
- u32 sum4;
- // UHADD8
- if (op2 == 0x04) {
- sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
- sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
- sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
- sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
- }
- // UHSUB8
- else {
- sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
- sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
- sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
- sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
- }
- sum1 >>= 1;
- sum2 >>= 1;
- sum3 >>= 1;
- sum4 >>= 1;
- RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UMAAL_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
- const u64 rm = RM;
- const u64 rn = RN;
- const u64 rd_lo = RDLO;
- const u64 rd_hi = RDHI;
- const u64 result = (rm * rn) + rd_lo + rd_hi;
- RDLO = (result & 0xFFFFFFFF);
- RDHI = ((result >> 32) & 0xFFFFFFFF);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umaal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UMLAL_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
- unsigned long long int rm = RM;
- unsigned long long int rs = RS;
- unsigned long long int rst = rm * rs;
- unsigned long long int add = ((unsigned long long) RDHI)<<32;
- add += RDLO;
- rst += add;
- RDLO = BITS(rst, 0, 31);
- RDHI = BITS(rst, 32, 63);
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umlal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UMULL_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- umull_inst* inst_cream = (umull_inst*)inst_base->component;
- unsigned long long int rm = RM;
- unsigned long long int rs = RS;
- unsigned long long int rst = rm * rs;
- RDHI = BITS(rst, 32, 63);
- RDLO = BITS(rst, 0, 31);
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umull_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- B_2_THUMB:
- {
- b_2_thumb* inst_cream = (b_2_thumb*)inst_base->component;
- cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
- INC_PC(sizeof(b_2_thumb));
- goto DISPATCH;
- }
- B_COND_THUMB:
- {
- b_cond_thumb* inst_cream = (b_cond_thumb*)inst_base->component;
- if(CondPassed(cpu, inst_cream->cond))
- cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
- else
- cpu->Reg[15] += 2;
- INC_PC(sizeof(b_cond_thumb));
- goto DISPATCH;
- }
- BL_1_THUMB:
- {
- bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component;
- cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bl_1_thumb));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- BL_2_THUMB:
- {
- bl_2_thumb* inst_cream = (bl_2_thumb*)inst_base->component;
- int tmp = ((cpu->Reg[15] + 2) | 1);
- cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm);
- cpu->Reg[14] = tmp;
- INC_PC(sizeof(bl_2_thumb));
- goto DISPATCH;
- }
- BLX_1_THUMB:
- {
- // BLX 1 for armv5t and above
- u32 tmp = cpu->Reg[15];
- blx_1_thumb* inst_cream = (blx_1_thumb*)inst_base->component;
- cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
- cpu->Reg[14] = ((tmp + 2) | 1);
- cpu->TFlag = 0;
- INC_PC(sizeof(blx_1_thumb));
- goto DISPATCH;
- }
- UQADD8_INST:
- UQADD16_INST:
- UQADDSUBX_INST:
- UQSUB8_INST:
- UQSUB16_INST:
- UQSUBADDX_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u8 op2 = inst_cream->op2;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- u16 lo_val = 0;
- u16 hi_val = 0;
- // UQADD16
- if (op2 == 0x00) {
- lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- }
- // UQASX
- else if (op2 == 0x01) {
- lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
- }
- // UQSAX
- else if (op2 == 0x02) {
- lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
- }
- // UQSUB16
- else if (op2 == 0x03) {
- lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- }
- // UQADD8
- else if (op2 == 0x04) {
- lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
- ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
- hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
- ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
- }
- // UQSUB8
- else {
- lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
- ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
- hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
- ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
- }
- RD = ((lo_val & 0xFFFF) | hi_val << 16);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- USAD8_INST:
- USADA8_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- const u8 ra_idx = inst_cream->Ra;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
- const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
- const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
- const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
- u32 finalDif = (diff1 + diff2 + diff3 + diff4);
- // Op is USADA8 if true.
- if (ra_idx != 15)
- finalDif += cpu->Reg[ra_idx];
- RD = finalDif;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- USAT_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- u8 shift_type = inst_cream->shift_type;
- u8 shift_amount = inst_cream->imm5;
- u32 rn_val = RN;
- // 32-bit ASR is encoded as an amount of 0.
- if (shift_type == 1 && shift_amount == 0)
- shift_amount = 31;
- if (shift_type == 0)
- rn_val <<= shift_amount;
- else if (shift_type == 1)
- rn_val = ((s32)rn_val >> shift_amount);
- bool saturated = false;
- rn_val = ARMul_UnsignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
- if (saturated)
- cpu->Cpsr |= (1 << 27);
- RD = rn_val;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- USAT16_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- const u8 saturate_to = inst_cream->sat_imm;
- bool sat1 = false;
- bool sat2 = false;
- RD = (ARMul_UnsignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) |
- ARMul_UnsignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16;
- if (sat1 || sat2)
- cpu->Cpsr |= (1 << 27);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTAB16_INST:
- UXTB16_INST:
- {
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
- const u8 rn_idx = inst_cream->Rn;
- const u32 rm_val = RM;
- const u32 rotation = inst_cream->rotate * 8;
- const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
- // UXTB16, otherwise UXTAB16
- if (rn_idx == 15) {
- RD = rotated_rm & 0x00FF00FF;
- } else {
- const u32 rn_val = RN;
- const u8 lo_rotated = (rotated_rm & 0xFF);
- const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
- const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
- const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
- RD = ((hi_result << 16) | (lo_result & 0xFFFF));
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- WFE_INST:
- {
- // Stubbed, as WFE is a hint instruction.
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM11, "WFE executed.");
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- WFI_INST:
- {
- // Stubbed, as WFI is a hint instruction.
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM11, "WFI executed.");
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- YIELD_INST:
- {
- // Stubbed, as YIELD is a hint instruction.
- if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM11, "YIELD executed.");
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- #define VFP_INTERPRETER_IMPL
- #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
- #undef VFP_INTERPRETER_IMPL
- END:
- {
- SAVE_NZCVT;
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
- }
- INIT_INST_LENGTH:
- {
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
- }
- }
|