ARMInstrInfo.td 250 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510
  1. //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file describes the ARM instructions in TableGen format.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. //===----------------------------------------------------------------------===//
  13. // ARM specific DAG Nodes.
  14. //
  15. // Type profiles.
  16. def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>,
  17. SDTCisVT<1, i32> ]>;
  18. def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
  19. def SDT_ARMStructByVal : SDTypeProfile<0, 4,
  20. [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
  21. SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
  22. def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
  23. def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
  24. def SDT_ARMCMov : SDTypeProfile<1, 3,
  25. [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
  26. SDTCisVT<3, i32>]>;
  27. def SDT_ARMBrcond : SDTypeProfile<0, 2,
  28. [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
  29. def SDT_ARMBrJT : SDTypeProfile<0, 2,
  30. [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
  31. def SDT_ARMBr2JT : SDTypeProfile<0, 3,
  32. [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
  33. SDTCisVT<2, i32>]>;
  34. def SDT_ARMBCC_i64 : SDTypeProfile<0, 6,
  35. [SDTCisVT<0, i32>,
  36. SDTCisVT<1, i32>, SDTCisVT<2, i32>,
  37. SDTCisVT<3, i32>, SDTCisVT<4, i32>,
  38. SDTCisVT<5, OtherVT>]>;
  39. def SDT_ARMAnd : SDTypeProfile<1, 2,
  40. [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
  41. SDTCisVT<2, i32>]>;
  42. def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
  43. def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
  44. SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
  45. def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
  46. def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
  47. SDTCisInt<2>]>;
  48. def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
  49. def SDT_ARMEH_SJLJ_SetupDispatch: SDTypeProfile<0, 0, []>;
  50. def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
  51. def SDT_ARMPREFETCH : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisSameAs<1, 2>,
  52. SDTCisInt<1>]>;
  53. def SDT_ARMTCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>]>;
  54. def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
  55. SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
  56. def SDT_WIN__DBZCHK : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
  57. def SDT_ARMMEMCPY : SDTypeProfile<2, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
  58. SDTCisVT<2, i32>, SDTCisVT<3, i32>,
  59. SDTCisVT<4, i32>]>;
  60. def SDTBinaryArithWithFlags : SDTypeProfile<2, 2,
  61. [SDTCisSameAs<0, 2>,
  62. SDTCisSameAs<0, 3>,
  63. SDTCisInt<0>, SDTCisVT<1, i32>]>;
  64. // SDTBinaryArithWithFlagsInOut - RES1, CPSR = op LHS, RHS, CPSR
  65. def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3,
  66. [SDTCisSameAs<0, 2>,
  67. SDTCisSameAs<0, 3>,
  68. SDTCisInt<0>,
  69. SDTCisVT<1, i32>,
  70. SDTCisVT<4, i32>]>;
  71. def SDT_LongMac : SDTypeProfile<2, 4, [SDTCisVT<0, i32>,
  72. SDTCisSameAs<0, 1>,
  73. SDTCisSameAs<0, 2>,
  74. SDTCisSameAs<0, 3>,
  75. SDTCisSameAs<0, 4>,
  76. SDTCisSameAs<0, 5>]>;
  77. // ARMlsll, ARMlsrl, ARMasrl
  78. def SDT_ARMIntShiftParts : SDTypeProfile<2, 3, [SDTCisSameAs<0, 1>,
  79. SDTCisSameAs<0, 2>,
  80. SDTCisSameAs<0, 3>,
  81. SDTCisInt<0>,
  82. SDTCisInt<4>]>;
  83. def ARMSmlald : SDNode<"ARMISD::SMLALD", SDT_LongMac>;
  84. def ARMSmlaldx : SDNode<"ARMISD::SMLALDX", SDT_LongMac>;
  85. def ARMSmlsld : SDNode<"ARMISD::SMLSLD", SDT_LongMac>;
  86. def ARMSmlsldx : SDNode<"ARMISD::SMLSLDX", SDT_LongMac>;
  87. def SDT_ARMCSel : SDTypeProfile<1, 3,
  88. [SDTCisSameAs<0, 1>,
  89. SDTCisSameAs<0, 2>,
  90. SDTCisInt<3>,
  91. SDTCisVT<3, i32>]>;
  92. def ARMcsinv : SDNode<"ARMISD::CSINV", SDT_ARMCSel, [SDNPOptInGlue]>;
  93. def ARMcsneg : SDNode<"ARMISD::CSNEG", SDT_ARMCSel, [SDNPOptInGlue]>;
  94. def ARMcsinc : SDNode<"ARMISD::CSINC", SDT_ARMCSel, [SDNPOptInGlue]>;
  95. def SDT_MulHSR : SDTypeProfile<1, 3, [SDTCisVT<0,i32>,
  96. SDTCisSameAs<0, 1>,
  97. SDTCisSameAs<0, 2>,
  98. SDTCisSameAs<0, 3>]>;
  99. def ARMsmmlar : SDNode<"ARMISD::SMMLAR", SDT_MulHSR>;
  100. def ARMsmmlsr : SDNode<"ARMISD::SMMLSR", SDT_MulHSR>;
  101. // Node definitions.
  102. def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
  103. def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntUnaryOp>;
  104. def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntUnaryOp>;
  105. def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
  106. [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
  107. def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
  108. [SDNPHasChain, SDNPSideEffect,
  109. SDNPOptInGlue, SDNPOutGlue]>;
  110. def ARMcopystructbyval : SDNode<"ARMISD::COPY_STRUCT_BYVAL" ,
  111. SDT_ARMStructByVal,
  112. [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
  113. SDNPMayStore, SDNPMayLoad]>;
  114. def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
  115. [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
  116. SDNPVariadic]>;
  117. def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
  118. [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
  119. SDNPVariadic]>;
  120. def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
  121. [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
  122. SDNPVariadic]>;
  123. def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
  124. [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
  125. def ARMseretflag : SDNode<"ARMISD::SERET_FLAG", SDTNone,
  126. [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
  127. def ARMintretflag : SDNode<"ARMISD::INTRET_FLAG", SDT_ARMcall,
  128. [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
  129. def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
  130. [SDNPInGlue]>;
  131. def ARMsubs : SDNode<"ARMISD::SUBS", SDTIntBinOp, [SDNPOutGlue]>;
  132. def ARMssat : SDNode<"ARMISD::SSAT", SDTIntSatNoShOp, []>;
  133. def ARMusat : SDNode<"ARMISD::USAT", SDTIntSatNoShOp, []>;
  134. def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
  135. [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
  136. def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
  137. [SDNPHasChain]>;
  138. def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
  139. [SDNPHasChain]>;
  140. def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
  141. [SDNPHasChain]>;
  142. def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
  143. [SDNPOutGlue]>;
  144. def ARMcmn : SDNode<"ARMISD::CMN", SDT_ARMCmp,
  145. [SDNPOutGlue]>;
  146. def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
  147. [SDNPOutGlue, SDNPCommutative]>;
  148. def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
  149. def ARMasrl : SDNode<"ARMISD::ASRL", SDT_ARMIntShiftParts, []>;
  150. def ARMlsrl : SDNode<"ARMISD::LSRL", SDT_ARMIntShiftParts, []>;
  151. def ARMlsll : SDNode<"ARMISD::LSLL", SDT_ARMIntShiftParts, []>;
  152. def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
  153. def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>;
  154. def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>;
  155. def ARMaddc : SDNode<"ARMISD::ADDC", SDTBinaryArithWithFlags,
  156. [SDNPCommutative]>;
  157. def ARMsubc : SDNode<"ARMISD::SUBC", SDTBinaryArithWithFlags>;
  158. def ARMlsls : SDNode<"ARMISD::LSLS", SDTBinaryArithWithFlags>;
  159. def ARMadde : SDNode<"ARMISD::ADDE", SDTBinaryArithWithFlagsInOut>;
  160. def ARMsube : SDNode<"ARMISD::SUBE", SDTBinaryArithWithFlagsInOut>;
  161. def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
  162. def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP",
  163. SDT_ARMEH_SJLJ_Setjmp,
  164. [SDNPHasChain, SDNPSideEffect]>;
  165. def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP",
  166. SDT_ARMEH_SJLJ_Longjmp,
  167. [SDNPHasChain, SDNPSideEffect]>;
  168. def ARMeh_sjlj_setup_dispatch: SDNode<"ARMISD::EH_SJLJ_SETUP_DISPATCH",
  169. SDT_ARMEH_SJLJ_SetupDispatch,
  170. [SDNPHasChain, SDNPSideEffect]>;
  171. def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
  172. [SDNPHasChain, SDNPSideEffect]>;
  173. def ARMPreload : SDNode<"ARMISD::PRELOAD", SDT_ARMPREFETCH,
  174. [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
  175. def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET,
  176. [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
  177. def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>;
  178. def ARMmemcopy : SDNode<"ARMISD::MEMCPY", SDT_ARMMEMCPY,
  179. [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
  180. SDNPMayStore, SDNPMayLoad]>;
  181. def ARMsmulwb : SDNode<"ARMISD::SMULWB", SDTIntBinOp, []>;
  182. def ARMsmulwt : SDNode<"ARMISD::SMULWT", SDTIntBinOp, []>;
  183. def ARMsmlalbb : SDNode<"ARMISD::SMLALBB", SDT_LongMac, []>;
  184. def ARMsmlalbt : SDNode<"ARMISD::SMLALBT", SDT_LongMac, []>;
  185. def ARMsmlaltb : SDNode<"ARMISD::SMLALTB", SDT_LongMac, []>;
  186. def ARMsmlaltt : SDNode<"ARMISD::SMLALTT", SDT_LongMac, []>;
  187. def ARMqadd8b : SDNode<"ARMISD::QADD8b", SDT_ARMAnd, []>;
  188. def ARMqsub8b : SDNode<"ARMISD::QSUB8b", SDT_ARMAnd, []>;
  189. def ARMqadd16b : SDNode<"ARMISD::QADD16b", SDT_ARMAnd, []>;
  190. def ARMqsub16b : SDNode<"ARMISD::QSUB16b", SDT_ARMAnd, []>;
  191. def ARMuqadd8b : SDNode<"ARMISD::UQADD8b", SDT_ARMAnd, []>;
  192. def ARMuqsub8b : SDNode<"ARMISD::UQSUB8b", SDT_ARMAnd, []>;
  193. def ARMuqadd16b : SDNode<"ARMISD::UQADD16b", SDT_ARMAnd, []>;
  194. def ARMuqsub16b : SDNode<"ARMISD::UQSUB16b", SDT_ARMAnd, []>;
  195. def SDT_ARMldrd : SDTypeProfile<2, 1, [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>;
  196. def ARMldrd : SDNode<"ARMISD::LDRD", SDT_ARMldrd, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
  197. def SDT_ARMstrd : SDTypeProfile<0, 3, [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>;
  198. def ARMstrd : SDNode<"ARMISD::STRD", SDT_ARMstrd, [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
  199. // Vector operations shared between NEON and MVE
  200. def ARMvdup : SDNode<"ARMISD::VDUP", SDTypeProfile<1, 1, [SDTCisVec<0>]>>;
  201. // VDUPLANE can produce a quad-register result from a double-register source,
  202. // so the result is not constrained to match the source.
  203. def ARMvduplane : SDNode<"ARMISD::VDUPLANE",
  204. SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>,
  205. SDTCisVT<2, i32>]>>;
  206. def SDTARMVIDUP : SDTypeProfile<2, 2, [SDTCisVec<0>, SDTCisVT<1, i32>,
  207. SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
  208. def ARMvidup : SDNode<"ARMISD::VIDUP", SDTARMVIDUP>;
  209. def SDTARMVSHUF : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisSameAs<0, 1>]>;
  210. def ARMvrev64 : SDNode<"ARMISD::VREV64", SDTARMVSHUF>;
  211. def ARMvrev32 : SDNode<"ARMISD::VREV32", SDTARMVSHUF>;
  212. def ARMvrev16 : SDNode<"ARMISD::VREV16", SDTARMVSHUF>;
  213. def SDTARMVGETLN : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVec<1>,
  214. SDTCisVT<2, i32>]>;
  215. def ARMvgetlaneu : SDNode<"ARMISD::VGETLANEu", SDTARMVGETLN>;
  216. def ARMvgetlanes : SDNode<"ARMISD::VGETLANEs", SDTARMVGETLN>;
  217. def SDTARMVMOVIMM : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>;
  218. def ARMvmovImm : SDNode<"ARMISD::VMOVIMM", SDTARMVMOVIMM>;
  219. def ARMvmvnImm : SDNode<"ARMISD::VMVNIMM", SDTARMVMOVIMM>;
  220. def ARMvmovFPImm : SDNode<"ARMISD::VMOVFPIMM", SDTARMVMOVIMM>;
  221. def SDTARMVORRIMM : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>,
  222. SDTCisVT<2, i32>]>;
  223. def ARMvorrImm : SDNode<"ARMISD::VORRIMM", SDTARMVORRIMM>;
  224. def ARMvbicImm : SDNode<"ARMISD::VBICIMM", SDTARMVORRIMM>;
  225. def SDTARMVSHIMM : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
  226. SDTCisVT<2, i32>]>;
  227. def SDTARMVSH : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
  228. SDTCisSameAs<0, 2>,]>;
  229. def ARMvshlImm : SDNode<"ARMISD::VSHLIMM", SDTARMVSHIMM>;
  230. def ARMvshrsImm : SDNode<"ARMISD::VSHRsIMM", SDTARMVSHIMM>;
  231. def ARMvshruImm : SDNode<"ARMISD::VSHRuIMM", SDTARMVSHIMM>;
  232. def ARMvshls : SDNode<"ARMISD::VSHLs", SDTARMVSH>;
  233. def ARMvshlu : SDNode<"ARMISD::VSHLu", SDTARMVSH>;
  234. def SDTARMVMULL : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>,
  235. SDTCisSameAs<1, 2>]>;
  236. def ARMvmulls : SDNode<"ARMISD::VMULLs", SDTARMVMULL>;
  237. def ARMvmullu : SDNode<"ARMISD::VMULLu", SDTARMVMULL>;
  238. def SDTARMVCMP : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<1, 2>,
  239. SDTCisInt<3>]>;
  240. def SDTARMVCMPZ : SDTypeProfile<1, 2, [SDTCisInt<2>]>;
  241. def ARMvcmp : SDNode<"ARMISD::VCMP", SDTARMVCMP>;
  242. def ARMvcmpz : SDNode<"ARMISD::VCMPZ", SDTARMVCMPZ>;
  243. // 'VECTOR_REG_CAST' is an operation that reinterprets the contents of a
  244. // vector register as a different vector type, without changing the contents of
  245. // the register. It differs from 'bitconvert' in that bitconvert reinterprets
  246. // the _memory_ storage format of the vector, whereas VECTOR_REG_CAST
  247. // reinterprets the _register_ format - and in big-endian, the memory and
  248. // register formats are different, so they are different operations.
  249. //
  250. // For example, 'VECTOR_REG_CAST' between v8i16 and v16i8 will map the LSB of
  251. // the zeroth i16 lane to the zeroth i8 lane, regardless of system endianness,
  252. // whereas 'bitconvert' will map it to the high byte in big-endian mode,
  253. // because that's what (MVE) VSTRH.16 followed by VLDRB.8 would do. So the
  254. // bitconvert would have to emit a VREV16.8 instruction, whereas the
  255. // VECTOR_REG_CAST emits no code at all if the vector is already in a register.
  256. def ARMVectorRegCastImpl : SDNode<"ARMISD::VECTOR_REG_CAST", SDTUnaryOp>;
  257. // In little-endian, VECTOR_REG_CAST is often turned into bitconvert during
  258. // lowering (because in that situation they're identical). So an isel pattern
  259. // that needs to match something that's _logically_ a VECTOR_REG_CAST must
  260. // _physically_ match a different node type depending on endianness.
  261. //
  262. // This 'PatFrags' instance is a centralized facility to make that easy. It
  263. // matches VECTOR_REG_CAST in either endianness, and also bitconvert in the
  264. // endianness where it's equivalent.
  265. def ARMVectorRegCast: PatFrags<
  266. (ops node:$x), [(ARMVectorRegCastImpl node:$x), (bitconvert node:$x)], [{
  267. // Reject a match against bitconvert (aka ISD::BITCAST) if big-endian
  268. return !(CurDAG->getDataLayout().isBigEndian() &&
  269. N->getOpcode() == ISD::BITCAST);
  270. }]>;
  271. //===----------------------------------------------------------------------===//
  272. // ARM Flag Definitions.
  273. class RegConstraint<string C> {
  274. string Constraints = C;
  275. }
  276. // ARMCC condition codes. See ARMCC::CondCodes
  277. def ARMCCeq : PatLeaf<(i32 0)>;
  278. def ARMCCne : PatLeaf<(i32 1)>;
  279. def ARMCChs : PatLeaf<(i32 2)>;
  280. def ARMCClo : PatLeaf<(i32 3)>;
  281. def ARMCCmi : PatLeaf<(i32 4)>;
  282. def ARMCCpl : PatLeaf<(i32 5)>;
  283. def ARMCCvs : PatLeaf<(i32 6)>;
  284. def ARMCCvc : PatLeaf<(i32 7)>;
  285. def ARMCChi : PatLeaf<(i32 8)>;
  286. def ARMCCls : PatLeaf<(i32 9)>;
  287. def ARMCCge : PatLeaf<(i32 10)>;
  288. def ARMCClt : PatLeaf<(i32 11)>;
  289. def ARMCCgt : PatLeaf<(i32 12)>;
  290. def ARMCCle : PatLeaf<(i32 13)>;
  291. def ARMCCal : PatLeaf<(i32 14)>;
  292. // VCC predicates. See ARMVCC::VPTCodes
  293. def ARMVCCNone : PatLeaf<(i32 0)>;
  294. def ARMVCCThen : PatLeaf<(i32 1)>;
  295. def ARMVCCElse : PatLeaf<(i32 2)>;
  296. //===----------------------------------------------------------------------===//
  297. // ARM specific transformation functions and pattern fragments.
  298. //
  299. // imm_neg_XFORM - Return the negation of an i32 immediate value.
  300. def imm_neg_XFORM : SDNodeXForm<imm, [{
  301. return CurDAG->getTargetConstant(-(int)N->getZExtValue(), SDLoc(N), MVT::i32);
  302. }]>;
  303. // imm_not_XFORM - Return the complement of a i32 immediate value.
  304. def imm_not_XFORM : SDNodeXForm<imm, [{
  305. return CurDAG->getTargetConstant(~(int)N->getZExtValue(), SDLoc(N), MVT::i32);
  306. }]>;
  307. // asr_imm_XFORM - Returns a shift immediate with bit {5} set to 1
  308. def asr_imm_XFORM : SDNodeXForm<imm, [{
  309. return CurDAG->getTargetConstant(0x20 | N->getZExtValue(), SDLoc(N), MVT:: i32);
  310. }]>;
  311. /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
  312. def imm16_31 : ImmLeaf<i32, [{
  313. return (int32_t)Imm >= 16 && (int32_t)Imm < 32;
  314. }]>;
  315. // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
  316. def sext_16_node : PatLeaf<(i32 GPR:$a), [{
  317. return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
  318. }]>;
  319. def sext_bottom_16 : PatFrag<(ops node:$a),
  320. (sext_inreg node:$a, i16)>;
  321. def sext_top_16 : PatFrag<(ops node:$a),
  322. (i32 (sra node:$a, (i32 16)))>;
  323. def bb_mul : PatFrag<(ops node:$a, node:$b),
  324. (mul (sext_bottom_16 node:$a), (sext_bottom_16 node:$b))>;
  325. def bt_mul : PatFrag<(ops node:$a, node:$b),
  326. (mul (sext_bottom_16 node:$a), (sra node:$b, (i32 16)))>;
  327. def tb_mul : PatFrag<(ops node:$a, node:$b),
  328. (mul (sra node:$a, (i32 16)), (sext_bottom_16 node:$b))>;
  329. def tt_mul : PatFrag<(ops node:$a, node:$b),
  330. (mul (sra node:$a, (i32 16)), (sra node:$b, (i32 16)))>;
  331. /// Split a 32-bit immediate into two 16 bit parts.
  332. def hi16 : SDNodeXForm<imm, [{
  333. return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, SDLoc(N),
  334. MVT::i32);
  335. }]>;
  336. def lo16AllZero : PatLeaf<(i32 imm), [{
  337. // Returns true if all low 16-bits are 0.
  338. return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
  339. }], hi16>;
  340. // top16Zero - answer true if the upper 16 bits of $src are 0, false otherwise
  341. def top16Zero: PatLeaf<(i32 GPR:$src), [{
  342. return !SDValue(N,0)->getValueType(0).isVector() &&
  343. CurDAG->MaskedValueIsZero(SDValue(N,0), APInt::getHighBitsSet(32, 16));
  344. }]>;
  345. // topbitsallzero - Return true if all bits except the lowest bit are known zero
  346. def topbitsallzero32 : PatLeaf<(i32 GPRwithZR:$src), [{
  347. return SDValue(N,0)->getValueType(0) == MVT::i32 &&
  348. CurDAG->MaskedValueIsZero(SDValue(N,0), APInt::getHighBitsSet(32, 31));
  349. }]>;
  350. class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
  351. class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
  352. // An 'and' node with a single use.
  353. def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
  354. return N->hasOneUse();
  355. }]>;
  356. // An 'xor' node with a single use.
  357. def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{
  358. return N->hasOneUse();
  359. }]>;
  360. // An 'fmul' node with a single use.
  361. def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{
  362. return N->hasOneUse();
  363. }]>;
  364. // An 'fadd' node which checks for single non-hazardous use.
  365. def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{
  366. return hasNoVMLxHazardUse(N);
  367. }]>;
  368. // An 'fsub' node which checks for single non-hazardous use.
  369. def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
  370. return hasNoVMLxHazardUse(N);
  371. }]>;
  372. def imm_even : ImmLeaf<i32, [{ return (Imm & 1) == 0; }]>;
  373. def imm_odd : ImmLeaf<i32, [{ return (Imm & 1) == 1; }]>;
  374. def asr_imm : ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }], asr_imm_XFORM>;
  375. //===----------------------------------------------------------------------===//
  376. // NEON/MVE pattern fragments
  377. //
  378. // Extract D sub-registers of Q registers.
  379. def DSubReg_i8_reg : SDNodeXForm<imm, [{
  380. assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
  381. return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/8, SDLoc(N),
  382. MVT::i32);
  383. }]>;
  384. def DSubReg_i16_reg : SDNodeXForm<imm, [{
  385. assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
  386. return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/4, SDLoc(N),
  387. MVT::i32);
  388. }]>;
  389. def DSubReg_i32_reg : SDNodeXForm<imm, [{
  390. assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
  391. return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/2, SDLoc(N),
  392. MVT::i32);
  393. }]>;
  394. def DSubReg_f64_reg : SDNodeXForm<imm, [{
  395. assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
  396. return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue(), SDLoc(N),
  397. MVT::i32);
  398. }]>;
  399. // Extract S sub-registers of Q/D registers.
  400. def SSubReg_f32_reg : SDNodeXForm<imm, [{
  401. assert(ARM::ssub_3 == ARM::ssub_0+3 && "Unexpected subreg numbering");
  402. return CurDAG->getTargetConstant(ARM::ssub_0 + N->getZExtValue(), SDLoc(N),
  403. MVT::i32);
  404. }]>;
  405. // Extract S sub-registers of Q/D registers containing a given f16/bf16 lane.
  406. def SSubReg_f16_reg : SDNodeXForm<imm, [{
  407. assert(ARM::ssub_3 == ARM::ssub_0+3 && "Unexpected subreg numbering");
  408. return CurDAG->getTargetConstant(ARM::ssub_0 + N->getZExtValue()/2, SDLoc(N),
  409. MVT::i32);
  410. }]>;
  411. // Translate lane numbers from Q registers to D subregs.
  412. def SubReg_i8_lane : SDNodeXForm<imm, [{
  413. return CurDAG->getTargetConstant(N->getZExtValue() & 7, SDLoc(N), MVT::i32);
  414. }]>;
  415. def SubReg_i16_lane : SDNodeXForm<imm, [{
  416. return CurDAG->getTargetConstant(N->getZExtValue() & 3, SDLoc(N), MVT::i32);
  417. }]>;
  418. def SubReg_i32_lane : SDNodeXForm<imm, [{
  419. return CurDAG->getTargetConstant(N->getZExtValue() & 1, SDLoc(N), MVT::i32);
  420. }]>;
  421. def ARMimmAllZerosV: PatLeaf<(bitconvert (v4i32 (ARMvmovImm (i32 0))))>;
  422. def ARMimmAllZerosD: PatLeaf<(bitconvert (v2i32 (ARMvmovImm (i32 0))))>;
  423. def ARMimmAllOnesV: PatLeaf<(bitconvert (v16i8 (ARMvmovImm (i32 0xEFF))))>;
  424. def ARMimmAllOnesD: PatLeaf<(bitconvert (v8i8 (ARMvmovImm (i32 0xEFF))))>;
  425. def ARMimmOneV: PatLeaf<(ARMvmovImm (i32 timm)), [{
  426. ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0));
  427. unsigned EltBits = 0;
  428. uint64_t EltVal = ARM_AM::decodeVMOVModImm(ConstVal->getZExtValue(), EltBits);
  429. return (EltBits == N->getValueType(0).getScalarSizeInBits() && EltVal == 0x01);
  430. }]>;
  431. //===----------------------------------------------------------------------===//
  432. // Operand Definitions.
  433. //
  434. // Immediate operands with a shared generic asm render method.
  435. class ImmAsmOperand<int Low, int High> : AsmOperandClass {
  436. let RenderMethod = "addImmOperands";
  437. let PredicateMethod = "isImmediate<" # Low # "," # High # ">";
  438. let DiagnosticString = "operand must be an immediate in the range [" # Low # "," # High # "]";
  439. }
  440. class ImmAsmOperandMinusOne<int Low, int High> : AsmOperandClass {
  441. let PredicateMethod = "isImmediate<" # Low # "," # High # ">";
  442. let DiagnosticType = "ImmRange" # Low # "_" # High;
  443. let DiagnosticString = "operand must be an immediate in the range [" # Low # "," # High # "]";
  444. }
  445. // Operands that are part of a memory addressing mode.
  446. class MemOperand : Operand<i32> { let OperandType = "OPERAND_MEMORY"; }
  447. // Branch target.
  448. // FIXME: rename brtarget to t2_brtarget
  449. def brtarget : Operand<OtherVT> {
  450. let EncoderMethod = "getBranchTargetOpValue";
  451. let OperandType = "OPERAND_PCREL";
  452. let DecoderMethod = "DecodeT2BROperand";
  453. }
  454. // Branches targeting ARM-mode must be divisible by 4 if they're a raw
  455. // immediate.
  456. def ARMBranchTarget : AsmOperandClass {
  457. let Name = "ARMBranchTarget";
  458. }
  459. // Branches targeting Thumb-mode must be divisible by 2 if they're a raw
  460. // immediate.
  461. def ThumbBranchTarget : AsmOperandClass {
  462. let Name = "ThumbBranchTarget";
  463. }
  464. def arm_br_target : Operand<OtherVT> {
  465. let ParserMatchClass = ARMBranchTarget;
  466. let EncoderMethod = "getARMBranchTargetOpValue";
  467. let OperandType = "OPERAND_PCREL";
  468. }
  469. // Call target for ARM. Handles conditional/unconditional
  470. // FIXME: rename bl_target to t2_bltarget?
  471. def arm_bl_target : Operand<i32> {
  472. let ParserMatchClass = ARMBranchTarget;
  473. let EncoderMethod = "getARMBLTargetOpValue";
  474. let OperandType = "OPERAND_PCREL";
  475. }
  476. // Target for BLX *from* ARM mode.
  477. def arm_blx_target : Operand<i32> {
  478. let ParserMatchClass = ThumbBranchTarget;
  479. let EncoderMethod = "getARMBLXTargetOpValue";
  480. let OperandType = "OPERAND_PCREL";
  481. }
  482. // A list of registers separated by comma. Used by load/store multiple.
  483. def RegListAsmOperand : AsmOperandClass { let Name = "RegList"; }
  484. def reglist : Operand<i32> {
  485. let EncoderMethod = "getRegisterListOpValue";
  486. let ParserMatchClass = RegListAsmOperand;
  487. let PrintMethod = "printRegisterList";
  488. let DecoderMethod = "DecodeRegListOperand";
  489. }
  490. // A list of general purpose registers and APSR separated by comma.
  491. // Used by CLRM
  492. def RegListWithAPSRAsmOperand : AsmOperandClass { let Name = "RegListWithAPSR"; }
  493. def reglist_with_apsr : Operand<i32> {
  494. let EncoderMethod = "getRegisterListOpValue";
  495. let ParserMatchClass = RegListWithAPSRAsmOperand;
  496. let PrintMethod = "printRegisterList";
  497. let DecoderMethod = "DecodeRegListOperand";
  498. }
  499. def GPRPairOp : RegisterOperand<GPRPair, "printGPRPairOperand">;
  500. def DPRRegListAsmOperand : AsmOperandClass {
  501. let Name = "DPRRegList";
  502. let DiagnosticType = "DPR_RegList";
  503. }
  504. def dpr_reglist : Operand<i32> {
  505. let EncoderMethod = "getRegisterListOpValue";
  506. let ParserMatchClass = DPRRegListAsmOperand;
  507. let PrintMethod = "printRegisterList";
  508. let DecoderMethod = "DecodeDPRRegListOperand";
  509. }
  510. def SPRRegListAsmOperand : AsmOperandClass {
  511. let Name = "SPRRegList";
  512. let DiagnosticString = "operand must be a list of registers in range [s0, s31]";
  513. }
  514. def spr_reglist : Operand<i32> {
  515. let EncoderMethod = "getRegisterListOpValue";
  516. let ParserMatchClass = SPRRegListAsmOperand;
  517. let PrintMethod = "printRegisterList";
  518. let DecoderMethod = "DecodeSPRRegListOperand";
  519. }
  520. def FPSRegListWithVPRAsmOperand : AsmOperandClass { let Name =
  521. "FPSRegListWithVPR"; }
  522. def fp_sreglist_with_vpr : Operand<i32> {
  523. let EncoderMethod = "getRegisterListOpValue";
  524. let ParserMatchClass = FPSRegListWithVPRAsmOperand;
  525. let PrintMethod = "printRegisterList";
  526. }
  527. def FPDRegListWithVPRAsmOperand : AsmOperandClass { let Name =
  528. "FPDRegListWithVPR"; }
  529. def fp_dreglist_with_vpr : Operand<i32> {
  530. let EncoderMethod = "getRegisterListOpValue";
  531. let ParserMatchClass = FPDRegListWithVPRAsmOperand;
  532. let PrintMethod = "printRegisterList";
  533. }
  534. // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
  535. def cpinst_operand : Operand<i32> {
  536. let PrintMethod = "printCPInstOperand";
  537. }
  538. // Local PC labels.
  539. def pclabel : Operand<i32> {
  540. let PrintMethod = "printPCLabel";
  541. }
  542. // ADR instruction labels.
  543. def AdrLabelAsmOperand : AsmOperandClass { let Name = "AdrLabel"; }
  544. def adrlabel : Operand<i32> {
  545. let EncoderMethod = "getAdrLabelOpValue";
  546. let ParserMatchClass = AdrLabelAsmOperand;
  547. let PrintMethod = "printAdrLabelOperand<0>";
  548. }
  549. def neon_vcvt_imm32 : Operand<i32> {
  550. let EncoderMethod = "getNEONVcvtImm32OpValue";
  551. let DecoderMethod = "DecodeVCVTImmOperand";
  552. }
  553. // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
  554. def rot_imm_XFORM: SDNodeXForm<imm, [{
  555. switch (N->getZExtValue()){
  556. default: llvm_unreachable(nullptr);
  557. case 0: return CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32);
  558. case 8: return CurDAG->getTargetConstant(1, SDLoc(N), MVT::i32);
  559. case 16: return CurDAG->getTargetConstant(2, SDLoc(N), MVT::i32);
  560. case 24: return CurDAG->getTargetConstant(3, SDLoc(N), MVT::i32);
  561. }
  562. }]>;
  563. def RotImmAsmOperand : AsmOperandClass {
  564. let Name = "RotImm";
  565. let ParserMethod = "parseRotImm";
  566. }
  567. def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
  568. int32_t v = N->getZExtValue();
  569. return v == 8 || v == 16 || v == 24; }],
  570. rot_imm_XFORM> {
  571. let PrintMethod = "printRotImmOperand";
  572. let ParserMatchClass = RotImmAsmOperand;
  573. }
  574. // Power-of-two operand for MVE VIDUP and friends, which encode
  575. // {1,2,4,8} as its log to base 2, i.e. as {0,1,2,3} respectively
  576. def MVE_VIDUP_imm_asmoperand : AsmOperandClass {
  577. let Name = "VIDUP_imm";
  578. let PredicateMethod = "isPowerTwoInRange<1,8>";
  579. let RenderMethod = "addPowerTwoOperands";
  580. let DiagnosticString = "vector increment immediate must be 1, 2, 4 or 8";
  581. }
  582. def MVE_VIDUP_imm : Operand<i32> {
  583. let EncoderMethod = "getPowerTwoOpValue";
  584. let DecoderMethod = "DecodePowerTwoOperand<0,3>";
  585. let ParserMatchClass = MVE_VIDUP_imm_asmoperand;
  586. }
  587. // Pair vector indexing
  588. class MVEPairVectorIndexOperand<string start, string end> : AsmOperandClass {
  589. let Name = "MVEPairVectorIndex"#start;
  590. let RenderMethod = "addMVEPairVectorIndexOperands";
  591. let PredicateMethod = "isMVEPairVectorIndex<"#start#", "#end#">";
  592. }
  593. class MVEPairVectorIndex<string opval> : Operand<i32> {
  594. let PrintMethod = "printVectorIndex";
  595. let EncoderMethod = "getMVEPairVectorIndexOpValue<"#opval#">";
  596. let DecoderMethod = "DecodeMVEPairVectorIndexOperand<"#opval#">";
  597. let MIOperandInfo = (ops i32imm);
  598. }
  599. def MVEPairVectorIndex0 : MVEPairVectorIndex<"0"> {
  600. let ParserMatchClass = MVEPairVectorIndexOperand<"0", "1">;
  601. }
  602. def MVEPairVectorIndex2 : MVEPairVectorIndex<"2"> {
  603. let ParserMatchClass = MVEPairVectorIndexOperand<"2", "3">;
  604. }
  605. // Vector indexing
  606. class MVEVectorIndexOperand<int NumLanes> : AsmOperandClass {
  607. let Name = "MVEVectorIndex"#NumLanes;
  608. let RenderMethod = "addMVEVectorIndexOperands";
  609. let PredicateMethod = "isVectorIndexInRange<"#NumLanes#">";
  610. }
  611. class MVEVectorIndex<int NumLanes> : Operand<i32> {
  612. let PrintMethod = "printVectorIndex";
  613. let ParserMatchClass = MVEVectorIndexOperand<NumLanes>;
  614. let MIOperandInfo = (ops i32imm);
  615. }
  616. // shift_imm: An integer that encodes a shift amount and the type of shift
  617. // (asr or lsl). The 6-bit immediate encodes as:
  618. // {5} 0 ==> lsl
  619. // 1 asr
  620. // {4-0} imm5 shift amount.
  621. // asr #32 encoded as imm5 == 0.
  622. def ShifterImmAsmOperand : AsmOperandClass {
  623. let Name = "ShifterImm";
  624. let ParserMethod = "parseShifterImm";
  625. }
  626. def shift_imm : Operand<i32> {
  627. let PrintMethod = "printShiftImmOperand";
  628. let ParserMatchClass = ShifterImmAsmOperand;
  629. }
  630. // shifter_operand operands: so_reg_reg, so_reg_imm, and mod_imm.
  631. def ShiftedRegAsmOperand : AsmOperandClass { let Name = "RegShiftedReg"; }
  632. def so_reg_reg : Operand<i32>, // reg reg imm
  633. ComplexPattern<i32, 3, "SelectRegShifterOperand",
  634. [shl, srl, sra, rotr]> {
  635. let EncoderMethod = "getSORegRegOpValue";
  636. let PrintMethod = "printSORegRegOperand";
  637. let DecoderMethod = "DecodeSORegRegOperand";
  638. let ParserMatchClass = ShiftedRegAsmOperand;
  639. let MIOperandInfo = (ops GPRnopc, GPRnopc, i32imm);
  640. }
  641. def ShiftedImmAsmOperand : AsmOperandClass { let Name = "RegShiftedImm"; }
  642. def so_reg_imm : Operand<i32>, // reg imm
  643. ComplexPattern<i32, 2, "SelectImmShifterOperand",
  644. [shl, srl, sra, rotr]> {
  645. let EncoderMethod = "getSORegImmOpValue";
  646. let PrintMethod = "printSORegImmOperand";
  647. let DecoderMethod = "DecodeSORegImmOperand";
  648. let ParserMatchClass = ShiftedImmAsmOperand;
  649. let MIOperandInfo = (ops GPR, i32imm);
  650. }
  651. // FIXME: Does this need to be distinct from so_reg?
  652. def shift_so_reg_reg : Operand<i32>, // reg reg imm
  653. ComplexPattern<i32, 3, "SelectShiftRegShifterOperand",
  654. [shl,srl,sra,rotr]> {
  655. let EncoderMethod = "getSORegRegOpValue";
  656. let PrintMethod = "printSORegRegOperand";
  657. let DecoderMethod = "DecodeSORegRegOperand";
  658. let ParserMatchClass = ShiftedRegAsmOperand;
  659. let MIOperandInfo = (ops GPR, GPR, i32imm);
  660. }
  661. // FIXME: Does this need to be distinct from so_reg?
  662. def shift_so_reg_imm : Operand<i32>, // reg reg imm
  663. ComplexPattern<i32, 2, "SelectShiftImmShifterOperand",
  664. [shl,srl,sra,rotr]> {
  665. let EncoderMethod = "getSORegImmOpValue";
  666. let PrintMethod = "printSORegImmOperand";
  667. let DecoderMethod = "DecodeSORegImmOperand";
  668. let ParserMatchClass = ShiftedImmAsmOperand;
  669. let MIOperandInfo = (ops GPR, i32imm);
  670. }
  671. // mod_imm: match a 32-bit immediate operand, which can be encoded into
  672. // a 12-bit immediate; an 8-bit integer and a 4-bit rotator (See ARMARM
  673. // - "Modified Immediate Constants"). Within the MC layer we keep this
  674. // immediate in its encoded form.
  675. def ModImmAsmOperand: AsmOperandClass {
  676. let Name = "ModImm";
  677. let ParserMethod = "parseModImm";
  678. }
  679. def mod_imm : Operand<i32>, ImmLeaf<i32, [{
  680. return ARM_AM::getSOImmVal(Imm) != -1;
  681. }]> {
  682. let EncoderMethod = "getModImmOpValue";
  683. let PrintMethod = "printModImmOperand";
  684. let ParserMatchClass = ModImmAsmOperand;
  685. }
  686. // Note: the patterns mod_imm_not and mod_imm_neg do not require an encoder
  687. // method and such, as they are only used on aliases (Pat<> and InstAlias<>).
  688. // The actual parsing, encoding, decoding are handled by the destination
  689. // instructions, which use mod_imm.
  690. def ModImmNotAsmOperand : AsmOperandClass { let Name = "ModImmNot"; }
  691. def mod_imm_not : Operand<i32>, PatLeaf<(imm), [{
  692. return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
  693. }], imm_not_XFORM> {
  694. let ParserMatchClass = ModImmNotAsmOperand;
  695. }
  696. def ModImmNegAsmOperand : AsmOperandClass { let Name = "ModImmNeg"; }
  697. def mod_imm_neg : Operand<i32>, PatLeaf<(imm), [{
  698. unsigned Value = -(unsigned)N->getZExtValue();
  699. return Value && ARM_AM::getSOImmVal(Value) != -1;
  700. }], imm_neg_XFORM> {
  701. let ParserMatchClass = ModImmNegAsmOperand;
  702. }
  703. /// arm_i32imm - True for +V6T2, or when isSOImmTwoParVal()
  704. def arm_i32imm : IntImmLeaf<i32, [{
  705. if (Subtarget->useMovt())
  706. return true;
  707. if (ARM_AM::isSOImmTwoPartVal(Imm.getZExtValue()))
  708. return true;
  709. return ARM_AM::isSOImmTwoPartValNeg(Imm.getZExtValue());
  710. }]>;
  711. /// imm0_1 predicate - Immediate in the range [0,1].
  712. def Imm0_1AsmOperand: ImmAsmOperand<0,1> { let Name = "Imm0_1"; }
  713. def imm0_1 : Operand<i32> { let ParserMatchClass = Imm0_1AsmOperand; }
  714. /// imm0_3 predicate - Immediate in the range [0,3].
  715. def Imm0_3AsmOperand: ImmAsmOperand<0,3> { let Name = "Imm0_3"; }
  716. def imm0_3 : Operand<i32> { let ParserMatchClass = Imm0_3AsmOperand; }
  717. /// imm0_7 predicate - Immediate in the range [0,7].
  718. def Imm0_7AsmOperand: ImmAsmOperand<0,7> {
  719. let Name = "Imm0_7";
  720. }
  721. def imm0_7 : Operand<i32>, ImmLeaf<i32, [{
  722. return Imm >= 0 && Imm < 8;
  723. }]> {
  724. let ParserMatchClass = Imm0_7AsmOperand;
  725. }
  726. /// imm8_255 predicate - Immediate in the range [8,255].
  727. def Imm8_255AsmOperand: ImmAsmOperand<8,255> { let Name = "Imm8_255"; }
  728. def imm8_255 : Operand<i32>, ImmLeaf<i32, [{
  729. return Imm >= 8 && Imm < 256;
  730. }]> {
  731. let ParserMatchClass = Imm8_255AsmOperand;
  732. }
  733. /// imm8 predicate - Immediate is exactly 8.
  734. def Imm8AsmOperand: ImmAsmOperand<8,8> { let Name = "Imm8"; }
  735. def imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 8; }]> {
  736. let ParserMatchClass = Imm8AsmOperand;
  737. }
  738. /// imm16 predicate - Immediate is exactly 16.
  739. def Imm16AsmOperand: ImmAsmOperand<16,16> { let Name = "Imm16"; }
  740. def imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 16; }]> {
  741. let ParserMatchClass = Imm16AsmOperand;
  742. }
  743. /// imm32 predicate - Immediate is exactly 32.
  744. def Imm32AsmOperand: ImmAsmOperand<32,32> { let Name = "Imm32"; }
  745. def imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 32; }]> {
  746. let ParserMatchClass = Imm32AsmOperand;
  747. }
  748. def imm8_or_16 : ImmLeaf<i32, [{ return Imm == 8 || Imm == 16;}]>;
  749. /// imm1_7 predicate - Immediate in the range [1,7].
  750. def Imm1_7AsmOperand: ImmAsmOperand<1,7> { let Name = "Imm1_7"; }
  751. def imm1_7 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 8; }]> {
  752. let ParserMatchClass = Imm1_7AsmOperand;
  753. }
  754. /// imm1_15 predicate - Immediate in the range [1,15].
  755. def Imm1_15AsmOperand: ImmAsmOperand<1,15> { let Name = "Imm1_15"; }
  756. def imm1_15 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 16; }]> {
  757. let ParserMatchClass = Imm1_15AsmOperand;
  758. }
  759. /// imm1_31 predicate - Immediate in the range [1,31].
  760. def Imm1_31AsmOperand: ImmAsmOperand<1,31> { let Name = "Imm1_31"; }
  761. def imm1_31 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 32; }]> {
  762. let ParserMatchClass = Imm1_31AsmOperand;
  763. }
  764. /// imm0_15 predicate - Immediate in the range [0,15].
  765. def Imm0_15AsmOperand: ImmAsmOperand<0,15> {
  766. let Name = "Imm0_15";
  767. }
  768. def imm0_15 : Operand<i32>, ImmLeaf<i32, [{
  769. return Imm >= 0 && Imm < 16;
  770. }]> {
  771. let ParserMatchClass = Imm0_15AsmOperand;
  772. }
  773. /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
  774. def Imm0_31AsmOperand: ImmAsmOperand<0,31> { let Name = "Imm0_31"; }
  775. def imm0_31 : Operand<i32>, ImmLeaf<i32, [{
  776. return Imm >= 0 && Imm < 32;
  777. }]> {
  778. let ParserMatchClass = Imm0_31AsmOperand;
  779. }
  780. /// imm0_32 predicate - True if the 32-bit immediate is in the range [0,32].
  781. def Imm0_32AsmOperand: ImmAsmOperand<0,32> { let Name = "Imm0_32"; }
  782. def imm0_32 : Operand<i32>, ImmLeaf<i32, [{
  783. return Imm >= 0 && Imm < 33;
  784. }]> {
  785. let ParserMatchClass = Imm0_32AsmOperand;
  786. }
  787. /// imm0_63 predicate - True if the 32-bit immediate is in the range [0,63].
  788. def Imm0_63AsmOperand: ImmAsmOperand<0,63> { let Name = "Imm0_63"; }
  789. def imm0_63 : Operand<i32>, ImmLeaf<i32, [{
  790. return Imm >= 0 && Imm < 64;
  791. }]> {
  792. let ParserMatchClass = Imm0_63AsmOperand;
  793. }
  794. /// imm0_239 predicate - Immediate in the range [0,239].
  795. def Imm0_239AsmOperand : ImmAsmOperand<0,239> {
  796. let Name = "Imm0_239";
  797. }
  798. def imm0_239 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 240; }]> {
  799. let ParserMatchClass = Imm0_239AsmOperand;
  800. }
  801. /// imm0_255 predicate - Immediate in the range [0,255].
  802. def Imm0_255AsmOperand : ImmAsmOperand<0,255> { let Name = "Imm0_255"; }
  803. def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> {
  804. let ParserMatchClass = Imm0_255AsmOperand;
  805. }
  806. /// imm0_65535 - An immediate is in the range [0,65535].
  807. def Imm0_65535AsmOperand: ImmAsmOperand<0,65535> { let Name = "Imm0_65535"; }
  808. def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
  809. return Imm >= 0 && Imm < 65536;
  810. }]> {
  811. let ParserMatchClass = Imm0_65535AsmOperand;
  812. }
  813. // imm0_65535_neg - An immediate whose negative value is in the range [0.65535].
  814. def imm0_65535_neg : Operand<i32>, ImmLeaf<i32, [{
  815. return -Imm >= 0 && -Imm < 65536;
  816. }]>;
  817. // imm0_65535_expr - For movt/movw - 16-bit immediate that can also reference
  818. // a relocatable expression.
  819. //
  820. // FIXME: This really needs a Thumb version separate from the ARM version.
  821. // While the range is the same, and can thus use the same match class,
  822. // the encoding is different so it should have a different encoder method.
  823. def Imm0_65535ExprAsmOperand: AsmOperandClass {
  824. let Name = "Imm0_65535Expr";
  825. let RenderMethod = "addImmOperands";
  826. let DiagnosticString = "operand must be an immediate in the range [0,0xffff] or a relocatable expression";
  827. }
  828. def imm0_65535_expr : Operand<i32> {
  829. let EncoderMethod = "getHiLo16ImmOpValue";
  830. let ParserMatchClass = Imm0_65535ExprAsmOperand;
  831. }
  832. def Imm256_65535ExprAsmOperand: ImmAsmOperand<256,65535> { let Name = "Imm256_65535Expr"; }
  833. def imm256_65535_expr : Operand<i32> {
  834. let ParserMatchClass = Imm256_65535ExprAsmOperand;
  835. }
  836. /// imm24b - True if the 32-bit immediate is encodable in 24 bits.
  837. def Imm24bitAsmOperand: ImmAsmOperand<0,0xffffff> {
  838. let Name = "Imm24bit";
  839. let DiagnosticString = "operand must be an immediate in the range [0,0xffffff]";
  840. }
  841. def imm24b : Operand<i32>, ImmLeaf<i32, [{
  842. return Imm >= 0 && Imm <= 0xffffff;
  843. }]> {
  844. let ParserMatchClass = Imm24bitAsmOperand;
  845. }
  846. /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
  847. /// e.g., 0xf000ffff
  848. def BitfieldAsmOperand : AsmOperandClass {
  849. let Name = "Bitfield";
  850. let ParserMethod = "parseBitfield";
  851. }
  852. def bf_inv_mask_imm : Operand<i32>,
  853. PatLeaf<(imm), [{
  854. return ARM::isBitFieldInvertedMask(N->getZExtValue());
  855. }] > {
  856. let EncoderMethod = "getBitfieldInvertedMaskOpValue";
  857. let PrintMethod = "printBitfieldInvMaskImmOperand";
  858. let DecoderMethod = "DecodeBitfieldMaskOperand";
  859. let ParserMatchClass = BitfieldAsmOperand;
  860. let GISelPredicateCode = [{
  861. // There's better methods of implementing this check. IntImmLeaf<> would be
  862. // equivalent and have less boilerplate but we need a test for C++
  863. // predicates and this one causes new rules to be imported into GlobalISel
  864. // without requiring additional features first.
  865. const auto &MO = MI.getOperand(1);
  866. if (!MO.isCImm())
  867. return false;
  868. return ARM::isBitFieldInvertedMask(MO.getCImm()->getZExtValue());
  869. }];
  870. }
  871. def imm1_32_XFORM: SDNodeXForm<imm, [{
  872. return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, SDLoc(N),
  873. MVT::i32);
  874. }]>;
  875. def Imm1_32AsmOperand: ImmAsmOperandMinusOne<1,32> {
  876. let Name = "Imm1_32";
  877. }
  878. def imm1_32 : Operand<i32>, PatLeaf<(imm), [{
  879. uint64_t Imm = N->getZExtValue();
  880. return Imm > 0 && Imm <= 32;
  881. }],
  882. imm1_32_XFORM> {
  883. let PrintMethod = "printImmPlusOneOperand";
  884. let ParserMatchClass = Imm1_32AsmOperand;
  885. }
  886. def imm1_16_XFORM: SDNodeXForm<imm, [{
  887. return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, SDLoc(N),
  888. MVT::i32);
  889. }]>;
  890. def Imm1_16AsmOperand: ImmAsmOperandMinusOne<1,16> { let Name = "Imm1_16"; }
  891. def imm1_16 : Operand<i32>, ImmLeaf<i32, [{
  892. return Imm > 0 && Imm <= 16;
  893. }],
  894. imm1_16_XFORM> {
  895. let PrintMethod = "printImmPlusOneOperand";
  896. let ParserMatchClass = Imm1_16AsmOperand;
  897. }
  898. def MVEShiftImm1_7AsmOperand: ImmAsmOperand<1,7> {
  899. let Name = "MVEShiftImm1_7";
  900. // Reason we're doing this is because instruction vshll.s8 t1 encoding
  901. // accepts 1,7 but the t2 encoding accepts 8. By doing this we can get a
  902. // better diagnostic message if someone uses bigger immediate than the t1/t2
  903. // encodings allow.
  904. let DiagnosticString = "operand must be an immediate in the range [1,8]";
  905. }
  906. def mve_shift_imm1_7 : Operand<i32>,
  907. // SelectImmediateInRange / isScaledConstantInRange uses a
  908. // half-open interval, so the parameters <1,8> mean 1-7 inclusive
  909. ComplexPattern<i32, 1, "SelectImmediateInRange<1,8>", [], []> {
  910. let ParserMatchClass = MVEShiftImm1_7AsmOperand;
  911. let EncoderMethod = "getMVEShiftImmOpValue";
  912. }
  913. def MVEShiftImm1_15AsmOperand: ImmAsmOperand<1,15> {
  914. let Name = "MVEShiftImm1_15";
  915. // Reason we're doing this is because instruction vshll.s16 t1 encoding
  916. // accepts 1,15 but the t2 encoding accepts 16. By doing this we can get a
  917. // better diagnostic message if someone uses bigger immediate than the t1/t2
  918. // encodings allow.
  919. let DiagnosticString = "operand must be an immediate in the range [1,16]";
  920. }
  921. def mve_shift_imm1_15 : Operand<i32>,
  922. // SelectImmediateInRange / isScaledConstantInRange uses a
  923. // half-open interval, so the parameters <1,16> mean 1-15 inclusive
  924. ComplexPattern<i32, 1, "SelectImmediateInRange<1,16>", [], []> {
  925. let ParserMatchClass = MVEShiftImm1_15AsmOperand;
  926. let EncoderMethod = "getMVEShiftImmOpValue";
  927. }
  928. // Define ARM specific addressing modes.
  929. // addrmode_imm12 := reg +/- imm12
  930. //
  931. def MemImm12OffsetAsmOperand : AsmOperandClass { let Name = "MemImm12Offset"; }
  932. class AddrMode_Imm12 : MemOperand,
  933. ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
  934. // 12-bit immediate operand. Note that instructions using this encode
  935. // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
  936. // immediate values are as normal.
  937. let EncoderMethod = "getAddrModeImm12OpValue";
  938. let DecoderMethod = "DecodeAddrModeImm12Operand";
  939. let ParserMatchClass = MemImm12OffsetAsmOperand;
  940. let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
  941. }
  942. def addrmode_imm12 : AddrMode_Imm12 {
  943. let PrintMethod = "printAddrModeImm12Operand<false>";
  944. }
  945. def addrmode_imm12_pre : AddrMode_Imm12 {
  946. let PrintMethod = "printAddrModeImm12Operand<true>";
  947. }
  948. // ldst_so_reg := reg +/- reg shop imm
  949. //
  950. def MemRegOffsetAsmOperand : AsmOperandClass { let Name = "MemRegOffset"; }
  951. def ldst_so_reg : MemOperand,
  952. ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
  953. let EncoderMethod = "getLdStSORegOpValue";
  954. // FIXME: Simplify the printer
  955. let PrintMethod = "printAddrMode2Operand";
  956. let DecoderMethod = "DecodeSORegMemOperand";
  957. let ParserMatchClass = MemRegOffsetAsmOperand;
  958. let MIOperandInfo = (ops GPR:$base, GPRnopc:$offsreg, i32imm:$shift);
  959. }
  960. // postidx_imm8 := +/- [0,255]
  961. //
  962. // 9 bit value:
  963. // {8} 1 is imm8 is non-negative. 0 otherwise.
  964. // {7-0} [0,255] imm8 value.
  965. def PostIdxImm8AsmOperand : AsmOperandClass { let Name = "PostIdxImm8"; }
  966. def postidx_imm8 : MemOperand {
  967. let PrintMethod = "printPostIdxImm8Operand";
  968. let ParserMatchClass = PostIdxImm8AsmOperand;
  969. let MIOperandInfo = (ops i32imm);
  970. }
  971. // postidx_imm8s4 := +/- [0,1020]
  972. //
  973. // 9 bit value:
  974. // {8} 1 is imm8 is non-negative. 0 otherwise.
  975. // {7-0} [0,255] imm8 value, scaled by 4.
  976. def PostIdxImm8s4AsmOperand : AsmOperandClass { let Name = "PostIdxImm8s4"; }
  977. def postidx_imm8s4 : MemOperand {
  978. let PrintMethod = "printPostIdxImm8s4Operand";
  979. let ParserMatchClass = PostIdxImm8s4AsmOperand;
  980. let MIOperandInfo = (ops i32imm);
  981. }
  982. // postidx_reg := +/- reg
  983. //
  984. def PostIdxRegAsmOperand : AsmOperandClass {
  985. let Name = "PostIdxReg";
  986. let ParserMethod = "parsePostIdxReg";
  987. }
  988. def postidx_reg : MemOperand {
  989. let EncoderMethod = "getPostIdxRegOpValue";
  990. let DecoderMethod = "DecodePostIdxReg";
  991. let PrintMethod = "printPostIdxRegOperand";
  992. let ParserMatchClass = PostIdxRegAsmOperand;
  993. let MIOperandInfo = (ops GPRnopc, i32imm);
  994. }
  995. def PostIdxRegShiftedAsmOperand : AsmOperandClass {
  996. let Name = "PostIdxRegShifted";
  997. let ParserMethod = "parsePostIdxReg";
  998. }
  999. def am2offset_reg : MemOperand,
  1000. ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg",
  1001. [], [SDNPWantRoot]> {
  1002. let EncoderMethod = "getAddrMode2OffsetOpValue";
  1003. let PrintMethod = "printAddrMode2OffsetOperand";
  1004. // When using this for assembly, it's always as a post-index offset.
  1005. let ParserMatchClass = PostIdxRegShiftedAsmOperand;
  1006. let MIOperandInfo = (ops GPRnopc, i32imm);
  1007. }
  1008. // FIXME: am2offset_imm should only need the immediate, not the GPR. Having
  1009. // the GPR is purely vestigal at this point.
  1010. def AM2OffsetImmAsmOperand : AsmOperandClass { let Name = "AM2OffsetImm"; }
  1011. def am2offset_imm : MemOperand,
  1012. ComplexPattern<i32, 2, "SelectAddrMode2OffsetImm",
  1013. [], [SDNPWantRoot]> {
  1014. let EncoderMethod = "getAddrMode2OffsetOpValue";
  1015. let PrintMethod = "printAddrMode2OffsetOperand";
  1016. let ParserMatchClass = AM2OffsetImmAsmOperand;
  1017. let MIOperandInfo = (ops GPRnopc, i32imm);
  1018. }
  1019. // addrmode3 := reg +/- reg
  1020. // addrmode3 := reg +/- imm8
  1021. //
  1022. // FIXME: split into imm vs. reg versions.
  1023. def AddrMode3AsmOperand : AsmOperandClass { let Name = "AddrMode3"; }
  1024. class AddrMode3 : MemOperand,
  1025. ComplexPattern<i32, 3, "SelectAddrMode3", []> {
  1026. let EncoderMethod = "getAddrMode3OpValue";
  1027. let ParserMatchClass = AddrMode3AsmOperand;
  1028. let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
  1029. }
  1030. def addrmode3 : AddrMode3
  1031. {
  1032. let PrintMethod = "printAddrMode3Operand<false>";
  1033. }
  1034. def addrmode3_pre : AddrMode3
  1035. {
  1036. let PrintMethod = "printAddrMode3Operand<true>";
  1037. }
  1038. // FIXME: split into imm vs. reg versions.
  1039. // FIXME: parser method to handle +/- register.
  1040. def AM3OffsetAsmOperand : AsmOperandClass {
  1041. let Name = "AM3Offset";
  1042. let ParserMethod = "parseAM3Offset";
  1043. }
  1044. def am3offset : MemOperand,
  1045. ComplexPattern<i32, 2, "SelectAddrMode3Offset",
  1046. [], [SDNPWantRoot]> {
  1047. let EncoderMethod = "getAddrMode3OffsetOpValue";
  1048. let PrintMethod = "printAddrMode3OffsetOperand";
  1049. let ParserMatchClass = AM3OffsetAsmOperand;
  1050. let MIOperandInfo = (ops GPR, i32imm);
  1051. }
  1052. // ldstm_mode := {ia, ib, da, db}
  1053. //
  1054. def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> {
  1055. let EncoderMethod = "getLdStmModeOpValue";
  1056. let PrintMethod = "printLdStmModeOperand";
  1057. }
  1058. // addrmode5 := reg +/- imm8*4
  1059. //
  1060. def AddrMode5AsmOperand : AsmOperandClass { let Name = "AddrMode5"; }
  1061. class AddrMode5 : MemOperand,
  1062. ComplexPattern<i32, 2, "SelectAddrMode5", []> {
  1063. let EncoderMethod = "getAddrMode5OpValue";
  1064. let DecoderMethod = "DecodeAddrMode5Operand";
  1065. let ParserMatchClass = AddrMode5AsmOperand;
  1066. let MIOperandInfo = (ops GPR:$base, i32imm);
  1067. }
  1068. def addrmode5 : AddrMode5 {
  1069. let PrintMethod = "printAddrMode5Operand<false>";
  1070. }
  1071. def addrmode5_pre : AddrMode5 {
  1072. let PrintMethod = "printAddrMode5Operand<true>";
  1073. }
  1074. // addrmode5fp16 := reg +/- imm8*2
  1075. //
  1076. def AddrMode5FP16AsmOperand : AsmOperandClass { let Name = "AddrMode5FP16"; }
  1077. class AddrMode5FP16 : MemOperand,
  1078. ComplexPattern<i32, 2, "SelectAddrMode5FP16", []> {
  1079. let EncoderMethod = "getAddrMode5FP16OpValue";
  1080. let DecoderMethod = "DecodeAddrMode5FP16Operand";
  1081. let ParserMatchClass = AddrMode5FP16AsmOperand;
  1082. let MIOperandInfo = (ops GPR:$base, i32imm);
  1083. }
  1084. def addrmode5fp16 : AddrMode5FP16 {
  1085. let PrintMethod = "printAddrMode5FP16Operand<false>";
  1086. }
  1087. // addrmode6 := reg with optional alignment
  1088. //
  1089. def AddrMode6AsmOperand : AsmOperandClass { let Name = "AlignedMemory"; }
  1090. def addrmode6 : MemOperand,
  1091. ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
  1092. let PrintMethod = "printAddrMode6Operand";
  1093. let MIOperandInfo = (ops GPR:$addr, i32imm:$align);
  1094. let EncoderMethod = "getAddrMode6AddressOpValue";
  1095. let DecoderMethod = "DecodeAddrMode6Operand";
  1096. let ParserMatchClass = AddrMode6AsmOperand;
  1097. }
  1098. def am6offset : MemOperand,
  1099. ComplexPattern<i32, 1, "SelectAddrMode6Offset",
  1100. [], [SDNPWantRoot]> {
  1101. let PrintMethod = "printAddrMode6OffsetOperand";
  1102. let MIOperandInfo = (ops GPR);
  1103. let EncoderMethod = "getAddrMode6OffsetOpValue";
  1104. let DecoderMethod = "DecodeGPRRegisterClass";
  1105. }
  1106. // Special version of addrmode6 to handle alignment encoding for VST1/VLD1
  1107. // (single element from one lane) for size 32.
  1108. def addrmode6oneL32 : MemOperand,
  1109. ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
  1110. let PrintMethod = "printAddrMode6Operand";
  1111. let MIOperandInfo = (ops GPR:$addr, i32imm);
  1112. let EncoderMethod = "getAddrMode6OneLane32AddressOpValue";
  1113. }
  1114. // Base class for addrmode6 with specific alignment restrictions.
  1115. class AddrMode6Align : MemOperand,
  1116. ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
  1117. let PrintMethod = "printAddrMode6Operand";
  1118. let MIOperandInfo = (ops GPR:$addr, i32imm:$align);
  1119. let EncoderMethod = "getAddrMode6AddressOpValue";
  1120. let DecoderMethod = "DecodeAddrMode6Operand";
  1121. }
  1122. // Special version of addrmode6 to handle no allowed alignment encoding for
  1123. // VLD/VST instructions and checking the alignment is not specified.
  1124. def AddrMode6AlignNoneAsmOperand : AsmOperandClass {
  1125. let Name = "AlignedMemoryNone";
  1126. let DiagnosticString = "alignment must be omitted";
  1127. }
  1128. def addrmode6alignNone : AddrMode6Align {
  1129. // The alignment specifier can only be omitted.
  1130. let ParserMatchClass = AddrMode6AlignNoneAsmOperand;
  1131. }
  1132. // Special version of addrmode6 to handle 16-bit alignment encoding for
  1133. // VLD/VST instructions and checking the alignment value.
  1134. def AddrMode6Align16AsmOperand : AsmOperandClass {
  1135. let Name = "AlignedMemory16";
  1136. let DiagnosticString = "alignment must be 16 or omitted";
  1137. }
  1138. def addrmode6align16 : AddrMode6Align {
  1139. // The alignment specifier can only be 16 or omitted.
  1140. let ParserMatchClass = AddrMode6Align16AsmOperand;
  1141. }
  1142. // Special version of addrmode6 to handle 32-bit alignment encoding for
  1143. // VLD/VST instructions and checking the alignment value.
  1144. def AddrMode6Align32AsmOperand : AsmOperandClass {
  1145. let Name = "AlignedMemory32";
  1146. let DiagnosticString = "alignment must be 32 or omitted";
  1147. }
  1148. def addrmode6align32 : AddrMode6Align {
  1149. // The alignment specifier can only be 32 or omitted.
  1150. let ParserMatchClass = AddrMode6Align32AsmOperand;
  1151. }
  1152. // Special version of addrmode6 to handle 64-bit alignment encoding for
  1153. // VLD/VST instructions and checking the alignment value.
  1154. def AddrMode6Align64AsmOperand : AsmOperandClass {
  1155. let Name = "AlignedMemory64";
  1156. let DiagnosticString = "alignment must be 64 or omitted";
  1157. }
  1158. def addrmode6align64 : AddrMode6Align {
  1159. // The alignment specifier can only be 64 or omitted.
  1160. let ParserMatchClass = AddrMode6Align64AsmOperand;
  1161. }
  1162. // Special version of addrmode6 to handle 64-bit or 128-bit alignment encoding
  1163. // for VLD/VST instructions and checking the alignment value.
  1164. def AddrMode6Align64or128AsmOperand : AsmOperandClass {
  1165. let Name = "AlignedMemory64or128";
  1166. let DiagnosticString = "alignment must be 64, 128 or omitted";
  1167. }
  1168. def addrmode6align64or128 : AddrMode6Align {
  1169. // The alignment specifier can only be 64, 128 or omitted.
  1170. let ParserMatchClass = AddrMode6Align64or128AsmOperand;
  1171. }
  1172. // Special version of addrmode6 to handle 64-bit, 128-bit or 256-bit alignment
  1173. // encoding for VLD/VST instructions and checking the alignment value.
  1174. def AddrMode6Align64or128or256AsmOperand : AsmOperandClass {
  1175. let Name = "AlignedMemory64or128or256";
  1176. let DiagnosticString = "alignment must be 64, 128, 256 or omitted";
  1177. }
  1178. def addrmode6align64or128or256 : AddrMode6Align {
  1179. // The alignment specifier can only be 64, 128, 256 or omitted.
  1180. let ParserMatchClass = AddrMode6Align64or128or256AsmOperand;
  1181. }
  1182. // Special version of addrmode6 to handle alignment encoding for VLD-dup
  1183. // instructions, specifically VLD4-dup.
  1184. def addrmode6dup : MemOperand,
  1185. ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
  1186. let PrintMethod = "printAddrMode6Operand";
  1187. let MIOperandInfo = (ops GPR:$addr, i32imm);
  1188. let EncoderMethod = "getAddrMode6DupAddressOpValue";
  1189. // FIXME: This is close, but not quite right. The alignment specifier is
  1190. // different.
  1191. let ParserMatchClass = AddrMode6AsmOperand;
  1192. }
  1193. // Base class for addrmode6dup with specific alignment restrictions.
  1194. class AddrMode6DupAlign : MemOperand,
  1195. ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
  1196. let PrintMethod = "printAddrMode6Operand";
  1197. let MIOperandInfo = (ops GPR:$addr, i32imm);
  1198. let EncoderMethod = "getAddrMode6DupAddressOpValue";
  1199. }
  1200. // Special version of addrmode6 to handle no allowed alignment encoding for
  1201. // VLD-dup instruction and checking the alignment is not specified.
  1202. def AddrMode6dupAlignNoneAsmOperand : AsmOperandClass {
  1203. let Name = "DupAlignedMemoryNone";
  1204. let DiagnosticString = "alignment must be omitted";
  1205. }
  1206. def addrmode6dupalignNone : AddrMode6DupAlign {
  1207. // The alignment specifier can only be omitted.
  1208. let ParserMatchClass = AddrMode6dupAlignNoneAsmOperand;
  1209. }
  1210. // Special version of addrmode6 to handle 16-bit alignment encoding for VLD-dup
  1211. // instruction and checking the alignment value.
  1212. def AddrMode6dupAlign16AsmOperand : AsmOperandClass {
  1213. let Name = "DupAlignedMemory16";
  1214. let DiagnosticString = "alignment must be 16 or omitted";
  1215. }
  1216. def addrmode6dupalign16 : AddrMode6DupAlign {
  1217. // The alignment specifier can only be 16 or omitted.
  1218. let ParserMatchClass = AddrMode6dupAlign16AsmOperand;
  1219. }
  1220. // Special version of addrmode6 to handle 32-bit alignment encoding for VLD-dup
  1221. // instruction and checking the alignment value.
  1222. def AddrMode6dupAlign32AsmOperand : AsmOperandClass {
  1223. let Name = "DupAlignedMemory32";
  1224. let DiagnosticString = "alignment must be 32 or omitted";
  1225. }
  1226. def addrmode6dupalign32 : AddrMode6DupAlign {
  1227. // The alignment specifier can only be 32 or omitted.
  1228. let ParserMatchClass = AddrMode6dupAlign32AsmOperand;
  1229. }
  1230. // Special version of addrmode6 to handle 64-bit alignment encoding for VLD
  1231. // instructions and checking the alignment value.
  1232. def AddrMode6dupAlign64AsmOperand : AsmOperandClass {
  1233. let Name = "DupAlignedMemory64";
  1234. let DiagnosticString = "alignment must be 64 or omitted";
  1235. }
  1236. def addrmode6dupalign64 : AddrMode6DupAlign {
  1237. // The alignment specifier can only be 64 or omitted.
  1238. let ParserMatchClass = AddrMode6dupAlign64AsmOperand;
  1239. }
  1240. // Special version of addrmode6 to handle 64-bit or 128-bit alignment encoding
  1241. // for VLD instructions and checking the alignment value.
  1242. def AddrMode6dupAlign64or128AsmOperand : AsmOperandClass {
  1243. let Name = "DupAlignedMemory64or128";
  1244. let DiagnosticString = "alignment must be 64, 128 or omitted";
  1245. }
  1246. def addrmode6dupalign64or128 : AddrMode6DupAlign {
  1247. // The alignment specifier can only be 64, 128 or omitted.
  1248. let ParserMatchClass = AddrMode6dupAlign64or128AsmOperand;
  1249. }
  1250. // addrmodepc := pc + reg
  1251. //
  1252. def addrmodepc : MemOperand,
  1253. ComplexPattern<i32, 2, "SelectAddrModePC", []> {
  1254. let PrintMethod = "printAddrModePCOperand";
  1255. let MIOperandInfo = (ops GPR, i32imm);
  1256. }
  1257. // addr_offset_none := reg
  1258. //
  1259. def MemNoOffsetAsmOperand : AsmOperandClass { let Name = "MemNoOffset"; }
  1260. def addr_offset_none : MemOperand,
  1261. ComplexPattern<i32, 1, "SelectAddrOffsetNone", []> {
  1262. let PrintMethod = "printAddrMode7Operand";
  1263. let DecoderMethod = "DecodeAddrMode7Operand";
  1264. let ParserMatchClass = MemNoOffsetAsmOperand;
  1265. let MIOperandInfo = (ops GPR:$base);
  1266. }
  1267. // t_addr_offset_none := reg [r0-r7]
  1268. def MemNoOffsetTAsmOperand : AsmOperandClass { let Name = "MemNoOffsetT"; }
  1269. def t_addr_offset_none : MemOperand {
  1270. let PrintMethod = "printAddrMode7Operand";
  1271. let DecoderMethod = "DecodetGPRRegisterClass";
  1272. let ParserMatchClass = MemNoOffsetTAsmOperand;
  1273. let MIOperandInfo = (ops tGPR:$base);
  1274. }
  1275. def nohash_imm : Operand<i32> {
  1276. let PrintMethod = "printNoHashImmediate";
  1277. }
  1278. def CoprocNumAsmOperand : AsmOperandClass {
  1279. let Name = "CoprocNum";
  1280. let ParserMethod = "parseCoprocNumOperand";
  1281. }
  1282. def p_imm : Operand<i32> {
  1283. let PrintMethod = "printPImmediate";
  1284. let ParserMatchClass = CoprocNumAsmOperand;
  1285. let DecoderMethod = "DecodeCoprocessor";
  1286. }
  1287. def CoprocRegAsmOperand : AsmOperandClass {
  1288. let Name = "CoprocReg";
  1289. let ParserMethod = "parseCoprocRegOperand";
  1290. }
  1291. def c_imm : Operand<i32> {
  1292. let PrintMethod = "printCImmediate";
  1293. let ParserMatchClass = CoprocRegAsmOperand;
  1294. }
  1295. def CoprocOptionAsmOperand : AsmOperandClass {
  1296. let Name = "CoprocOption";
  1297. let ParserMethod = "parseCoprocOptionOperand";
  1298. }
  1299. def coproc_option_imm : Operand<i32> {
  1300. let PrintMethod = "printCoprocOptionImm";
  1301. let ParserMatchClass = CoprocOptionAsmOperand;
  1302. }
  1303. //===----------------------------------------------------------------------===//
  1304. include "ARMInstrFormats.td"
  1305. //===----------------------------------------------------------------------===//
  1306. // Multiclass helpers...
  1307. //
  1308. /// AsI1_bin_irs - Defines a set of (op r, {mod_imm|r|so_reg}) patterns for a
  1309. /// binop that produces a value.
  1310. let TwoOperandAliasConstraint = "$Rn = $Rd" in
  1311. multiclass AsI1_bin_irs<bits<4> opcod, string opc,
  1312. InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
  1313. SDPatternOperator opnode, bit Commutable = 0> {
  1314. // The register-immediate version is re-materializable. This is useful
  1315. // in particular for taking the address of a local.
  1316. let isReMaterializable = 1 in {
  1317. def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm), DPFrm,
  1318. iii, opc, "\t$Rd, $Rn, $imm",
  1319. [(set GPR:$Rd, (opnode GPR:$Rn, mod_imm:$imm))]>,
  1320. Sched<[WriteALU, ReadALU]> {
  1321. bits<4> Rd;
  1322. bits<4> Rn;
  1323. bits<12> imm;
  1324. let Inst{25} = 1;
  1325. let Inst{19-16} = Rn;
  1326. let Inst{15-12} = Rd;
  1327. let Inst{11-0} = imm;
  1328. }
  1329. }
  1330. def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
  1331. iir, opc, "\t$Rd, $Rn, $Rm",
  1332. [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>,
  1333. Sched<[WriteALU, ReadALU, ReadALU]> {
  1334. bits<4> Rd;
  1335. bits<4> Rn;
  1336. bits<4> Rm;
  1337. let Inst{25} = 0;
  1338. let isCommutable = Commutable;
  1339. let Inst{19-16} = Rn;
  1340. let Inst{15-12} = Rd;
  1341. let Inst{11-4} = 0b00000000;
  1342. let Inst{3-0} = Rm;
  1343. }
  1344. def rsi : AsI1<opcod, (outs GPR:$Rd),
  1345. (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm,
  1346. iis, opc, "\t$Rd, $Rn, $shift",
  1347. [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]>,
  1348. Sched<[WriteALUsi, ReadALU]> {
  1349. bits<4> Rd;
  1350. bits<4> Rn;
  1351. bits<12> shift;
  1352. let Inst{25} = 0;
  1353. let Inst{19-16} = Rn;
  1354. let Inst{15-12} = Rd;
  1355. let Inst{11-5} = shift{11-5};
  1356. let Inst{4} = 0;
  1357. let Inst{3-0} = shift{3-0};
  1358. }
  1359. def rsr : AsI1<opcod, (outs GPR:$Rd),
  1360. (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm,
  1361. iis, opc, "\t$Rd, $Rn, $shift",
  1362. [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]>,
  1363. Sched<[WriteALUsr, ReadALUsr]> {
  1364. bits<4> Rd;
  1365. bits<4> Rn;
  1366. bits<12> shift;
  1367. let Inst{25} = 0;
  1368. let Inst{19-16} = Rn;
  1369. let Inst{15-12} = Rd;
  1370. let Inst{11-8} = shift{11-8};
  1371. let Inst{7} = 0;
  1372. let Inst{6-5} = shift{6-5};
  1373. let Inst{4} = 1;
  1374. let Inst{3-0} = shift{3-0};
  1375. }
  1376. }
  1377. /// AsI1_rbin_irs - Same as AsI1_bin_irs except the order of operands are
  1378. /// reversed. The 'rr' form is only defined for the disassembler; for codegen
  1379. /// it is equivalent to the AsI1_bin_irs counterpart.
  1380. let TwoOperandAliasConstraint = "$Rn = $Rd" in
  1381. multiclass AsI1_rbin_irs<bits<4> opcod, string opc,
  1382. InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
  1383. SDNode opnode> {
  1384. // The register-immediate version is re-materializable. This is useful
  1385. // in particular for taking the address of a local.
  1386. let isReMaterializable = 1 in {
  1387. def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm), DPFrm,
  1388. iii, opc, "\t$Rd, $Rn, $imm",
  1389. [(set GPR:$Rd, (opnode mod_imm:$imm, GPR:$Rn))]>,
  1390. Sched<[WriteALU, ReadALU]> {
  1391. bits<4> Rd;
  1392. bits<4> Rn;
  1393. bits<12> imm;
  1394. let Inst{25} = 1;
  1395. let Inst{19-16} = Rn;
  1396. let Inst{15-12} = Rd;
  1397. let Inst{11-0} = imm;
  1398. }
  1399. }
  1400. def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
  1401. iir, opc, "\t$Rd, $Rn, $Rm",
  1402. [/* pattern left blank */]>,
  1403. Sched<[WriteALU, ReadALU, ReadALU]> {
  1404. bits<4> Rd;
  1405. bits<4> Rn;
  1406. bits<4> Rm;
  1407. let Inst{11-4} = 0b00000000;
  1408. let Inst{25} = 0;
  1409. let Inst{3-0} = Rm;
  1410. let Inst{15-12} = Rd;
  1411. let Inst{19-16} = Rn;
  1412. }
  1413. def rsi : AsI1<opcod, (outs GPR:$Rd),
  1414. (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm,
  1415. iis, opc, "\t$Rd, $Rn, $shift",
  1416. [(set GPR:$Rd, (opnode so_reg_imm:$shift, GPR:$Rn))]>,
  1417. Sched<[WriteALUsi, ReadALU]> {
  1418. bits<4> Rd;
  1419. bits<4> Rn;
  1420. bits<12> shift;
  1421. let Inst{25} = 0;
  1422. let Inst{19-16} = Rn;
  1423. let Inst{15-12} = Rd;
  1424. let Inst{11-5} = shift{11-5};
  1425. let Inst{4} = 0;
  1426. let Inst{3-0} = shift{3-0};
  1427. }
  1428. def rsr : AsI1<opcod, (outs GPR:$Rd),
  1429. (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm,
  1430. iis, opc, "\t$Rd, $Rn, $shift",
  1431. [(set GPR:$Rd, (opnode so_reg_reg:$shift, GPR:$Rn))]>,
  1432. Sched<[WriteALUsr, ReadALUsr]> {
  1433. bits<4> Rd;
  1434. bits<4> Rn;
  1435. bits<12> shift;
  1436. let Inst{25} = 0;
  1437. let Inst{19-16} = Rn;
  1438. let Inst{15-12} = Rd;
  1439. let Inst{11-8} = shift{11-8};
  1440. let Inst{7} = 0;
  1441. let Inst{6-5} = shift{6-5};
  1442. let Inst{4} = 1;
  1443. let Inst{3-0} = shift{3-0};
  1444. }
  1445. }
  1446. /// AsI1_bin_s_irs - Same as AsI1_bin_irs except it sets the 's' bit by default.
  1447. ///
  1448. /// These opcodes will be converted to the real non-S opcodes by
  1449. /// AdjustInstrPostInstrSelection after giving them an optional CPSR operand.
  1450. let hasPostISelHook = 1, Defs = [CPSR] in {
  1451. multiclass AsI1_bin_s_irs<InstrItinClass iii, InstrItinClass iir,
  1452. InstrItinClass iis, SDNode opnode,
  1453. bit Commutable = 0> {
  1454. def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm, pred:$p),
  1455. 4, iii,
  1456. [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, mod_imm:$imm))]>,
  1457. Sched<[WriteALU, ReadALU]>;
  1458. def rr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, pred:$p),
  1459. 4, iir,
  1460. [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm))]>,
  1461. Sched<[WriteALU, ReadALU, ReadALU]> {
  1462. let isCommutable = Commutable;
  1463. }
  1464. def rsi : ARMPseudoInst<(outs GPR:$Rd),
  1465. (ins GPR:$Rn, so_reg_imm:$shift, pred:$p),
  1466. 4, iis,
  1467. [(set GPR:$Rd, CPSR, (opnode GPR:$Rn,
  1468. so_reg_imm:$shift))]>,
  1469. Sched<[WriteALUsi, ReadALU]>;
  1470. def rsr : ARMPseudoInst<(outs GPR:$Rd),
  1471. (ins GPR:$Rn, so_reg_reg:$shift, pred:$p),
  1472. 4, iis,
  1473. [(set GPR:$Rd, CPSR, (opnode GPR:$Rn,
  1474. so_reg_reg:$shift))]>,
  1475. Sched<[WriteALUSsr, ReadALUsr]>;
  1476. }
  1477. }
  1478. /// AsI1_rbin_s_is - Same as AsI1_bin_s_irs, except selection DAG
  1479. /// operands are reversed.
  1480. let hasPostISelHook = 1, Defs = [CPSR] in {
  1481. multiclass AsI1_rbin_s_is<InstrItinClass iii,
  1482. InstrItinClass iis, SDNode opnode> {
  1483. def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm, pred:$p),
  1484. 4, iii,
  1485. [(set GPR:$Rd, CPSR, (opnode mod_imm:$imm, GPR:$Rn))]>,
  1486. Sched<[WriteALU, ReadALU]>;
  1487. def rsi : ARMPseudoInst<(outs GPR:$Rd),
  1488. (ins GPR:$Rn, so_reg_imm:$shift, pred:$p),
  1489. 4, iis,
  1490. [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift,
  1491. GPR:$Rn))]>,
  1492. Sched<[WriteALUsi, ReadALU]>;
  1493. def rsr : ARMPseudoInst<(outs GPR:$Rd),
  1494. (ins GPR:$Rn, so_reg_reg:$shift, pred:$p),
  1495. 4, iis,
  1496. [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift,
  1497. GPR:$Rn))]>,
  1498. Sched<[WriteALUSsr, ReadALUsr]>;
  1499. }
  1500. }
  1501. /// AI1_cmp_irs - Defines a set of (op r, {mod_imm|r|so_reg}) cmp / test
  1502. /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
  1503. /// a explicit result, only implicitly set CPSR.
  1504. let isCompare = 1, Defs = [CPSR] in {
  1505. multiclass AI1_cmp_irs<bits<4> opcod, string opc,
  1506. InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
  1507. SDPatternOperator opnode, bit Commutable = 0,
  1508. string rrDecoderMethod = ""> {
  1509. def ri : AI1<opcod, (outs), (ins GPR:$Rn, mod_imm:$imm), DPFrm, iii,
  1510. opc, "\t$Rn, $imm",
  1511. [(opnode GPR:$Rn, mod_imm:$imm)]>,
  1512. Sched<[WriteCMP, ReadALU]> {
  1513. bits<4> Rn;
  1514. bits<12> imm;
  1515. let Inst{25} = 1;
  1516. let Inst{20} = 1;
  1517. let Inst{19-16} = Rn;
  1518. let Inst{15-12} = 0b0000;
  1519. let Inst{11-0} = imm;
  1520. let Unpredictable{15-12} = 0b1111;
  1521. }
  1522. def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir,
  1523. opc, "\t$Rn, $Rm",
  1524. [(opnode GPR:$Rn, GPR:$Rm)]>,
  1525. Sched<[WriteCMP, ReadALU, ReadALU]> {
  1526. bits<4> Rn;
  1527. bits<4> Rm;
  1528. let isCommutable = Commutable;
  1529. let Inst{25} = 0;
  1530. let Inst{20} = 1;
  1531. let Inst{19-16} = Rn;
  1532. let Inst{15-12} = 0b0000;
  1533. let Inst{11-4} = 0b00000000;
  1534. let Inst{3-0} = Rm;
  1535. let DecoderMethod = rrDecoderMethod;
  1536. let Unpredictable{15-12} = 0b1111;
  1537. }
  1538. def rsi : AI1<opcod, (outs),
  1539. (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, iis,
  1540. opc, "\t$Rn, $shift",
  1541. [(opnode GPR:$Rn, so_reg_imm:$shift)]>,
  1542. Sched<[WriteCMPsi, ReadALU]> {
  1543. bits<4> Rn;
  1544. bits<12> shift;
  1545. let Inst{25} = 0;
  1546. let Inst{20} = 1;
  1547. let Inst{19-16} = Rn;
  1548. let Inst{15-12} = 0b0000;
  1549. let Inst{11-5} = shift{11-5};
  1550. let Inst{4} = 0;
  1551. let Inst{3-0} = shift{3-0};
  1552. let Unpredictable{15-12} = 0b1111;
  1553. }
  1554. def rsr : AI1<opcod, (outs),
  1555. (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, iis,
  1556. opc, "\t$Rn, $shift",
  1557. [(opnode GPRnopc:$Rn, so_reg_reg:$shift)]>,
  1558. Sched<[WriteCMPsr, ReadALU]> {
  1559. bits<4> Rn;
  1560. bits<12> shift;
  1561. let Inst{25} = 0;
  1562. let Inst{20} = 1;
  1563. let Inst{19-16} = Rn;
  1564. let Inst{15-12} = 0b0000;
  1565. let Inst{11-8} = shift{11-8};
  1566. let Inst{7} = 0;
  1567. let Inst{6-5} = shift{6-5};
  1568. let Inst{4} = 1;
  1569. let Inst{3-0} = shift{3-0};
  1570. let Unpredictable{15-12} = 0b1111;
  1571. }
  1572. }
  1573. }
  1574. /// AI_ext_rrot - A unary operation with two forms: one whose operand is a
  1575. /// register and one whose operand is a register rotated by 8/16/24.
  1576. /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
  1577. class AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode>
  1578. : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot),
  1579. IIC_iEXTr, opc, "\t$Rd, $Rm$rot",
  1580. [(set GPRnopc:$Rd, (opnode (rotr GPRnopc:$Rm, rot_imm:$rot)))]>,
  1581. Requires<[IsARM, HasV6]>, Sched<[WriteALUsi]> {
  1582. bits<4> Rd;
  1583. bits<4> Rm;
  1584. bits<2> rot;
  1585. let Inst{19-16} = 0b1111;
  1586. let Inst{15-12} = Rd;
  1587. let Inst{11-10} = rot;
  1588. let Inst{3-0} = Rm;
  1589. }
  1590. class AI_ext_rrot_np<bits<8> opcod, string opc>
  1591. : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot),
  1592. IIC_iEXTr, opc, "\t$Rd, $Rm$rot", []>,
  1593. Requires<[IsARM, HasV6]>, Sched<[WriteALUsi]> {
  1594. bits<2> rot;
  1595. let Inst{19-16} = 0b1111;
  1596. let Inst{11-10} = rot;
  1597. }
  1598. /// AI_exta_rrot - A binary operation with two forms: one whose operand is a
  1599. /// register and one whose operand is a register rotated by 8/16/24.
  1600. class AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode>
  1601. : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot),
  1602. IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot",
  1603. [(set GPRnopc:$Rd, (opnode GPR:$Rn,
  1604. (rotr GPRnopc:$Rm, rot_imm:$rot)))]>,
  1605. Requires<[IsARM, HasV6]>, Sched<[WriteALUsr]> {
  1606. bits<4> Rd;
  1607. bits<4> Rm;
  1608. bits<4> Rn;
  1609. bits<2> rot;
  1610. let Inst{19-16} = Rn;
  1611. let Inst{15-12} = Rd;
  1612. let Inst{11-10} = rot;
  1613. let Inst{9-4} = 0b000111;
  1614. let Inst{3-0} = Rm;
  1615. }
  1616. class AI_exta_rrot_np<bits<8> opcod, string opc>
  1617. : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot),
  1618. IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot", []>,
  1619. Requires<[IsARM, HasV6]>, Sched<[WriteALUsr]> {
  1620. bits<4> Rn;
  1621. bits<2> rot;
  1622. let Inst{19-16} = Rn;
  1623. let Inst{11-10} = rot;
  1624. }
  1625. /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
  1626. let TwoOperandAliasConstraint = "$Rn = $Rd" in
  1627. multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, SDNode opnode,
  1628. bit Commutable = 0> {
  1629. let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in {
  1630. def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm),
  1631. DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
  1632. [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, mod_imm:$imm, CPSR))]>,
  1633. Requires<[IsARM]>,
  1634. Sched<[WriteALU, ReadALU]> {
  1635. bits<4> Rd;
  1636. bits<4> Rn;
  1637. bits<12> imm;
  1638. let Inst{25} = 1;
  1639. let Inst{15-12} = Rd;
  1640. let Inst{19-16} = Rn;
  1641. let Inst{11-0} = imm;
  1642. }
  1643. def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
  1644. DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
  1645. [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm, CPSR))]>,
  1646. Requires<[IsARM]>,
  1647. Sched<[WriteALU, ReadALU, ReadALU]> {
  1648. bits<4> Rd;
  1649. bits<4> Rn;
  1650. bits<4> Rm;
  1651. let Inst{11-4} = 0b00000000;
  1652. let Inst{25} = 0;
  1653. let isCommutable = Commutable;
  1654. let Inst{3-0} = Rm;
  1655. let Inst{15-12} = Rd;
  1656. let Inst{19-16} = Rn;
  1657. }
  1658. def rsi : AsI1<opcod, (outs GPR:$Rd),
  1659. (ins GPR:$Rn, so_reg_imm:$shift),
  1660. DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
  1661. [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_reg_imm:$shift, CPSR))]>,
  1662. Requires<[IsARM]>,
  1663. Sched<[WriteALUsi, ReadALU]> {
  1664. bits<4> Rd;
  1665. bits<4> Rn;
  1666. bits<12> shift;
  1667. let Inst{25} = 0;
  1668. let Inst{19-16} = Rn;
  1669. let Inst{15-12} = Rd;
  1670. let Inst{11-5} = shift{11-5};
  1671. let Inst{4} = 0;
  1672. let Inst{3-0} = shift{3-0};
  1673. }
  1674. def rsr : AsI1<opcod, (outs GPRnopc:$Rd),
  1675. (ins GPRnopc:$Rn, so_reg_reg:$shift),
  1676. DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
  1677. [(set GPRnopc:$Rd, CPSR,
  1678. (opnode GPRnopc:$Rn, so_reg_reg:$shift, CPSR))]>,
  1679. Requires<[IsARM]>,
  1680. Sched<[WriteALUsr, ReadALUsr]> {
  1681. bits<4> Rd;
  1682. bits<4> Rn;
  1683. bits<12> shift;
  1684. let Inst{25} = 0;
  1685. let Inst{19-16} = Rn;
  1686. let Inst{15-12} = Rd;
  1687. let Inst{11-8} = shift{11-8};
  1688. let Inst{7} = 0;
  1689. let Inst{6-5} = shift{6-5};
  1690. let Inst{4} = 1;
  1691. let Inst{3-0} = shift{3-0};
  1692. }
  1693. }
  1694. }
  1695. /// AI1_rsc_irs - Define instructions and patterns for rsc
  1696. let TwoOperandAliasConstraint = "$Rn = $Rd" in
  1697. multiclass AI1_rsc_irs<bits<4> opcod, string opc, SDNode opnode> {
  1698. let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in {
  1699. def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm),
  1700. DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
  1701. [(set GPR:$Rd, CPSR, (opnode mod_imm:$imm, GPR:$Rn, CPSR))]>,
  1702. Requires<[IsARM]>,
  1703. Sched<[WriteALU, ReadALU]> {
  1704. bits<4> Rd;
  1705. bits<4> Rn;
  1706. bits<12> imm;
  1707. let Inst{25} = 1;
  1708. let Inst{15-12} = Rd;
  1709. let Inst{19-16} = Rn;
  1710. let Inst{11-0} = imm;
  1711. }
  1712. def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
  1713. DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm",
  1714. [/* pattern left blank */]>,
  1715. Sched<[WriteALU, ReadALU, ReadALU]> {
  1716. bits<4> Rd;
  1717. bits<4> Rn;
  1718. bits<4> Rm;
  1719. let Inst{11-4} = 0b00000000;
  1720. let Inst{25} = 0;
  1721. let Inst{3-0} = Rm;
  1722. let Inst{15-12} = Rd;
  1723. let Inst{19-16} = Rn;
  1724. }
  1725. def rsi : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
  1726. DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
  1727. [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift, GPR:$Rn, CPSR))]>,
  1728. Requires<[IsARM]>,
  1729. Sched<[WriteALUsi, ReadALU]> {
  1730. bits<4> Rd;
  1731. bits<4> Rn;
  1732. bits<12> shift;
  1733. let Inst{25} = 0;
  1734. let Inst{19-16} = Rn;
  1735. let Inst{15-12} = Rd;
  1736. let Inst{11-5} = shift{11-5};
  1737. let Inst{4} = 0;
  1738. let Inst{3-0} = shift{3-0};
  1739. }
  1740. def rsr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift),
  1741. DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
  1742. [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift, GPR:$Rn, CPSR))]>,
  1743. Requires<[IsARM]>,
  1744. Sched<[WriteALUsr, ReadALUsr]> {
  1745. bits<4> Rd;
  1746. bits<4> Rn;
  1747. bits<12> shift;
  1748. let Inst{25} = 0;
  1749. let Inst{19-16} = Rn;
  1750. let Inst{15-12} = Rd;
  1751. let Inst{11-8} = shift{11-8};
  1752. let Inst{7} = 0;
  1753. let Inst{6-5} = shift{6-5};
  1754. let Inst{4} = 1;
  1755. let Inst{3-0} = shift{3-0};
  1756. }
  1757. }
  1758. }
  1759. let canFoldAsLoad = 1, isReMaterializable = 1 in {
  1760. multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii,
  1761. InstrItinClass iir, PatFrag opnode> {
  1762. // Note: We use the complex addrmode_imm12 rather than just an input
  1763. // GPR and a constrained immediate so that we can use this to match
  1764. // frame index references and avoid matching constant pool references.
  1765. def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
  1766. AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
  1767. [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
  1768. bits<4> Rt;
  1769. bits<17> addr;
  1770. let Inst{23} = addr{12}; // U (add = ('U' == 1))
  1771. let Inst{19-16} = addr{16-13}; // Rn
  1772. let Inst{15-12} = Rt;
  1773. let Inst{11-0} = addr{11-0}; // imm12
  1774. }
  1775. def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
  1776. AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
  1777. [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
  1778. bits<4> Rt;
  1779. bits<17> shift;
  1780. let shift{4} = 0; // Inst{4} = 0
  1781. let Inst{23} = shift{12}; // U (add = ('U' == 1))
  1782. let Inst{19-16} = shift{16-13}; // Rn
  1783. let Inst{15-12} = Rt;
  1784. let Inst{11-0} = shift{11-0};
  1785. }
  1786. }
  1787. }
  1788. let canFoldAsLoad = 1, isReMaterializable = 1 in {
  1789. multiclass AI_ldr1nopc<bit isByte, string opc, InstrItinClass iii,
  1790. InstrItinClass iir, PatFrag opnode> {
  1791. // Note: We use the complex addrmode_imm12 rather than just an input
  1792. // GPR and a constrained immediate so that we can use this to match
  1793. // frame index references and avoid matching constant pool references.
  1794. def i12: AI2ldst<0b010, 1, isByte, (outs GPRnopc:$Rt),
  1795. (ins addrmode_imm12:$addr),
  1796. AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
  1797. [(set GPRnopc:$Rt, (opnode addrmode_imm12:$addr))]> {
  1798. bits<4> Rt;
  1799. bits<17> addr;
  1800. let Inst{23} = addr{12}; // U (add = ('U' == 1))
  1801. let Inst{19-16} = addr{16-13}; // Rn
  1802. let Inst{15-12} = Rt;
  1803. let Inst{11-0} = addr{11-0}; // imm12
  1804. }
  1805. def rs : AI2ldst<0b011, 1, isByte, (outs GPRnopc:$Rt),
  1806. (ins ldst_so_reg:$shift),
  1807. AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
  1808. [(set GPRnopc:$Rt, (opnode ldst_so_reg:$shift))]> {
  1809. bits<4> Rt;
  1810. bits<17> shift;
  1811. let shift{4} = 0; // Inst{4} = 0
  1812. let Inst{23} = shift{12}; // U (add = ('U' == 1))
  1813. let Inst{19-16} = shift{16-13}; // Rn
  1814. let Inst{15-12} = Rt;
  1815. let Inst{11-0} = shift{11-0};
  1816. }
  1817. }
  1818. }
  1819. multiclass AI_str1<bit isByte, string opc, InstrItinClass iii,
  1820. InstrItinClass iir, PatFrag opnode> {
  1821. // Note: We use the complex addrmode_imm12 rather than just an input
  1822. // GPR and a constrained immediate so that we can use this to match
  1823. // frame index references and avoid matching constant pool references.
  1824. def i12 : AI2ldst<0b010, 0, isByte, (outs),
  1825. (ins GPR:$Rt, addrmode_imm12:$addr),
  1826. AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
  1827. [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
  1828. bits<4> Rt;
  1829. bits<17> addr;
  1830. let Inst{23} = addr{12}; // U (add = ('U' == 1))
  1831. let Inst{19-16} = addr{16-13}; // Rn
  1832. let Inst{15-12} = Rt;
  1833. let Inst{11-0} = addr{11-0}; // imm12
  1834. }
  1835. def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
  1836. AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
  1837. [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
  1838. bits<4> Rt;
  1839. bits<17> shift;
  1840. let shift{4} = 0; // Inst{4} = 0
  1841. let Inst{23} = shift{12}; // U (add = ('U' == 1))
  1842. let Inst{19-16} = shift{16-13}; // Rn
  1843. let Inst{15-12} = Rt;
  1844. let Inst{11-0} = shift{11-0};
  1845. }
  1846. }
  1847. multiclass AI_str1nopc<bit isByte, string opc, InstrItinClass iii,
  1848. InstrItinClass iir, PatFrag opnode> {
  1849. // Note: We use the complex addrmode_imm12 rather than just an input
  1850. // GPR and a constrained immediate so that we can use this to match
  1851. // frame index references and avoid matching constant pool references.
  1852. def i12 : AI2ldst<0b010, 0, isByte, (outs),
  1853. (ins GPRnopc:$Rt, addrmode_imm12:$addr),
  1854. AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
  1855. [(opnode GPRnopc:$Rt, addrmode_imm12:$addr)]> {
  1856. bits<4> Rt;
  1857. bits<17> addr;
  1858. let Inst{23} = addr{12}; // U (add = ('U' == 1))
  1859. let Inst{19-16} = addr{16-13}; // Rn
  1860. let Inst{15-12} = Rt;
  1861. let Inst{11-0} = addr{11-0}; // imm12
  1862. }
  1863. def rs : AI2ldst<0b011, 0, isByte, (outs),
  1864. (ins GPRnopc:$Rt, ldst_so_reg:$shift),
  1865. AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
  1866. [(opnode GPRnopc:$Rt, ldst_so_reg:$shift)]> {
  1867. bits<4> Rt;
  1868. bits<17> shift;
  1869. let shift{4} = 0; // Inst{4} = 0
  1870. let Inst{23} = shift{12}; // U (add = ('U' == 1))
  1871. let Inst{19-16} = shift{16-13}; // Rn
  1872. let Inst{15-12} = Rt;
  1873. let Inst{11-0} = shift{11-0};
  1874. }
  1875. }
  1876. //===----------------------------------------------------------------------===//
  1877. // Instructions
  1878. //===----------------------------------------------------------------------===//
  1879. //===----------------------------------------------------------------------===//
  1880. // Miscellaneous Instructions.
  1881. //
  1882. /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
  1883. /// the function. The first operand is the ID# for this instruction, the second
  1884. /// is the index into the MachineConstantPool that this is, the third is the
  1885. /// size in bytes of this constant pool entry.
  1886. let hasSideEffects = 0, isNotDuplicable = 1, hasNoSchedulingInfo = 1 in
  1887. def CONSTPOOL_ENTRY :
  1888. PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
  1889. i32imm:$size), NoItinerary, []>;
  1890. /// A jumptable consisting of direct 32-bit addresses of the destination basic
  1891. /// blocks (either absolute, or relative to the start of the jump-table in PIC
  1892. /// mode). Used mostly in ARM and Thumb-1 modes.
  1893. def JUMPTABLE_ADDRS :
  1894. PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
  1895. i32imm:$size), NoItinerary, []>;
  1896. /// A jumptable consisting of 32-bit jump instructions. Used for Thumb-2 tables
  1897. /// that cannot be optimised to use TBB or TBH.
  1898. def JUMPTABLE_INSTS :
  1899. PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
  1900. i32imm:$size), NoItinerary, []>;
  1901. /// A jumptable consisting of 8-bit unsigned integers representing offsets from
  1902. /// a TBB instruction.
  1903. def JUMPTABLE_TBB :
  1904. PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
  1905. i32imm:$size), NoItinerary, []>;
  1906. /// A jumptable consisting of 16-bit unsigned integers representing offsets from
  1907. /// a TBH instruction.
  1908. def JUMPTABLE_TBH :
  1909. PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
  1910. i32imm:$size), NoItinerary, []>;
  1911. // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
  1912. // from removing one half of the matched pairs. That breaks PEI, which assumes
  1913. // these will always be in pairs, and asserts if it finds otherwise. Better way?
  1914. let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
  1915. def ADJCALLSTACKUP :
  1916. PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
  1917. [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
  1918. def ADJCALLSTACKDOWN :
  1919. PseudoInst<(outs), (ins i32imm:$amt, i32imm:$amt2, pred:$p), NoItinerary,
  1920. [(ARMcallseq_start timm:$amt, timm:$amt2)]>;
  1921. }
  1922. def HINT : AI<(outs), (ins imm0_239:$imm), MiscFrm, NoItinerary,
  1923. "hint", "\t$imm", [(int_arm_hint imm0_239:$imm)]>,
  1924. Requires<[IsARM, HasV6]> {
  1925. bits<8> imm;
  1926. let Inst{27-8} = 0b00110010000011110000;
  1927. let Inst{7-0} = imm;
  1928. let DecoderMethod = "DecodeHINTInstruction";
  1929. }
  1930. def : InstAlias<"nop$p", (HINT 0, pred:$p)>, Requires<[IsARM, HasV6K]>;
  1931. def : InstAlias<"yield$p", (HINT 1, pred:$p)>, Requires<[IsARM, HasV6K]>;
  1932. def : InstAlias<"wfe$p", (HINT 2, pred:$p)>, Requires<[IsARM, HasV6K]>;
  1933. def : InstAlias<"wfi$p", (HINT 3, pred:$p)>, Requires<[IsARM, HasV6K]>;
  1934. def : InstAlias<"sev$p", (HINT 4, pred:$p)>, Requires<[IsARM, HasV6K]>;
  1935. def : InstAlias<"sevl$p", (HINT 5, pred:$p)>, Requires<[IsARM, HasV8]>;
  1936. def : InstAlias<"esb$p", (HINT 16, pred:$p)>, Requires<[IsARM, HasRAS]>;
  1937. def : InstAlias<"csdb$p", (HINT 20, pred:$p)>, Requires<[IsARM, HasV6K]>;
  1938. // Clear BHB instruction
  1939. def : InstAlias<"clrbhb$p", (HINT 22, pred:$p), 0>, Requires<[IsARM, HasV8]>;
  1940. def : InstAlias<"clrbhb$p", (HINT 22, pred:$p), 1>, Requires<[IsARM, HasV8, HasCLRBHB]>;
  1941. def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel",
  1942. "\t$Rd, $Rn, $Rm",
  1943. [(set GPR:$Rd, (int_arm_sel GPR:$Rn, GPR:$Rm))]>,
  1944. Requires<[IsARM, HasV6]> {
  1945. bits<4> Rd;
  1946. bits<4> Rn;
  1947. bits<4> Rm;
  1948. let Inst{3-0} = Rm;
  1949. let Inst{15-12} = Rd;
  1950. let Inst{19-16} = Rn;
  1951. let Inst{27-20} = 0b01101000;
  1952. let Inst{7-4} = 0b1011;
  1953. let Inst{11-8} = 0b1111;
  1954. let Unpredictable{11-8} = 0b1111;
  1955. }
  1956. // The 16-bit operand $val can be used by a debugger to store more information
  1957. // about the breakpoint.
  1958. def BKPT : AInoP<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary,
  1959. "bkpt", "\t$val", []>, Requires<[IsARM]> {
  1960. bits<16> val;
  1961. let Inst{3-0} = val{3-0};
  1962. let Inst{19-8} = val{15-4};
  1963. let Inst{27-20} = 0b00010010;
  1964. let Inst{31-28} = 0xe; // AL
  1965. let Inst{7-4} = 0b0111;
  1966. }
  1967. // default immediate for breakpoint mnemonic
  1968. def : InstAlias<"bkpt", (BKPT 0), 0>, Requires<[IsARM]>;
  1969. def HLT : AInoP<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary,
  1970. "hlt", "\t$val", []>, Requires<[IsARM, HasV8]> {
  1971. bits<16> val;
  1972. let Inst{3-0} = val{3-0};
  1973. let Inst{19-8} = val{15-4};
  1974. let Inst{27-20} = 0b00010000;
  1975. let Inst{31-28} = 0xe; // AL
  1976. let Inst{7-4} = 0b0111;
  1977. }
  1978. // Change Processor State
  1979. // FIXME: We should use InstAlias to handle the optional operands.
  1980. class CPS<dag iops, string asm_ops>
  1981. : AXI<(outs), iops, MiscFrm, NoItinerary, !strconcat("cps", asm_ops),
  1982. []>, Requires<[IsARM]> {
  1983. bits<2> imod;
  1984. bits<3> iflags;
  1985. bits<5> mode;
  1986. bit M;
  1987. let Inst{31-28} = 0b1111;
  1988. let Inst{27-20} = 0b00010000;
  1989. let Inst{19-18} = imod;
  1990. let Inst{17} = M; // Enabled if mode is set;
  1991. let Inst{16-9} = 0b00000000;
  1992. let Inst{8-6} = iflags;
  1993. let Inst{5} = 0;
  1994. let Inst{4-0} = mode;
  1995. }
  1996. let DecoderMethod = "DecodeCPSInstruction" in {
  1997. let M = 1 in
  1998. def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, imm0_31:$mode),
  1999. "$imod\t$iflags, $mode">;
  2000. let mode = 0, M = 0 in
  2001. def CPS2p : CPS<(ins imod_op:$imod, iflags_op:$iflags), "$imod\t$iflags">;
  2002. let imod = 0, iflags = 0, M = 1 in
  2003. def CPS1p : CPS<(ins imm0_31:$mode), "\t$mode">;
  2004. }
  2005. // Preload signals the memory system of possible future data/instruction access.
  2006. multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
  2007. def i12 : AXIM<(outs), (ins addrmode_imm12:$addr), AddrMode_i12, MiscFrm,
  2008. IIC_Preload, !strconcat(opc, "\t$addr"),
  2009. [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]>,
  2010. Sched<[WritePreLd]> {
  2011. bits<4> Rt;
  2012. bits<17> addr;
  2013. let Inst{31-26} = 0b111101;
  2014. let Inst{25} = 0; // 0 for immediate form
  2015. let Inst{24} = data;
  2016. let Inst{23} = addr{12}; // U (add = ('U' == 1))
  2017. let Inst{22} = read;
  2018. let Inst{21-20} = 0b01;
  2019. let Inst{19-16} = addr{16-13}; // Rn
  2020. let Inst{15-12} = 0b1111;
  2021. let Inst{11-0} = addr{11-0}; // imm12
  2022. }
  2023. def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
  2024. !strconcat(opc, "\t$shift"),
  2025. [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]>,
  2026. Sched<[WritePreLd]> {
  2027. bits<17> shift;
  2028. let Inst{31-26} = 0b111101;
  2029. let Inst{25} = 1; // 1 for register form
  2030. let Inst{24} = data;
  2031. let Inst{23} = shift{12}; // U (add = ('U' == 1))
  2032. let Inst{22} = read;
  2033. let Inst{21-20} = 0b01;
  2034. let Inst{19-16} = shift{16-13}; // Rn
  2035. let Inst{15-12} = 0b1111;
  2036. let Inst{11-0} = shift{11-0};
  2037. let Inst{4} = 0;
  2038. }
  2039. }
  2040. defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
  2041. defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
  2042. defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
  2043. def SETEND : AXI<(outs), (ins setend_op:$end), MiscFrm, NoItinerary,
  2044. "setend\t$end", []>, Requires<[IsARM]>, Deprecated<HasV8Ops> {
  2045. bits<1> end;
  2046. let Inst{31-10} = 0b1111000100000001000000;
  2047. let Inst{9} = end;
  2048. let Inst{8-0} = 0;
  2049. }
  2050. def DBG : AI<(outs), (ins imm0_15:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
  2051. [(int_arm_dbg imm0_15:$opt)]>, Requires<[IsARM, HasV7]> {
  2052. bits<4> opt;
  2053. let Inst{27-4} = 0b001100100000111100001111;
  2054. let Inst{3-0} = opt;
  2055. }
  2056. // A8.8.247 UDF - Undefined (Encoding A1)
  2057. def UDF : AInoP<(outs), (ins imm0_65535:$imm16), MiscFrm, NoItinerary,
  2058. "udf", "\t$imm16", [(int_arm_undefined imm0_65535:$imm16)]> {
  2059. bits<16> imm16;
  2060. let Inst{31-28} = 0b1110; // AL
  2061. let Inst{27-25} = 0b011;
  2062. let Inst{24-20} = 0b11111;
  2063. let Inst{19-8} = imm16{15-4};
  2064. let Inst{7-4} = 0b1111;
  2065. let Inst{3-0} = imm16{3-0};
  2066. }
  2067. /*
  2068. * A5.4 Permanently UNDEFINED instructions.
  2069. *
  2070. * For most targets use UDF #65006, for which the OS will generate SIGTRAP.
  2071. * Other UDF encodings generate SIGILL.
  2072. *
  2073. * NaCl's OS instead chooses an ARM UDF encoding that's also a UDF in Thumb.
  2074. * Encoding A1:
  2075. * 1110 0111 1111 iiii iiii iiii 1111 iiii
  2076. * Encoding T1:
  2077. * 1101 1110 iiii iiii
  2078. * It uses the following encoding:
  2079. * 1110 0111 1111 1110 1101 1110 1111 0000
  2080. * - In ARM: UDF #60896;
  2081. * - In Thumb: UDF #254 followed by a branch-to-self.
  2082. */
  2083. let isBarrier = 1, isTerminator = 1 in
  2084. def TRAPNaCl : AXI<(outs), (ins), MiscFrm, NoItinerary,
  2085. "trap", [(trap)]>,
  2086. Requires<[IsARM,UseNaClTrap]> {
  2087. let Inst = 0xe7fedef0;
  2088. }
  2089. let isBarrier = 1, isTerminator = 1 in
  2090. def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
  2091. "trap", [(trap)]>,
  2092. Requires<[IsARM,DontUseNaClTrap]> {
  2093. let Inst = 0xe7ffdefe;
  2094. }
  2095. def : Pat<(debugtrap), (BKPT 0)>, Requires<[IsARM, HasV5T]>;
  2096. def : Pat<(debugtrap), (UDF 254)>, Requires<[IsARM, NoV5T]>;
  2097. // Address computation and loads and stores in PIC mode.
  2098. let isNotDuplicable = 1 in {
  2099. def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
  2100. 4, IIC_iALUr,
  2101. [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>,
  2102. Sched<[WriteALU, ReadALU]>;
  2103. let AddedComplexity = 10 in {
  2104. def PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
  2105. 4, IIC_iLoad_r,
  2106. [(set GPR:$dst, (load addrmodepc:$addr))]>;
  2107. def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
  2108. 4, IIC_iLoad_bh_r,
  2109. [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>;
  2110. def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
  2111. 4, IIC_iLoad_bh_r,
  2112. [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>;
  2113. def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
  2114. 4, IIC_iLoad_bh_r,
  2115. [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>;
  2116. def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p),
  2117. 4, IIC_iLoad_bh_r,
  2118. [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>;
  2119. }
  2120. let AddedComplexity = 10 in {
  2121. def PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
  2122. 4, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>;
  2123. def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
  2124. 4, IIC_iStore_bh_r, [(truncstorei16 GPR:$src,
  2125. addrmodepc:$addr)]>;
  2126. def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
  2127. 4, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
  2128. }
  2129. } // isNotDuplicable = 1
  2130. // LEApcrel - Load a pc-relative address into a register without offending the
  2131. // assembler.
  2132. let hasSideEffects = 0, isReMaterializable = 1 in
  2133. // The 'adr' mnemonic encodes differently if the label is before or after
  2134. // the instruction. The {24-21} opcode bits are set by the fixup, as we don't
  2135. // know until then which form of the instruction will be used.
  2136. def ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label),
  2137. MiscFrm, IIC_iALUi, "adr", "\t$Rd, $label", []>,
  2138. Sched<[WriteALU, ReadALU]> {
  2139. bits<4> Rd;
  2140. bits<14> label;
  2141. let Inst{27-25} = 0b001;
  2142. let Inst{24} = 0;
  2143. let Inst{23-22} = label{13-12};
  2144. let Inst{21} = 0;
  2145. let Inst{20} = 0;
  2146. let Inst{19-16} = 0b1111;
  2147. let Inst{15-12} = Rd;
  2148. let Inst{11-0} = label{11-0};
  2149. }
  2150. let hasSideEffects = 1 in {
  2151. def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p),
  2152. 4, IIC_iALUi, []>, Sched<[WriteALU, ReadALU]>;
  2153. def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
  2154. (ins i32imm:$label, pred:$p),
  2155. 4, IIC_iALUi, []>, Sched<[WriteALU, ReadALU]>;
  2156. }
  2157. //===----------------------------------------------------------------------===//
  2158. // Control Flow Instructions.
  2159. //
  2160. let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
  2161. // ARMV4T and above
  2162. def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
  2163. "bx", "\tlr", [(ARMretflag)]>,
  2164. Requires<[IsARM, HasV4T]>, Sched<[WriteBr]> {
  2165. let Inst{27-0} = 0b0001001011111111111100011110;
  2166. }
  2167. // ARMV4 only
  2168. def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
  2169. "mov", "\tpc, lr", [(ARMretflag)]>,
  2170. Requires<[IsARM, NoV4T]>, Sched<[WriteBr]> {
  2171. let Inst{27-0} = 0b0001101000001111000000001110;
  2172. }
  2173. // Exception return: N.b. doesn't set CPSR as far as we're concerned (it sets
  2174. // the user-space one).
  2175. def SUBS_PC_LR : ARMPseudoInst<(outs), (ins i32imm:$offset, pred:$p),
  2176. 4, IIC_Br,
  2177. [(ARMintretflag imm:$offset)]>;
  2178. }
  2179. // Indirect branches
  2180. let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
  2181. // ARMV4T and above
  2182. def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
  2183. [(brind GPR:$dst)]>,
  2184. Requires<[IsARM, HasV4T]>, Sched<[WriteBr]> {
  2185. bits<4> dst;
  2186. let Inst{31-4} = 0b1110000100101111111111110001;
  2187. let Inst{3-0} = dst;
  2188. }
  2189. def BX_pred : AI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br,
  2190. "bx", "\t$dst", [/* pattern left blank */]>,
  2191. Requires<[IsARM, HasV4T]>, Sched<[WriteBr]> {
  2192. bits<4> dst;
  2193. let Inst{27-4} = 0b000100101111111111110001;
  2194. let Inst{3-0} = dst;
  2195. }
  2196. }
  2197. // SP is marked as a use to prevent stack-pointer assignments that appear
  2198. // immediately before calls from potentially appearing dead.
  2199. let isCall = 1,
  2200. // FIXME: Do we really need a non-predicated version? If so, it should
  2201. // at least be a pseudo instruction expanding to the predicated version
  2202. // at MC lowering time.
  2203. Defs = [LR], Uses = [SP] in {
  2204. def BL : ABXI<0b1011, (outs), (ins arm_bl_target:$func),
  2205. IIC_Br, "bl\t$func",
  2206. [(ARMcall tglobaladdr:$func)]>,
  2207. Requires<[IsARM]>, Sched<[WriteBrL]> {
  2208. let Inst{31-28} = 0b1110;
  2209. bits<24> func;
  2210. let Inst{23-0} = func;
  2211. let DecoderMethod = "DecodeBranchImmInstruction";
  2212. }
  2213. def BL_pred : ABI<0b1011, (outs), (ins arm_bl_target:$func),
  2214. IIC_Br, "bl", "\t$func",
  2215. [(ARMcall_pred tglobaladdr:$func)]>,
  2216. Requires<[IsARM]>, Sched<[WriteBrL]> {
  2217. bits<24> func;
  2218. let Inst{23-0} = func;
  2219. let DecoderMethod = "DecodeBranchImmInstruction";
  2220. }
  2221. // ARMv5T and above
  2222. def BLX : AXI<(outs), (ins GPR:$func), BrMiscFrm, IIC_Br, "blx\t$func", []>,
  2223. Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]> {
  2224. bits<4> func;
  2225. let Inst{31-4} = 0b1110000100101111111111110011;
  2226. let Inst{3-0} = func;
  2227. }
  2228. def BLX_noip : ARMPseudoExpand<(outs), (ins GPRnoip:$func),
  2229. 4, IIC_Br, [], (BLX GPR:$func)>,
  2230. Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]>;
  2231. def BLX_pred : AI<(outs), (ins GPR:$func), BrMiscFrm,
  2232. IIC_Br, "blx", "\t$func", []>,
  2233. Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]> {
  2234. bits<4> func;
  2235. let Inst{27-4} = 0b000100101111111111110011;
  2236. let Inst{3-0} = func;
  2237. }
  2238. def BLX_pred_noip : ARMPseudoExpand<(outs), (ins GPRnoip:$func),
  2239. 4, IIC_Br, [],
  2240. (BLX_pred GPR:$func, (ops 14, zero_reg))>,
  2241. Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]>;
  2242. // ARMv4T
  2243. // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
  2244. def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func),
  2245. 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
  2246. Requires<[IsARM, HasV4T]>, Sched<[WriteBr]>;
  2247. // ARMv4
  2248. def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func),
  2249. 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>,
  2250. Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>;
  2251. // mov lr, pc; b if callee is marked noreturn to avoid confusing the
  2252. // return stack predictor.
  2253. def BMOVPCB_CALL : ARMPseudoInst<(outs), (ins arm_bl_target:$func),
  2254. 8, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>,
  2255. Requires<[IsARM]>, Sched<[WriteBr]>;
  2256. // push lr before the call
  2257. def BL_PUSHLR : ARMPseudoInst<(outs), (ins GPRlr:$ra, arm_bl_target:$func),
  2258. 4, IIC_Br,
  2259. []>,
  2260. Requires<[IsARM]>, Sched<[WriteBr]>;
  2261. }
  2262. def : ARMPat<(ARMcall GPR:$func), (BLX $func)>,
  2263. Requires<[IsARM, HasV5T, NoSLSBLRMitigation]>;
  2264. def : ARMPat<(ARMcall GPRnoip:$func), (BLX_noip $func)>,
  2265. Requires<[IsARM, HasV5T, SLSBLRMitigation]>;
  2266. def : ARMPat<(ARMcall_pred GPR:$func), (BLX_pred $func)>,
  2267. Requires<[IsARM, HasV5T, NoSLSBLRMitigation]>;
  2268. def : ARMPat<(ARMcall_pred GPRnoip:$func), (BLX_pred_noip $func)>,
  2269. Requires<[IsARM, HasV5T, SLSBLRMitigation]>;
  2270. let isBranch = 1, isTerminator = 1 in {
  2271. // FIXME: should be able to write a pattern for ARMBrcond, but can't use
  2272. // a two-value operand where a dag node expects two operands. :(
  2273. def Bcc : ABI<0b1010, (outs), (ins arm_br_target:$target),
  2274. IIC_Br, "b", "\t$target",
  2275. [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>,
  2276. Sched<[WriteBr]> {
  2277. bits<24> target;
  2278. let Inst{23-0} = target;
  2279. let DecoderMethod = "DecodeBranchImmInstruction";
  2280. }
  2281. let isBarrier = 1 in {
  2282. // B is "predicable" since it's just a Bcc with an 'always' condition.
  2283. let isPredicable = 1 in
  2284. // FIXME: We shouldn't need this pseudo at all. Just using Bcc directly
  2285. // should be sufficient.
  2286. // FIXME: Is B really a Barrier? That doesn't seem right.
  2287. def B : ARMPseudoExpand<(outs), (ins arm_br_target:$target), 4, IIC_Br,
  2288. [(br bb:$target)], (Bcc arm_br_target:$target,
  2289. (ops 14, zero_reg))>,
  2290. Sched<[WriteBr]>;
  2291. let Size = 4, isNotDuplicable = 1, isIndirectBranch = 1 in {
  2292. def BR_JTr : ARMPseudoInst<(outs),
  2293. (ins GPR:$target, i32imm:$jt),
  2294. 0, IIC_Br,
  2295. [(ARMbrjt GPR:$target, tjumptable:$jt)]>,
  2296. Sched<[WriteBr]>;
  2297. def BR_JTm_i12 : ARMPseudoInst<(outs),
  2298. (ins addrmode_imm12:$target, i32imm:$jt),
  2299. 0, IIC_Br,
  2300. [(ARMbrjt (i32 (load addrmode_imm12:$target)),
  2301. tjumptable:$jt)]>, Sched<[WriteBrTbl]>;
  2302. def BR_JTm_rs : ARMPseudoInst<(outs),
  2303. (ins ldst_so_reg:$target, i32imm:$jt),
  2304. 0, IIC_Br,
  2305. [(ARMbrjt (i32 (load ldst_so_reg:$target)),
  2306. tjumptable:$jt)]>, Sched<[WriteBrTbl]>;
  2307. def BR_JTadd : ARMPseudoInst<(outs),
  2308. (ins GPR:$target, GPR:$idx, i32imm:$jt),
  2309. 0, IIC_Br,
  2310. [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt)]>,
  2311. Sched<[WriteBrTbl]>;
  2312. } // isNotDuplicable = 1, isIndirectBranch = 1
  2313. } // isBarrier = 1
  2314. }
  2315. // BLX (immediate)
  2316. def BLXi : AXI<(outs), (ins arm_blx_target:$target), BrMiscFrm, NoItinerary,
  2317. "blx\t$target", []>,
  2318. Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]> {
  2319. let Inst{31-25} = 0b1111101;
  2320. bits<25> target;
  2321. let Inst{23-0} = target{24-1};
  2322. let Inst{24} = target{0};
  2323. let isCall = 1;
  2324. }
  2325. // Branch and Exchange Jazelle
  2326. def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
  2327. [/* pattern left blank */]>, Sched<[WriteBr]> {
  2328. bits<4> func;
  2329. let Inst{23-20} = 0b0010;
  2330. let Inst{19-8} = 0xfff;
  2331. let Inst{7-4} = 0b0010;
  2332. let Inst{3-0} = func;
  2333. let isBranch = 1;
  2334. let isIndirectBranch = 1;
  2335. }
  2336. // Tail calls.
  2337. let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in {
  2338. def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, i32imm:$SPDiff), IIC_Br, []>,
  2339. Sched<[WriteBr]>;
  2340. def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, i32imm:$SPDiff), IIC_Br, []>,
  2341. Sched<[WriteBr]>;
  2342. def TAILJMPd : ARMPseudoExpand<(outs), (ins arm_br_target:$dst),
  2343. 4, IIC_Br, [],
  2344. (Bcc arm_br_target:$dst, (ops 14, zero_reg))>,
  2345. Requires<[IsARM]>, Sched<[WriteBr]>;
  2346. def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst),
  2347. 4, IIC_Br, [],
  2348. (BX GPR:$dst)>, Sched<[WriteBr]>,
  2349. Requires<[IsARM, HasV4T]>;
  2350. }
  2351. // Secure Monitor Call is a system instruction.
  2352. def SMC : ABI<0b0001, (outs), (ins imm0_15:$opt), NoItinerary, "smc", "\t$opt",
  2353. []>, Requires<[IsARM, HasTrustZone]> {
  2354. bits<4> opt;
  2355. let Inst{23-4} = 0b01100000000000000111;
  2356. let Inst{3-0} = opt;
  2357. }
  2358. def : MnemonicAlias<"smi", "smc">;
  2359. // Supervisor Call (Software Interrupt)
  2360. let isCall = 1, Uses = [SP] in {
  2361. def SVC : ABI<0b1111, (outs), (ins imm24b:$svc), IIC_Br, "svc", "\t$svc", []>,
  2362. Sched<[WriteBr]> {
  2363. bits<24> svc;
  2364. let Inst{23-0} = svc;
  2365. }
  2366. }
  2367. // Store Return State
  2368. class SRSI<bit wb, string asm>
  2369. : XI<(outs), (ins imm0_31:$mode), AddrModeNone, 4, IndexModeNone, BrFrm,
  2370. NoItinerary, asm, "", []> {
  2371. bits<5> mode;
  2372. let Inst{31-28} = 0b1111;
  2373. let Inst{27-25} = 0b100;
  2374. let Inst{22} = 1;
  2375. let Inst{21} = wb;
  2376. let Inst{20} = 0;
  2377. let Inst{19-16} = 0b1101; // SP
  2378. let Inst{15-5} = 0b00000101000;
  2379. let Inst{4-0} = mode;
  2380. }
  2381. def SRSDA : SRSI<0, "srsda\tsp, $mode"> {
  2382. let Inst{24-23} = 0;
  2383. }
  2384. def SRSDA_UPD : SRSI<1, "srsda\tsp!, $mode"> {
  2385. let Inst{24-23} = 0;
  2386. }
  2387. def SRSDB : SRSI<0, "srsdb\tsp, $mode"> {
  2388. let Inst{24-23} = 0b10;
  2389. }
  2390. def SRSDB_UPD : SRSI<1, "srsdb\tsp!, $mode"> {
  2391. let Inst{24-23} = 0b10;
  2392. }
  2393. def SRSIA : SRSI<0, "srsia\tsp, $mode"> {
  2394. let Inst{24-23} = 0b01;
  2395. }
  2396. def SRSIA_UPD : SRSI<1, "srsia\tsp!, $mode"> {
  2397. let Inst{24-23} = 0b01;
  2398. }
  2399. def SRSIB : SRSI<0, "srsib\tsp, $mode"> {
  2400. let Inst{24-23} = 0b11;
  2401. }
  2402. def SRSIB_UPD : SRSI<1, "srsib\tsp!, $mode"> {
  2403. let Inst{24-23} = 0b11;
  2404. }
  2405. def : ARMInstAlias<"srsda $mode", (SRSDA imm0_31:$mode)>;
  2406. def : ARMInstAlias<"srsda $mode!", (SRSDA_UPD imm0_31:$mode)>;
  2407. def : ARMInstAlias<"srsdb $mode", (SRSDB imm0_31:$mode)>;
  2408. def : ARMInstAlias<"srsdb $mode!", (SRSDB_UPD imm0_31:$mode)>;
  2409. def : ARMInstAlias<"srsia $mode", (SRSIA imm0_31:$mode)>;
  2410. def : ARMInstAlias<"srsia $mode!", (SRSIA_UPD imm0_31:$mode)>;
  2411. def : ARMInstAlias<"srsib $mode", (SRSIB imm0_31:$mode)>;
  2412. def : ARMInstAlias<"srsib $mode!", (SRSIB_UPD imm0_31:$mode)>;
  2413. // Return From Exception
  2414. class RFEI<bit wb, string asm>
  2415. : XI<(outs), (ins GPR:$Rn), AddrModeNone, 4, IndexModeNone, BrFrm,
  2416. NoItinerary, asm, "", []> {
  2417. bits<4> Rn;
  2418. let Inst{31-28} = 0b1111;
  2419. let Inst{27-25} = 0b100;
  2420. let Inst{22} = 0;
  2421. let Inst{21} = wb;
  2422. let Inst{20} = 1;
  2423. let Inst{19-16} = Rn;
  2424. let Inst{15-0} = 0xa00;
  2425. }
  2426. def RFEDA : RFEI<0, "rfeda\t$Rn"> {
  2427. let Inst{24-23} = 0;
  2428. }
  2429. def RFEDA_UPD : RFEI<1, "rfeda\t$Rn!"> {
  2430. let Inst{24-23} = 0;
  2431. }
  2432. def RFEDB : RFEI<0, "rfedb\t$Rn"> {
  2433. let Inst{24-23} = 0b10;
  2434. }
  2435. def RFEDB_UPD : RFEI<1, "rfedb\t$Rn!"> {
  2436. let Inst{24-23} = 0b10;
  2437. }
  2438. def RFEIA : RFEI<0, "rfeia\t$Rn"> {
  2439. let Inst{24-23} = 0b01;
  2440. }
  2441. def RFEIA_UPD : RFEI<1, "rfeia\t$Rn!"> {
  2442. let Inst{24-23} = 0b01;
  2443. }
  2444. def RFEIB : RFEI<0, "rfeib\t$Rn"> {
  2445. let Inst{24-23} = 0b11;
  2446. }
  2447. def RFEIB_UPD : RFEI<1, "rfeib\t$Rn!"> {
  2448. let Inst{24-23} = 0b11;
  2449. }
  2450. // Hypervisor Call is a system instruction
  2451. let isCall = 1 in {
  2452. def HVC : AInoP< (outs), (ins imm0_65535:$imm), BrFrm, NoItinerary,
  2453. "hvc", "\t$imm", []>,
  2454. Requires<[IsARM, HasVirtualization]> {
  2455. bits<16> imm;
  2456. // Even though HVC isn't predicable, it's encoding includes a condition field.
  2457. // The instruction is undefined if the condition field is 0xf otherwise it is
  2458. // unpredictable if it isn't condition AL (0xe).
  2459. let Inst{31-28} = 0b1110;
  2460. let Unpredictable{31-28} = 0b1111;
  2461. let Inst{27-24} = 0b0001;
  2462. let Inst{23-20} = 0b0100;
  2463. let Inst{19-8} = imm{15-4};
  2464. let Inst{7-4} = 0b0111;
  2465. let Inst{3-0} = imm{3-0};
  2466. }
  2467. }
  2468. // Return from exception in Hypervisor mode.
  2469. let isReturn = 1, isBarrier = 1, isTerminator = 1, Defs = [PC] in
  2470. def ERET : ABI<0b0001, (outs), (ins), NoItinerary, "eret", "", []>,
  2471. Requires<[IsARM, HasVirtualization]> {
  2472. let Inst{23-0} = 0b011000000000000001101110;
  2473. }
  2474. //===----------------------------------------------------------------------===//
  2475. // Load / Store Instructions.
  2476. //
  2477. // Load
  2478. defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si, load>;
  2479. defm LDRB : AI_ldr1nopc<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si,
  2480. zextloadi8>;
  2481. defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si, store>;
  2482. defm STRB : AI_str1nopc<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si,
  2483. truncstorei8>;
  2484. // Special LDR for loads from non-pc-relative constpools.
  2485. let canFoldAsLoad = 1, mayLoad = 1, hasSideEffects = 0,
  2486. isReMaterializable = 1, isCodeGenOnly = 1 in
  2487. def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
  2488. AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr",
  2489. []> {
  2490. bits<4> Rt;
  2491. bits<17> addr;
  2492. let Inst{23} = addr{12}; // U (add = ('U' == 1))
  2493. let Inst{19-16} = 0b1111;
  2494. let Inst{15-12} = Rt;
  2495. let Inst{11-0} = addr{11-0}; // imm12
  2496. }
  2497. // Loads with zero extension
  2498. def LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
  2499. IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr",
  2500. [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>;
  2501. // Loads with sign extension
  2502. def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
  2503. IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr",
  2504. [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>;
  2505. def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm,
  2506. IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr",
  2507. [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>;
  2508. let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in {
  2509. // Load doubleword
  2510. def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rt, GPR:$Rt2), (ins addrmode3:$addr),
  2511. LdMiscFrm, IIC_iLoad_d_r, "ldrd", "\t$Rt, $Rt2, $addr", []>,
  2512. Requires<[IsARM, HasV5TE]>;
  2513. }
  2514. let mayLoad = 1, hasSideEffects = 0, hasNoSchedulingInfo = 1 in {
  2515. def LOADDUAL : ARMPseudoInst<(outs GPRPairOp:$Rt), (ins addrmode3:$addr),
  2516. 64, IIC_iLoad_d_r, []>,
  2517. Requires<[IsARM, HasV5TE]> {
  2518. let AM = AddrMode3;
  2519. }
  2520. }
  2521. def LDA : AIldracq<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr),
  2522. NoItinerary, "lda", "\t$Rt, $addr", []>;
  2523. def LDAB : AIldracq<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr),
  2524. NoItinerary, "ldab", "\t$Rt, $addr", []>;
  2525. def LDAH : AIldracq<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr),
  2526. NoItinerary, "ldah", "\t$Rt, $addr", []>;
  2527. // Indexed loads
  2528. multiclass AI2_ldridx<bit isByte, string opc,
  2529. InstrItinClass iii, InstrItinClass iir> {
  2530. def _PRE_IMM : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
  2531. (ins addrmode_imm12_pre:$addr), IndexModePre, LdFrm, iii,
  2532. opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
  2533. bits<17> addr;
  2534. let Inst{25} = 0;
  2535. let Inst{23} = addr{12};
  2536. let Inst{19-16} = addr{16-13};
  2537. let Inst{11-0} = addr{11-0};
  2538. let DecoderMethod = "DecodeLDRPreImm";
  2539. }
  2540. def _PRE_REG : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
  2541. (ins ldst_so_reg:$addr), IndexModePre, LdFrm, iir,
  2542. opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
  2543. bits<17> addr;
  2544. let Inst{25} = 1;
  2545. let Inst{23} = addr{12};
  2546. let Inst{19-16} = addr{16-13};
  2547. let Inst{11-0} = addr{11-0};
  2548. let Inst{4} = 0;
  2549. let DecoderMethod = "DecodeLDRPreReg";
  2550. }
  2551. def _POST_REG : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
  2552. (ins addr_offset_none:$addr, am2offset_reg:$offset),
  2553. IndexModePost, LdFrm, iir,
  2554. opc, "\t$Rt, $addr, $offset",
  2555. "$addr.base = $Rn_wb", []> {
  2556. // {12} isAdd
  2557. // {11-0} imm12/Rm
  2558. bits<14> offset;
  2559. bits<4> addr;
  2560. let Inst{25} = 1;
  2561. let Inst{23} = offset{12};
  2562. let Inst{19-16} = addr;
  2563. let Inst{11-0} = offset{11-0};
  2564. let Inst{4} = 0;
  2565. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  2566. }
  2567. def _POST_IMM : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
  2568. (ins addr_offset_none:$addr, am2offset_imm:$offset),
  2569. IndexModePost, LdFrm, iii,
  2570. opc, "\t$Rt, $addr, $offset",
  2571. "$addr.base = $Rn_wb", []> {
  2572. // {12} isAdd
  2573. // {11-0} imm12/Rm
  2574. bits<14> offset;
  2575. bits<4> addr;
  2576. let Inst{25} = 0;
  2577. let Inst{23} = offset{12};
  2578. let Inst{19-16} = addr;
  2579. let Inst{11-0} = offset{11-0};
  2580. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  2581. }
  2582. }
  2583. let mayLoad = 1, hasSideEffects = 0 in {
  2584. // FIXME: for LDR_PRE_REG etc. the itinerary should be either IIC_iLoad_ru or
  2585. // IIC_iLoad_siu depending on whether it the offset register is shifted.
  2586. defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_iu, IIC_iLoad_ru>;
  2587. defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_iu, IIC_iLoad_bh_ru>;
  2588. }
  2589. multiclass AI3_ldridx<bits<4> op, string opc, InstrItinClass itin> {
  2590. def _PRE : AI3ldstidx<op, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
  2591. (ins addrmode3_pre:$addr), IndexModePre,
  2592. LdMiscFrm, itin,
  2593. opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
  2594. bits<14> addr;
  2595. let Inst{23} = addr{8}; // U bit
  2596. let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
  2597. let Inst{19-16} = addr{12-9}; // Rn
  2598. let Inst{11-8} = addr{7-4}; // imm7_4/zero
  2599. let Inst{3-0} = addr{3-0}; // imm3_0/Rm
  2600. let DecoderMethod = "DecodeAddrMode3Instruction";
  2601. }
  2602. def _POST : AI3ldstidx<op, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
  2603. (ins addr_offset_none:$addr, am3offset:$offset),
  2604. IndexModePost, LdMiscFrm, itin,
  2605. opc, "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb",
  2606. []> {
  2607. bits<10> offset;
  2608. bits<4> addr;
  2609. let Inst{23} = offset{8}; // U bit
  2610. let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
  2611. let Inst{19-16} = addr;
  2612. let Inst{11-8} = offset{7-4}; // imm7_4/zero
  2613. let Inst{3-0} = offset{3-0}; // imm3_0/Rm
  2614. let DecoderMethod = "DecodeAddrMode3Instruction";
  2615. }
  2616. }
  2617. let mayLoad = 1, hasSideEffects = 0 in {
  2618. defm LDRH : AI3_ldridx<0b1011, "ldrh", IIC_iLoad_bh_ru>;
  2619. defm LDRSH : AI3_ldridx<0b1111, "ldrsh", IIC_iLoad_bh_ru>;
  2620. defm LDRSB : AI3_ldridx<0b1101, "ldrsb", IIC_iLoad_bh_ru>;
  2621. let hasExtraDefRegAllocReq = 1 in {
  2622. def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
  2623. (ins addrmode3_pre:$addr), IndexModePre,
  2624. LdMiscFrm, IIC_iLoad_d_ru,
  2625. "ldrd", "\t$Rt, $Rt2, $addr!",
  2626. "$addr.base = $Rn_wb", []> {
  2627. bits<14> addr;
  2628. let Inst{23} = addr{8}; // U bit
  2629. let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
  2630. let Inst{19-16} = addr{12-9}; // Rn
  2631. let Inst{11-8} = addr{7-4}; // imm7_4/zero
  2632. let Inst{3-0} = addr{3-0}; // imm3_0/Rm
  2633. let DecoderMethod = "DecodeAddrMode3Instruction";
  2634. }
  2635. def LDRD_POST: AI3ldstidx<0b1101, 0, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
  2636. (ins addr_offset_none:$addr, am3offset:$offset),
  2637. IndexModePost, LdMiscFrm, IIC_iLoad_d_ru,
  2638. "ldrd", "\t$Rt, $Rt2, $addr, $offset",
  2639. "$addr.base = $Rn_wb", []> {
  2640. bits<10> offset;
  2641. bits<4> addr;
  2642. let Inst{23} = offset{8}; // U bit
  2643. let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
  2644. let Inst{19-16} = addr;
  2645. let Inst{11-8} = offset{7-4}; // imm7_4/zero
  2646. let Inst{3-0} = offset{3-0}; // imm3_0/Rm
  2647. let DecoderMethod = "DecodeAddrMode3Instruction";
  2648. }
  2649. } // hasExtraDefRegAllocReq = 1
  2650. } // mayLoad = 1, hasSideEffects = 0
  2651. // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT.
  2652. let mayLoad = 1, hasSideEffects = 0 in {
  2653. def LDRT_POST_REG : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb),
  2654. (ins addr_offset_none:$addr, am2offset_reg:$offset),
  2655. IndexModePost, LdFrm, IIC_iLoad_ru,
  2656. "ldrt", "\t$Rt, $addr, $offset",
  2657. "$addr.base = $Rn_wb", []> {
  2658. // {12} isAdd
  2659. // {11-0} imm12/Rm
  2660. bits<14> offset;
  2661. bits<4> addr;
  2662. let Inst{25} = 1;
  2663. let Inst{23} = offset{12};
  2664. let Inst{21} = 1; // overwrite
  2665. let Inst{19-16} = addr;
  2666. let Inst{11-5} = offset{11-5};
  2667. let Inst{4} = 0;
  2668. let Inst{3-0} = offset{3-0};
  2669. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  2670. }
  2671. def LDRT_POST_IMM
  2672. : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb),
  2673. (ins addr_offset_none:$addr, am2offset_imm:$offset),
  2674. IndexModePost, LdFrm, IIC_iLoad_ru,
  2675. "ldrt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> {
  2676. // {12} isAdd
  2677. // {11-0} imm12/Rm
  2678. bits<14> offset;
  2679. bits<4> addr;
  2680. let Inst{25} = 0;
  2681. let Inst{23} = offset{12};
  2682. let Inst{21} = 1; // overwrite
  2683. let Inst{19-16} = addr;
  2684. let Inst{11-0} = offset{11-0};
  2685. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  2686. }
  2687. def LDRBT_POST_REG : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
  2688. (ins addr_offset_none:$addr, am2offset_reg:$offset),
  2689. IndexModePost, LdFrm, IIC_iLoad_bh_ru,
  2690. "ldrbt", "\t$Rt, $addr, $offset",
  2691. "$addr.base = $Rn_wb", []> {
  2692. // {12} isAdd
  2693. // {11-0} imm12/Rm
  2694. bits<14> offset;
  2695. bits<4> addr;
  2696. let Inst{25} = 1;
  2697. let Inst{23} = offset{12};
  2698. let Inst{21} = 1; // overwrite
  2699. let Inst{19-16} = addr;
  2700. let Inst{11-5} = offset{11-5};
  2701. let Inst{4} = 0;
  2702. let Inst{3-0} = offset{3-0};
  2703. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  2704. }
  2705. def LDRBT_POST_IMM
  2706. : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
  2707. (ins addr_offset_none:$addr, am2offset_imm:$offset),
  2708. IndexModePost, LdFrm, IIC_iLoad_bh_ru,
  2709. "ldrbt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> {
  2710. // {12} isAdd
  2711. // {11-0} imm12/Rm
  2712. bits<14> offset;
  2713. bits<4> addr;
  2714. let Inst{25} = 0;
  2715. let Inst{23} = offset{12};
  2716. let Inst{21} = 1; // overwrite
  2717. let Inst{19-16} = addr;
  2718. let Inst{11-0} = offset{11-0};
  2719. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  2720. }
  2721. multiclass AI3ldrT<bits<4> op, string opc> {
  2722. def i : AI3ldstidxT<op, 1, (outs GPR:$Rt, GPR:$base_wb),
  2723. (ins addr_offset_none:$addr, postidx_imm8:$offset),
  2724. IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc,
  2725. "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> {
  2726. bits<9> offset;
  2727. let Inst{23} = offset{8};
  2728. let Inst{22} = 1;
  2729. let Inst{11-8} = offset{7-4};
  2730. let Inst{3-0} = offset{3-0};
  2731. }
  2732. def r : AI3ldstidxT<op, 1, (outs GPRnopc:$Rt, GPRnopc:$base_wb),
  2733. (ins addr_offset_none:$addr, postidx_reg:$Rm),
  2734. IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc,
  2735. "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> {
  2736. bits<5> Rm;
  2737. let Inst{23} = Rm{4};
  2738. let Inst{22} = 0;
  2739. let Inst{11-8} = 0;
  2740. let Unpredictable{11-8} = 0b1111;
  2741. let Inst{3-0} = Rm{3-0};
  2742. let DecoderMethod = "DecodeLDR";
  2743. }
  2744. def ii : ARMAsmPseudo<!strconcat(opc, "${p} $Rt, $addr"),
  2745. (ins addr_offset_none:$addr, pred:$p), (outs GPR:$Rt)>;
  2746. }
  2747. defm LDRSBT : AI3ldrT<0b1101, "ldrsbt">;
  2748. defm LDRHT : AI3ldrT<0b1011, "ldrht">;
  2749. defm LDRSHT : AI3ldrT<0b1111, "ldrsht">;
  2750. }
  2751. def LDRT_POST
  2752. : ARMAsmPseudo<"ldrt${q} $Rt, $addr", (ins addr_offset_none:$addr, pred:$q),
  2753. (outs GPR:$Rt)>;
  2754. def LDRBT_POST
  2755. : ARMAsmPseudo<"ldrbt${q} $Rt, $addr", (ins addr_offset_none:$addr, pred:$q),
  2756. (outs GPR:$Rt)>;
  2757. // Pseudo instruction ldr Rt, =immediate
  2758. def LDRConstPool
  2759. : ARMAsmPseudo<"ldr${q} $Rt, $immediate",
  2760. (ins const_pool_asm_imm:$immediate, pred:$q),
  2761. (outs GPR:$Rt)>;
  2762. // Store
  2763. // Stores with truncate
  2764. def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
  2765. IIC_iStore_bh_r, "strh", "\t$Rt, $addr",
  2766. [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
  2767. // Store doubleword
  2768. let mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in {
  2769. def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$Rt2, addrmode3:$addr),
  2770. StMiscFrm, IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", []>,
  2771. Requires<[IsARM, HasV5TE]> {
  2772. let Inst{21} = 0;
  2773. }
  2774. }
  2775. let mayStore = 1, hasSideEffects = 0, hasNoSchedulingInfo = 1 in {
  2776. def STOREDUAL : ARMPseudoInst<(outs), (ins GPRPairOp:$Rt, addrmode3:$addr),
  2777. 64, IIC_iStore_d_r, []>,
  2778. Requires<[IsARM, HasV5TE]> {
  2779. let AM = AddrMode3;
  2780. }
  2781. }
  2782. // Indexed stores
  2783. multiclass AI2_stridx<bit isByte, string opc,
  2784. InstrItinClass iii, InstrItinClass iir> {
  2785. def _PRE_IMM : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb),
  2786. (ins GPR:$Rt, addrmode_imm12_pre:$addr), IndexModePre,
  2787. StFrm, iii,
  2788. opc, "\t$Rt, $addr!",
  2789. "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> {
  2790. bits<17> addr;
  2791. let Inst{25} = 0;
  2792. let Inst{23} = addr{12}; // U (add = ('U' == 1))
  2793. let Inst{19-16} = addr{16-13}; // Rn
  2794. let Inst{11-0} = addr{11-0}; // imm12
  2795. let DecoderMethod = "DecodeSTRPreImm";
  2796. }
  2797. def _PRE_REG : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb),
  2798. (ins GPR:$Rt, ldst_so_reg:$addr),
  2799. IndexModePre, StFrm, iir,
  2800. opc, "\t$Rt, $addr!",
  2801. "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> {
  2802. bits<17> addr;
  2803. let Inst{25} = 1;
  2804. let Inst{23} = addr{12}; // U (add = ('U' == 1))
  2805. let Inst{19-16} = addr{16-13}; // Rn
  2806. let Inst{11-0} = addr{11-0};
  2807. let Inst{4} = 0; // Inst{4} = 0
  2808. let DecoderMethod = "DecodeSTRPreReg";
  2809. }
  2810. def _POST_REG : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb),
  2811. (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset),
  2812. IndexModePost, StFrm, iir,
  2813. opc, "\t$Rt, $addr, $offset",
  2814. "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> {
  2815. // {12} isAdd
  2816. // {11-0} imm12/Rm
  2817. bits<14> offset;
  2818. bits<4> addr;
  2819. let Inst{25} = 1;
  2820. let Inst{23} = offset{12};
  2821. let Inst{19-16} = addr;
  2822. let Inst{11-0} = offset{11-0};
  2823. let Inst{4} = 0;
  2824. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  2825. }
  2826. def _POST_IMM : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb),
  2827. (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset),
  2828. IndexModePost, StFrm, iii,
  2829. opc, "\t$Rt, $addr, $offset",
  2830. "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> {
  2831. // {12} isAdd
  2832. // {11-0} imm12/Rm
  2833. bits<14> offset;
  2834. bits<4> addr;
  2835. let Inst{25} = 0;
  2836. let Inst{23} = offset{12};
  2837. let Inst{19-16} = addr;
  2838. let Inst{11-0} = offset{11-0};
  2839. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  2840. }
  2841. }
  2842. let mayStore = 1, hasSideEffects = 0 in {
  2843. // FIXME: for STR_PRE_REG etc. the itinerary should be either IIC_iStore_ru or
  2844. // IIC_iStore_siu depending on whether it the offset register is shifted.
  2845. defm STR : AI2_stridx<0, "str", IIC_iStore_iu, IIC_iStore_ru>;
  2846. defm STRB : AI2_stridx<1, "strb", IIC_iStore_bh_iu, IIC_iStore_bh_ru>;
  2847. }
  2848. def : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr,
  2849. am2offset_reg:$offset),
  2850. (STR_POST_REG GPR:$Rt, addr_offset_none:$addr,
  2851. am2offset_reg:$offset)>;
  2852. def : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr,
  2853. am2offset_imm:$offset),
  2854. (STR_POST_IMM GPR:$Rt, addr_offset_none:$addr,
  2855. am2offset_imm:$offset)>;
  2856. def : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr,
  2857. am2offset_reg:$offset),
  2858. (STRB_POST_REG GPR:$Rt, addr_offset_none:$addr,
  2859. am2offset_reg:$offset)>;
  2860. def : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr,
  2861. am2offset_imm:$offset),
  2862. (STRB_POST_IMM GPR:$Rt, addr_offset_none:$addr,
  2863. am2offset_imm:$offset)>;
  2864. // Pseudo-instructions for pattern matching the pre-indexed stores. We can't
  2865. // put the patterns on the instruction definitions directly as ISel wants
  2866. // the address base and offset to be separate operands, not a single
  2867. // complex operand like we represent the instructions themselves. The
  2868. // pseudos map between the two.
  2869. let usesCustomInserter = 1,
  2870. Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in {
  2871. def STRi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
  2872. (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p),
  2873. 4, IIC_iStore_ru,
  2874. [(set GPR:$Rn_wb,
  2875. (pre_store GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>;
  2876. def STRr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
  2877. (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p),
  2878. 4, IIC_iStore_ru,
  2879. [(set GPR:$Rn_wb,
  2880. (pre_store GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>;
  2881. def STRBi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
  2882. (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p),
  2883. 4, IIC_iStore_ru,
  2884. [(set GPR:$Rn_wb,
  2885. (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>;
  2886. def STRBr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
  2887. (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p),
  2888. 4, IIC_iStore_ru,
  2889. [(set GPR:$Rn_wb,
  2890. (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>;
  2891. def STRH_preidx: ARMPseudoInst<(outs GPR:$Rn_wb),
  2892. (ins GPR:$Rt, GPR:$Rn, am3offset:$offset, pred:$p),
  2893. 4, IIC_iStore_ru,
  2894. [(set GPR:$Rn_wb,
  2895. (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>;
  2896. }
  2897. def STRH_PRE : AI3ldstidx<0b1011, 0, 1, (outs GPR:$Rn_wb),
  2898. (ins GPR:$Rt, addrmode3_pre:$addr), IndexModePre,
  2899. StMiscFrm, IIC_iStore_bh_ru,
  2900. "strh", "\t$Rt, $addr!",
  2901. "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> {
  2902. bits<14> addr;
  2903. let Inst{23} = addr{8}; // U bit
  2904. let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
  2905. let Inst{19-16} = addr{12-9}; // Rn
  2906. let Inst{11-8} = addr{7-4}; // imm7_4/zero
  2907. let Inst{3-0} = addr{3-0}; // imm3_0/Rm
  2908. let DecoderMethod = "DecodeAddrMode3Instruction";
  2909. }
  2910. def STRH_POST : AI3ldstidx<0b1011, 0, 0, (outs GPR:$Rn_wb),
  2911. (ins GPR:$Rt, addr_offset_none:$addr, am3offset:$offset),
  2912. IndexModePost, StMiscFrm, IIC_iStore_bh_ru,
  2913. "strh", "\t$Rt, $addr, $offset",
  2914. "$addr.base = $Rn_wb,@earlyclobber $Rn_wb",
  2915. [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
  2916. addr_offset_none:$addr,
  2917. am3offset:$offset))]> {
  2918. bits<10> offset;
  2919. bits<4> addr;
  2920. let Inst{23} = offset{8}; // U bit
  2921. let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
  2922. let Inst{19-16} = addr;
  2923. let Inst{11-8} = offset{7-4}; // imm7_4/zero
  2924. let Inst{3-0} = offset{3-0}; // imm3_0/Rm
  2925. let DecoderMethod = "DecodeAddrMode3Instruction";
  2926. }
  2927. let mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in {
  2928. def STRD_PRE : AI3ldstidx<0b1111, 0, 1, (outs GPR:$Rn_wb),
  2929. (ins GPR:$Rt, GPR:$Rt2, addrmode3_pre:$addr),
  2930. IndexModePre, StMiscFrm, IIC_iStore_d_ru,
  2931. "strd", "\t$Rt, $Rt2, $addr!",
  2932. "$addr.base = $Rn_wb", []> {
  2933. bits<14> addr;
  2934. let Inst{23} = addr{8}; // U bit
  2935. let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
  2936. let Inst{19-16} = addr{12-9}; // Rn
  2937. let Inst{11-8} = addr{7-4}; // imm7_4/zero
  2938. let Inst{3-0} = addr{3-0}; // imm3_0/Rm
  2939. let DecoderMethod = "DecodeAddrMode3Instruction";
  2940. }
  2941. def STRD_POST: AI3ldstidx<0b1111, 0, 0, (outs GPR:$Rn_wb),
  2942. (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr,
  2943. am3offset:$offset),
  2944. IndexModePost, StMiscFrm, IIC_iStore_d_ru,
  2945. "strd", "\t$Rt, $Rt2, $addr, $offset",
  2946. "$addr.base = $Rn_wb", []> {
  2947. bits<10> offset;
  2948. bits<4> addr;
  2949. let Inst{23} = offset{8}; // U bit
  2950. let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
  2951. let Inst{19-16} = addr;
  2952. let Inst{11-8} = offset{7-4}; // imm7_4/zero
  2953. let Inst{3-0} = offset{3-0}; // imm3_0/Rm
  2954. let DecoderMethod = "DecodeAddrMode3Instruction";
  2955. }
  2956. } // mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1
  2957. // STRT, STRBT, and STRHT
  2958. def STRBT_POST_REG : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
  2959. (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset),
  2960. IndexModePost, StFrm, IIC_iStore_bh_ru,
  2961. "strbt", "\t$Rt, $addr, $offset",
  2962. "$addr.base = $Rn_wb", []> {
  2963. // {12} isAdd
  2964. // {11-0} imm12/Rm
  2965. bits<14> offset;
  2966. bits<4> addr;
  2967. let Inst{25} = 1;
  2968. let Inst{23} = offset{12};
  2969. let Inst{21} = 1; // overwrite
  2970. let Inst{19-16} = addr;
  2971. let Inst{11-5} = offset{11-5};
  2972. let Inst{4} = 0;
  2973. let Inst{3-0} = offset{3-0};
  2974. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  2975. }
  2976. def STRBT_POST_IMM
  2977. : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
  2978. (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset),
  2979. IndexModePost, StFrm, IIC_iStore_bh_ru,
  2980. "strbt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> {
  2981. // {12} isAdd
  2982. // {11-0} imm12/Rm
  2983. bits<14> offset;
  2984. bits<4> addr;
  2985. let Inst{25} = 0;
  2986. let Inst{23} = offset{12};
  2987. let Inst{21} = 1; // overwrite
  2988. let Inst{19-16} = addr;
  2989. let Inst{11-0} = offset{11-0};
  2990. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  2991. }
  2992. def STRBT_POST
  2993. : ARMAsmPseudo<"strbt${q} $Rt, $addr",
  2994. (ins GPR:$Rt, addr_offset_none:$addr, pred:$q)>;
  2995. let mayStore = 1, hasSideEffects = 0 in {
  2996. def STRT_POST_REG : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
  2997. (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset),
  2998. IndexModePost, StFrm, IIC_iStore_ru,
  2999. "strt", "\t$Rt, $addr, $offset",
  3000. "$addr.base = $Rn_wb", []> {
  3001. // {12} isAdd
  3002. // {11-0} imm12/Rm
  3003. bits<14> offset;
  3004. bits<4> addr;
  3005. let Inst{25} = 1;
  3006. let Inst{23} = offset{12};
  3007. let Inst{21} = 1; // overwrite
  3008. let Inst{19-16} = addr;
  3009. let Inst{11-5} = offset{11-5};
  3010. let Inst{4} = 0;
  3011. let Inst{3-0} = offset{3-0};
  3012. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  3013. }
  3014. def STRT_POST_IMM
  3015. : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
  3016. (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset),
  3017. IndexModePost, StFrm, IIC_iStore_ru,
  3018. "strt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> {
  3019. // {12} isAdd
  3020. // {11-0} imm12/Rm
  3021. bits<14> offset;
  3022. bits<4> addr;
  3023. let Inst{25} = 0;
  3024. let Inst{23} = offset{12};
  3025. let Inst{21} = 1; // overwrite
  3026. let Inst{19-16} = addr;
  3027. let Inst{11-0} = offset{11-0};
  3028. let DecoderMethod = "DecodeAddrMode2IdxInstruction";
  3029. }
  3030. }
  3031. def STRT_POST
  3032. : ARMAsmPseudo<"strt${q} $Rt, $addr",
  3033. (ins GPR:$Rt, addr_offset_none:$addr, pred:$q)>;
  3034. multiclass AI3strT<bits<4> op, string opc> {
  3035. def i : AI3ldstidxT<op, 0, (outs GPR:$base_wb),
  3036. (ins GPR:$Rt, addr_offset_none:$addr, postidx_imm8:$offset),
  3037. IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc,
  3038. "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> {
  3039. bits<9> offset;
  3040. let Inst{23} = offset{8};
  3041. let Inst{22} = 1;
  3042. let Inst{11-8} = offset{7-4};
  3043. let Inst{3-0} = offset{3-0};
  3044. }
  3045. def r : AI3ldstidxT<op, 0, (outs GPR:$base_wb),
  3046. (ins GPR:$Rt, addr_offset_none:$addr, postidx_reg:$Rm),
  3047. IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc,
  3048. "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> {
  3049. bits<5> Rm;
  3050. let Inst{23} = Rm{4};
  3051. let Inst{22} = 0;
  3052. let Inst{11-8} = 0;
  3053. let Inst{3-0} = Rm{3-0};
  3054. }
  3055. }
  3056. defm STRHT : AI3strT<0b1011, "strht">;
  3057. def STL : AIstrrel<0b00, (outs), (ins GPR:$Rt, addr_offset_none:$addr),
  3058. NoItinerary, "stl", "\t$Rt, $addr", []>;
  3059. def STLB : AIstrrel<0b10, (outs), (ins GPR:$Rt, addr_offset_none:$addr),
  3060. NoItinerary, "stlb", "\t$Rt, $addr", []>;
  3061. def STLH : AIstrrel<0b11, (outs), (ins GPR:$Rt, addr_offset_none:$addr),
  3062. NoItinerary, "stlh", "\t$Rt, $addr", []>;
  3063. //===----------------------------------------------------------------------===//
  3064. // Load / store multiple Instructions.
  3065. //
  3066. multiclass arm_ldst_mult<string asm, string sfx, bit L_bit, bit P_bit, Format f,
  3067. InstrItinClass itin, InstrItinClass itin_upd> {
  3068. // IA is the default, so no need for an explicit suffix on the
  3069. // mnemonic here. Without it is the canonical spelling.
  3070. def IA :
  3071. AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
  3072. IndexModeNone, f, itin,
  3073. !strconcat(asm, "${p}\t$Rn, $regs", sfx), "", []> {
  3074. let Inst{24-23} = 0b01; // Increment After
  3075. let Inst{22} = P_bit;
  3076. let Inst{21} = 0; // No writeback
  3077. let Inst{20} = L_bit;
  3078. }
  3079. def IA_UPD :
  3080. AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
  3081. IndexModeUpd, f, itin_upd,
  3082. !strconcat(asm, "${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
  3083. let Inst{24-23} = 0b01; // Increment After
  3084. let Inst{22} = P_bit;
  3085. let Inst{21} = 1; // Writeback
  3086. let Inst{20} = L_bit;
  3087. let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
  3088. }
  3089. def DA :
  3090. AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
  3091. IndexModeNone, f, itin,
  3092. !strconcat(asm, "da${p}\t$Rn, $regs", sfx), "", []> {
  3093. let Inst{24-23} = 0b00; // Decrement After
  3094. let Inst{22} = P_bit;
  3095. let Inst{21} = 0; // No writeback
  3096. let Inst{20} = L_bit;
  3097. }
  3098. def DA_UPD :
  3099. AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
  3100. IndexModeUpd, f, itin_upd,
  3101. !strconcat(asm, "da${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
  3102. let Inst{24-23} = 0b00; // Decrement After
  3103. let Inst{22} = P_bit;
  3104. let Inst{21} = 1; // Writeback
  3105. let Inst{20} = L_bit;
  3106. let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
  3107. }
  3108. def DB :
  3109. AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
  3110. IndexModeNone, f, itin,
  3111. !strconcat(asm, "db${p}\t$Rn, $regs", sfx), "", []> {
  3112. let Inst{24-23} = 0b10; // Decrement Before
  3113. let Inst{22} = P_bit;
  3114. let Inst{21} = 0; // No writeback
  3115. let Inst{20} = L_bit;
  3116. }
  3117. def DB_UPD :
  3118. AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
  3119. IndexModeUpd, f, itin_upd,
  3120. !strconcat(asm, "db${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
  3121. let Inst{24-23} = 0b10; // Decrement Before
  3122. let Inst{22} = P_bit;
  3123. let Inst{21} = 1; // Writeback
  3124. let Inst{20} = L_bit;
  3125. let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
  3126. }
  3127. def IB :
  3128. AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
  3129. IndexModeNone, f, itin,
  3130. !strconcat(asm, "ib${p}\t$Rn, $regs", sfx), "", []> {
  3131. let Inst{24-23} = 0b11; // Increment Before
  3132. let Inst{22} = P_bit;
  3133. let Inst{21} = 0; // No writeback
  3134. let Inst{20} = L_bit;
  3135. }
  3136. def IB_UPD :
  3137. AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
  3138. IndexModeUpd, f, itin_upd,
  3139. !strconcat(asm, "ib${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> {
  3140. let Inst{24-23} = 0b11; // Increment Before
  3141. let Inst{22} = P_bit;
  3142. let Inst{21} = 1; // Writeback
  3143. let Inst{20} = L_bit;
  3144. let DecoderMethod = "DecodeMemMultipleWritebackInstruction";
  3145. }
  3146. }
  3147. let hasSideEffects = 0 in {
  3148. let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in
  3149. defm LDM : arm_ldst_mult<"ldm", "", 1, 0, LdStMulFrm, IIC_iLoad_m,
  3150. IIC_iLoad_mu>, ComplexDeprecationPredicate<"ARMLoad">;
  3151. let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
  3152. defm STM : arm_ldst_mult<"stm", "", 0, 0, LdStMulFrm, IIC_iStore_m,
  3153. IIC_iStore_mu>,
  3154. ComplexDeprecationPredicate<"ARMStore">;
  3155. } // hasSideEffects
  3156. // FIXME: remove when we have a way to marking a MI with these properties.
  3157. // FIXME: Should pc be an implicit operand like PICADD, etc?
  3158. let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
  3159. hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
  3160. def LDMIA_RET : ARMPseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
  3161. reglist:$regs, variable_ops),
  3162. 4, IIC_iLoad_mBr, [],
  3163. (LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>,
  3164. RegConstraint<"$Rn = $wb">;
  3165. let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
  3166. defm sysLDM : arm_ldst_mult<"ldm", " ^", 1, 1, LdStMulFrm, IIC_iLoad_m,
  3167. IIC_iLoad_mu>;
  3168. let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
  3169. defm sysSTM : arm_ldst_mult<"stm", " ^", 0, 1, LdStMulFrm, IIC_iStore_m,
  3170. IIC_iStore_mu>;
  3171. //===----------------------------------------------------------------------===//
  3172. // Move Instructions.
  3173. //
  3174. let hasSideEffects = 0, isMoveReg = 1 in
  3175. def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
  3176. "mov", "\t$Rd, $Rm", []>, UnaryDP, Sched<[WriteALU]> {
  3177. bits<4> Rd;
  3178. bits<4> Rm;
  3179. let Inst{19-16} = 0b0000;
  3180. let Inst{11-4} = 0b00000000;
  3181. let Inst{25} = 0;
  3182. let Inst{3-0} = Rm;
  3183. let Inst{15-12} = Rd;
  3184. }
  3185. // A version for the smaller set of tail call registers.
  3186. let hasSideEffects = 0 in
  3187. def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
  3188. IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP, Sched<[WriteALU]> {
  3189. bits<4> Rd;
  3190. bits<4> Rm;
  3191. let Inst{11-4} = 0b00000000;
  3192. let Inst{25} = 0;
  3193. let Inst{3-0} = Rm;
  3194. let Inst{15-12} = Rd;
  3195. }
  3196. def MOVsr : AsI1<0b1101, (outs GPRnopc:$Rd), (ins shift_so_reg_reg:$src),
  3197. DPSoRegRegFrm, IIC_iMOVsr,
  3198. "mov", "\t$Rd, $src",
  3199. [(set GPRnopc:$Rd, shift_so_reg_reg:$src)]>, UnaryDP,
  3200. Sched<[WriteALU]> {
  3201. bits<4> Rd;
  3202. bits<12> src;
  3203. let Inst{15-12} = Rd;
  3204. let Inst{19-16} = 0b0000;
  3205. let Inst{11-8} = src{11-8};
  3206. let Inst{7} = 0;
  3207. let Inst{6-5} = src{6-5};
  3208. let Inst{4} = 1;
  3209. let Inst{3-0} = src{3-0};
  3210. let Inst{25} = 0;
  3211. }
  3212. def MOVsi : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg_imm:$src),
  3213. DPSoRegImmFrm, IIC_iMOVsr,
  3214. "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg_imm:$src)]>,
  3215. UnaryDP, Sched<[WriteALU]> {
  3216. bits<4> Rd;
  3217. bits<12> src;
  3218. let Inst{15-12} = Rd;
  3219. let Inst{19-16} = 0b0000;
  3220. let Inst{11-5} = src{11-5};
  3221. let Inst{4} = 0;
  3222. let Inst{3-0} = src{3-0};
  3223. let Inst{25} = 0;
  3224. }
  3225. let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
  3226. def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins mod_imm:$imm), DPFrm, IIC_iMOVi,
  3227. "mov", "\t$Rd, $imm", [(set GPR:$Rd, mod_imm:$imm)]>, UnaryDP,
  3228. Sched<[WriteALU]> {
  3229. bits<4> Rd;
  3230. bits<12> imm;
  3231. let Inst{25} = 1;
  3232. let Inst{15-12} = Rd;
  3233. let Inst{19-16} = 0b0000;
  3234. let Inst{11-0} = imm;
  3235. }
  3236. let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
  3237. def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins imm0_65535_expr:$imm),
  3238. DPFrm, IIC_iMOVi,
  3239. "movw", "\t$Rd, $imm",
  3240. [(set GPR:$Rd, imm0_65535:$imm)]>,
  3241. Requires<[IsARM, HasV6T2]>, UnaryDP, Sched<[WriteALU]> {
  3242. bits<4> Rd;
  3243. bits<16> imm;
  3244. let Inst{15-12} = Rd;
  3245. let Inst{11-0} = imm{11-0};
  3246. let Inst{19-16} = imm{15-12};
  3247. let Inst{20} = 0;
  3248. let Inst{25} = 1;
  3249. let DecoderMethod = "DecodeArmMOVTWInstruction";
  3250. }
  3251. def : InstAlias<"mov${p} $Rd, $imm",
  3252. (MOVi16 GPR:$Rd, imm0_65535_expr:$imm, pred:$p), 0>,
  3253. Requires<[IsARM, HasV6T2]>;
  3254. // This gets lowered to a single 4-byte instructions
  3255. let Size = 4 in
  3256. def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
  3257. (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>,
  3258. Sched<[WriteALU]>;
  3259. let Constraints = "$src = $Rd" in {
  3260. def MOVTi16 : AI1<0b1010, (outs GPRnopc:$Rd),
  3261. (ins GPR:$src, imm0_65535_expr:$imm),
  3262. DPFrm, IIC_iMOVi,
  3263. "movt", "\t$Rd, $imm",
  3264. [(set GPRnopc:$Rd,
  3265. (or (and GPR:$src, 0xffff),
  3266. lo16AllZero:$imm))]>, UnaryDP,
  3267. Requires<[IsARM, HasV6T2]>, Sched<[WriteALU]> {
  3268. bits<4> Rd;
  3269. bits<16> imm;
  3270. let Inst{15-12} = Rd;
  3271. let Inst{11-0} = imm{11-0};
  3272. let Inst{19-16} = imm{15-12};
  3273. let Inst{20} = 0;
  3274. let Inst{25} = 1;
  3275. let DecoderMethod = "DecodeArmMOVTWInstruction";
  3276. }
  3277. // This gets lowered to a single 4-byte instructions
  3278. let Size = 4 in
  3279. def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
  3280. (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>,
  3281. Sched<[WriteALU]>;
  3282. } // Constraints
  3283. def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
  3284. Requires<[IsARM, HasV6T2]>;
  3285. let Uses = [CPSR] in
  3286. def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi,
  3287. [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP,
  3288. Requires<[IsARM]>, Sched<[WriteALU]>;
  3289. // These aren't really mov instructions, but we have to define them this way
  3290. // due to flag operands.
  3291. let Defs = [CPSR] in {
  3292. def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
  3293. [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP,
  3294. Sched<[WriteALU]>, Requires<[IsARM]>;
  3295. def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
  3296. [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP,
  3297. Sched<[WriteALU]>, Requires<[IsARM]>;
  3298. }
  3299. //===----------------------------------------------------------------------===//
  3300. // Extend Instructions.
  3301. //
  3302. // Sign extenders
  3303. def SXTB : AI_ext_rrot<0b01101010,
  3304. "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
  3305. def SXTH : AI_ext_rrot<0b01101011,
  3306. "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
  3307. def SXTAB : AI_exta_rrot<0b01101010,
  3308. "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
  3309. def SXTAH : AI_exta_rrot<0b01101011,
  3310. "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
  3311. def : ARMV6Pat<(add rGPR:$Rn, (sext_inreg (srl rGPR:$Rm, rot_imm:$rot), i8)),
  3312. (SXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
  3313. def : ARMV6Pat<(add rGPR:$Rn, (sext_inreg (srl rGPR:$Rm, imm8_or_16:$rot),
  3314. i16)),
  3315. (SXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
  3316. def SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">;
  3317. def : ARMV6Pat<(int_arm_sxtb16 GPR:$Src),
  3318. (SXTB16 GPR:$Src, 0)>;
  3319. def : ARMV6Pat<(int_arm_sxtb16 (rotr GPR:$Src, rot_imm:$rot)),
  3320. (SXTB16 GPR:$Src, rot_imm:$rot)>;
  3321. def SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">;
  3322. def : ARMV6Pat<(int_arm_sxtab16 GPR:$LHS, GPR:$RHS),
  3323. (SXTAB16 GPR:$LHS, GPR:$RHS, 0)>;
  3324. def : ARMV6Pat<(int_arm_sxtab16 GPR:$LHS, (rotr GPR:$RHS, rot_imm:$rot)),
  3325. (SXTAB16 GPR:$LHS, GPR:$RHS, rot_imm:$rot)>;
  3326. // Zero extenders
  3327. let AddedComplexity = 16 in {
  3328. def UXTB : AI_ext_rrot<0b01101110,
  3329. "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
  3330. def UXTH : AI_ext_rrot<0b01101111,
  3331. "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
  3332. def UXTB16 : AI_ext_rrot<0b01101100,
  3333. "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
  3334. // FIXME: This pattern incorrectly assumes the shl operator is a rotate.
  3335. // The transformation should probably be done as a combiner action
  3336. // instead so we can include a check for masking back in the upper
  3337. // eight bits of the source into the lower eight bits of the result.
  3338. //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
  3339. // (UXTB16r_rot GPR:$Src, 3)>;
  3340. def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
  3341. (UXTB16 GPR:$Src, 1)>;
  3342. def : ARMV6Pat<(int_arm_uxtb16 GPR:$Src),
  3343. (UXTB16 GPR:$Src, 0)>;
  3344. def : ARMV6Pat<(int_arm_uxtb16 (rotr GPR:$Src, rot_imm:$rot)),
  3345. (UXTB16 GPR:$Src, rot_imm:$rot)>;
  3346. def UXTAB : AI_exta_rrot<0b01101110, "uxtab",
  3347. BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
  3348. def UXTAH : AI_exta_rrot<0b01101111, "uxtah",
  3349. BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
  3350. def : ARMV6Pat<(add rGPR:$Rn, (and (srl rGPR:$Rm, rot_imm:$rot), 0xFF)),
  3351. (UXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
  3352. def : ARMV6Pat<(add rGPR:$Rn, (and (srl rGPR:$Rm, imm8_or_16:$rot), 0xFFFF)),
  3353. (UXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>;
  3354. }
  3355. // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
  3356. def UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
  3357. def : ARMV6Pat<(int_arm_uxtab16 GPR:$LHS, GPR:$RHS),
  3358. (UXTAB16 GPR:$LHS, GPR:$RHS, 0)>;
  3359. def : ARMV6Pat<(int_arm_uxtab16 GPR:$LHS, (rotr GPR:$RHS, rot_imm:$rot)),
  3360. (UXTAB16 GPR:$LHS, GPR:$RHS, rot_imm:$rot)>;
  3361. def SBFX : I<(outs GPRnopc:$Rd),
  3362. (ins GPRnopc:$Rn, imm0_31:$lsb, imm1_32:$width),
  3363. AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
  3364. "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
  3365. Requires<[IsARM, HasV6T2]> {
  3366. bits<4> Rd;
  3367. bits<4> Rn;
  3368. bits<5> lsb;
  3369. bits<5> width;
  3370. let Inst{27-21} = 0b0111101;
  3371. let Inst{6-4} = 0b101;
  3372. let Inst{20-16} = width;
  3373. let Inst{15-12} = Rd;
  3374. let Inst{11-7} = lsb;
  3375. let Inst{3-0} = Rn;
  3376. }
  3377. def UBFX : I<(outs GPRnopc:$Rd),
  3378. (ins GPRnopc:$Rn, imm0_31:$lsb, imm1_32:$width),
  3379. AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
  3380. "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
  3381. Requires<[IsARM, HasV6T2]> {
  3382. bits<4> Rd;
  3383. bits<4> Rn;
  3384. bits<5> lsb;
  3385. bits<5> width;
  3386. let Inst{27-21} = 0b0111111;
  3387. let Inst{6-4} = 0b101;
  3388. let Inst{20-16} = width;
  3389. let Inst{15-12} = Rd;
  3390. let Inst{11-7} = lsb;
  3391. let Inst{3-0} = Rn;
  3392. }
  3393. //===----------------------------------------------------------------------===//
  3394. // Arithmetic Instructions.
  3395. //
  3396. let isAdd = 1 in
  3397. defm ADD : AsI1_bin_irs<0b0100, "add",
  3398. IIC_iALUi, IIC_iALUr, IIC_iALUsr, add, 1>;
  3399. defm SUB : AsI1_bin_irs<0b0010, "sub",
  3400. IIC_iALUi, IIC_iALUr, IIC_iALUsr, sub>;
  3401. // ADD and SUB with 's' bit set.
  3402. //
  3403. // Currently, ADDS/SUBS are pseudo opcodes that exist only in the
  3404. // selection DAG. They are "lowered" to real ADD/SUB opcodes by
  3405. // AdjustInstrPostInstrSelection where we determine whether or not to
  3406. // set the "s" bit based on CPSR liveness.
  3407. //
  3408. // FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen
  3409. // support for an optional CPSR definition that corresponds to the DAG
  3410. // node's second value. We can then eliminate the implicit def of CPSR.
  3411. let isAdd = 1 in
  3412. defm ADDS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, ARMaddc, 1>;
  3413. defm SUBS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, ARMsubc>;
  3414. def : ARMPat<(ARMsubs GPR:$Rn, mod_imm:$imm), (SUBSri $Rn, mod_imm:$imm)>;
  3415. def : ARMPat<(ARMsubs GPR:$Rn, GPR:$Rm), (SUBSrr $Rn, $Rm)>;
  3416. def : ARMPat<(ARMsubs GPR:$Rn, so_reg_imm:$shift),
  3417. (SUBSrsi $Rn, so_reg_imm:$shift)>;
  3418. def : ARMPat<(ARMsubs GPR:$Rn, so_reg_reg:$shift),
  3419. (SUBSrsr $Rn, so_reg_reg:$shift)>;
  3420. let isAdd = 1 in
  3421. defm ADC : AI1_adde_sube_irs<0b0101, "adc", ARMadde, 1>;
  3422. defm SBC : AI1_adde_sube_irs<0b0110, "sbc", ARMsube>;
  3423. defm RSB : AsI1_rbin_irs<0b0011, "rsb",
  3424. IIC_iALUi, IIC_iALUr, IIC_iALUsr,
  3425. sub>;
  3426. // FIXME: Eliminate them if we can write def : Pat patterns which defines
  3427. // CPSR and the implicit def of CPSR is not needed.
  3428. defm RSBS : AsI1_rbin_s_is<IIC_iALUi, IIC_iALUsr, ARMsubc>;
  3429. defm RSC : AI1_rsc_irs<0b0111, "rsc", ARMsube>;
  3430. // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
  3431. // The assume-no-carry-in form uses the negation of the input since add/sub
  3432. // assume opposite meanings of the carry flag (i.e., carry == !borrow).
  3433. // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
  3434. // details.
  3435. def : ARMPat<(add GPR:$src, mod_imm_neg:$imm),
  3436. (SUBri GPR:$src, mod_imm_neg:$imm)>;
  3437. def : ARMPat<(ARMaddc GPR:$src, mod_imm_neg:$imm),
  3438. (SUBSri GPR:$src, mod_imm_neg:$imm)>;
  3439. def : ARMPat<(add GPR:$src, imm0_65535_neg:$imm),
  3440. (SUBrr GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>,
  3441. Requires<[IsARM, HasV6T2]>;
  3442. def : ARMPat<(ARMaddc GPR:$src, imm0_65535_neg:$imm),
  3443. (SUBSrr GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>,
  3444. Requires<[IsARM, HasV6T2]>;
  3445. // The with-carry-in form matches bitwise not instead of the negation.
  3446. // Effectively, the inverse interpretation of the carry flag already accounts
  3447. // for part of the negation.
  3448. def : ARMPat<(ARMadde GPR:$src, mod_imm_not:$imm, CPSR),
  3449. (SBCri GPR:$src, mod_imm_not:$imm)>;
  3450. def : ARMPat<(ARMadde GPR:$src, imm0_65535_neg:$imm, CPSR),
  3451. (SBCrr GPR:$src, (MOVi16 (imm_not_XFORM imm:$imm)))>,
  3452. Requires<[IsARM, HasV6T2]>;
  3453. // Note: These are implemented in C++ code, because they have to generate
  3454. // ADD/SUBrs instructions, which use a complex pattern that a xform function
  3455. // cannot produce.
  3456. // (mul X, 2^n+1) -> (add (X << n), X)
  3457. // (mul X, 2^n-1) -> (rsb X, (X << n))
  3458. // ARM Arithmetic Instruction
  3459. // GPR:$dst = GPR:$a op GPR:$b
  3460. class AAI<bits<8> op27_20, bits<8> op11_4, string opc,
  3461. list<dag> pattern = [],
  3462. dag iops = (ins GPRnopc:$Rn, GPRnopc:$Rm),
  3463. string asm = "\t$Rd, $Rn, $Rm">
  3464. : AI<(outs GPRnopc:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern>,
  3465. Sched<[WriteALU, ReadALU, ReadALU]> {
  3466. bits<4> Rn;
  3467. bits<4> Rd;
  3468. bits<4> Rm;
  3469. let Inst{27-20} = op27_20;
  3470. let Inst{11-4} = op11_4;
  3471. let Inst{19-16} = Rn;
  3472. let Inst{15-12} = Rd;
  3473. let Inst{3-0} = Rm;
  3474. let Unpredictable{11-8} = 0b1111;
  3475. }
  3476. // Wrappers around the AAI class
  3477. class AAIRevOpr<bits<8> op27_20, bits<8> op11_4, string opc,
  3478. list<dag> pattern = []>
  3479. : AAI<op27_20, op11_4, opc,
  3480. pattern,
  3481. (ins GPRnopc:$Rm, GPRnopc:$Rn),
  3482. "\t$Rd, $Rm, $Rn">;
  3483. class AAIIntrinsic<bits<8> op27_20, bits<8> op11_4, string opc,
  3484. Intrinsic intrinsic>
  3485. : AAI<op27_20, op11_4, opc,
  3486. [(set GPRnopc:$Rd, (intrinsic GPRnopc:$Rn, GPRnopc:$Rm))]>;
  3487. // Saturating add/subtract
  3488. let hasSideEffects = 1 in {
  3489. def QADD8 : AAIIntrinsic<0b01100010, 0b11111001, "qadd8", int_arm_qadd8>;
  3490. def QADD16 : AAIIntrinsic<0b01100010, 0b11110001, "qadd16", int_arm_qadd16>;
  3491. def QSUB16 : AAIIntrinsic<0b01100010, 0b11110111, "qsub16", int_arm_qsub16>;
  3492. def QSUB8 : AAIIntrinsic<0b01100010, 0b11111111, "qsub8", int_arm_qsub8>;
  3493. def QDADD : AAIRevOpr<0b00010100, 0b00000101, "qdadd",
  3494. [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm,
  3495. (int_arm_qadd GPRnopc:$Rn, GPRnopc:$Rn)))]>;
  3496. def QDSUB : AAIRevOpr<0b00010110, 0b00000101, "qdsub",
  3497. [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm,
  3498. (int_arm_qadd GPRnopc:$Rn, GPRnopc:$Rn)))]>;
  3499. def QSUB : AAIRevOpr<0b00010010, 0b00000101, "qsub",
  3500. [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm, GPRnopc:$Rn))]>;
  3501. let DecoderMethod = "DecodeQADDInstruction" in
  3502. def QADD : AAIRevOpr<0b00010000, 0b00000101, "qadd",
  3503. [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm, GPRnopc:$Rn))]>;
  3504. }
  3505. def : ARMV5TEPat<(saddsat GPR:$a, GPR:$b),
  3506. (QADD GPR:$a, GPR:$b)>;
  3507. def : ARMV5TEPat<(ssubsat GPR:$a, GPR:$b),
  3508. (QSUB GPR:$a, GPR:$b)>;
  3509. def : ARMV5TEPat<(saddsat rGPR:$Rm, (saddsat rGPR:$Rn, rGPR:$Rn)),
  3510. (QDADD rGPR:$Rm, rGPR:$Rn)>;
  3511. def : ARMV5TEPat<(ssubsat rGPR:$Rm, (saddsat rGPR:$Rn, rGPR:$Rn)),
  3512. (QDSUB rGPR:$Rm, rGPR:$Rn)>;
  3513. def : ARMV6Pat<(ARMqadd8b rGPR:$Rm, rGPR:$Rn),
  3514. (QADD8 rGPR:$Rm, rGPR:$Rn)>;
  3515. def : ARMV6Pat<(ARMqsub8b rGPR:$Rm, rGPR:$Rn),
  3516. (QSUB8 rGPR:$Rm, rGPR:$Rn)>;
  3517. def : ARMV6Pat<(ARMqadd16b rGPR:$Rm, rGPR:$Rn),
  3518. (QADD16 rGPR:$Rm, rGPR:$Rn)>;
  3519. def : ARMV6Pat<(ARMqsub16b rGPR:$Rm, rGPR:$Rn),
  3520. (QSUB16 rGPR:$Rm, rGPR:$Rn)>;
  3521. def UQADD16 : AAIIntrinsic<0b01100110, 0b11110001, "uqadd16", int_arm_uqadd16>;
  3522. def UQADD8 : AAIIntrinsic<0b01100110, 0b11111001, "uqadd8", int_arm_uqadd8>;
  3523. def UQSUB16 : AAIIntrinsic<0b01100110, 0b11110111, "uqsub16", int_arm_uqsub16>;
  3524. def UQSUB8 : AAIIntrinsic<0b01100110, 0b11111111, "uqsub8", int_arm_uqsub8>;
  3525. def QASX : AAIIntrinsic<0b01100010, 0b11110011, "qasx", int_arm_qasx>;
  3526. def QSAX : AAIIntrinsic<0b01100010, 0b11110101, "qsax", int_arm_qsax>;
  3527. def UQASX : AAIIntrinsic<0b01100110, 0b11110011, "uqasx", int_arm_uqasx>;
  3528. def UQSAX : AAIIntrinsic<0b01100110, 0b11110101, "uqsax", int_arm_uqsax>;
  3529. def : ARMV6Pat<(ARMuqadd8b rGPR:$Rm, rGPR:$Rn),
  3530. (UQADD8 rGPR:$Rm, rGPR:$Rn)>;
  3531. def : ARMV6Pat<(ARMuqsub8b rGPR:$Rm, rGPR:$Rn),
  3532. (UQSUB8 rGPR:$Rm, rGPR:$Rn)>;
  3533. def : ARMV6Pat<(ARMuqadd16b rGPR:$Rm, rGPR:$Rn),
  3534. (UQADD16 rGPR:$Rm, rGPR:$Rn)>;
  3535. def : ARMV6Pat<(ARMuqsub16b rGPR:$Rm, rGPR:$Rn),
  3536. (UQSUB16 rGPR:$Rm, rGPR:$Rn)>;
  3537. // Signed/Unsigned add/subtract
  3538. def SASX : AAIIntrinsic<0b01100001, 0b11110011, "sasx", int_arm_sasx>;
  3539. def SADD16 : AAIIntrinsic<0b01100001, 0b11110001, "sadd16", int_arm_sadd16>;
  3540. def SADD8 : AAIIntrinsic<0b01100001, 0b11111001, "sadd8", int_arm_sadd8>;
  3541. def SSAX : AAIIntrinsic<0b01100001, 0b11110101, "ssax", int_arm_ssax>;
  3542. def SSUB16 : AAIIntrinsic<0b01100001, 0b11110111, "ssub16", int_arm_ssub16>;
  3543. def SSUB8 : AAIIntrinsic<0b01100001, 0b11111111, "ssub8", int_arm_ssub8>;
  3544. def UASX : AAIIntrinsic<0b01100101, 0b11110011, "uasx", int_arm_uasx>;
  3545. def UADD16 : AAIIntrinsic<0b01100101, 0b11110001, "uadd16", int_arm_uadd16>;
  3546. def UADD8 : AAIIntrinsic<0b01100101, 0b11111001, "uadd8", int_arm_uadd8>;
  3547. def USAX : AAIIntrinsic<0b01100101, 0b11110101, "usax", int_arm_usax>;
  3548. def USUB16 : AAIIntrinsic<0b01100101, 0b11110111, "usub16", int_arm_usub16>;
  3549. def USUB8 : AAIIntrinsic<0b01100101, 0b11111111, "usub8", int_arm_usub8>;
  3550. // Signed/Unsigned halving add/subtract
  3551. def SHASX : AAIIntrinsic<0b01100011, 0b11110011, "shasx", int_arm_shasx>;
  3552. def SHADD16 : AAIIntrinsic<0b01100011, 0b11110001, "shadd16", int_arm_shadd16>;
  3553. def SHADD8 : AAIIntrinsic<0b01100011, 0b11111001, "shadd8", int_arm_shadd8>;
  3554. def SHSAX : AAIIntrinsic<0b01100011, 0b11110101, "shsax", int_arm_shsax>;
  3555. def SHSUB16 : AAIIntrinsic<0b01100011, 0b11110111, "shsub16", int_arm_shsub16>;
  3556. def SHSUB8 : AAIIntrinsic<0b01100011, 0b11111111, "shsub8", int_arm_shsub8>;
  3557. def UHASX : AAIIntrinsic<0b01100111, 0b11110011, "uhasx", int_arm_uhasx>;
  3558. def UHADD16 : AAIIntrinsic<0b01100111, 0b11110001, "uhadd16", int_arm_uhadd16>;
  3559. def UHADD8 : AAIIntrinsic<0b01100111, 0b11111001, "uhadd8", int_arm_uhadd8>;
  3560. def UHSAX : AAIIntrinsic<0b01100111, 0b11110101, "uhsax", int_arm_uhsax>;
  3561. def UHSUB16 : AAIIntrinsic<0b01100111, 0b11110111, "uhsub16", int_arm_uhsub16>;
  3562. def UHSUB8 : AAIIntrinsic<0b01100111, 0b11111111, "uhsub8", int_arm_uhsub8>;
  3563. // Unsigned Sum of Absolute Differences [and Accumulate].
  3564. def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
  3565. MulFrm /* for convenience */, NoItinerary, "usad8",
  3566. "\t$Rd, $Rn, $Rm",
  3567. [(set GPR:$Rd, (int_arm_usad8 GPR:$Rn, GPR:$Rm))]>,
  3568. Requires<[IsARM, HasV6]>, Sched<[WriteALU, ReadALU, ReadALU]> {
  3569. bits<4> Rd;
  3570. bits<4> Rn;
  3571. bits<4> Rm;
  3572. let Inst{27-20} = 0b01111000;
  3573. let Inst{15-12} = 0b1111;
  3574. let Inst{7-4} = 0b0001;
  3575. let Inst{19-16} = Rd;
  3576. let Inst{11-8} = Rm;
  3577. let Inst{3-0} = Rn;
  3578. }
  3579. def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
  3580. MulFrm /* for convenience */, NoItinerary, "usada8",
  3581. "\t$Rd, $Rn, $Rm, $Ra",
  3582. [(set GPR:$Rd, (int_arm_usada8 GPR:$Rn, GPR:$Rm, GPR:$Ra))]>,
  3583. Requires<[IsARM, HasV6]>, Sched<[WriteALU, ReadALU, ReadALU]>{
  3584. bits<4> Rd;
  3585. bits<4> Rn;
  3586. bits<4> Rm;
  3587. bits<4> Ra;
  3588. let Inst{27-20} = 0b01111000;
  3589. let Inst{7-4} = 0b0001;
  3590. let Inst{19-16} = Rd;
  3591. let Inst{15-12} = Ra;
  3592. let Inst{11-8} = Rm;
  3593. let Inst{3-0} = Rn;
  3594. }
  3595. // Signed/Unsigned saturate
  3596. def SSAT : AI<(outs GPRnopc:$Rd),
  3597. (ins imm1_32:$sat_imm, GPRnopc:$Rn, shift_imm:$sh),
  3598. SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []>,
  3599. Requires<[IsARM,HasV6]>{
  3600. bits<4> Rd;
  3601. bits<5> sat_imm;
  3602. bits<4> Rn;
  3603. bits<8> sh;
  3604. let Inst{27-21} = 0b0110101;
  3605. let Inst{5-4} = 0b01;
  3606. let Inst{20-16} = sat_imm;
  3607. let Inst{15-12} = Rd;
  3608. let Inst{11-7} = sh{4-0};
  3609. let Inst{6} = sh{5};
  3610. let Inst{3-0} = Rn;
  3611. }
  3612. def SSAT16 : AI<(outs GPRnopc:$Rd),
  3613. (ins imm1_16:$sat_imm, GPRnopc:$Rn), SatFrm,
  3614. NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []>,
  3615. Requires<[IsARM,HasV6]>{
  3616. bits<4> Rd;
  3617. bits<4> sat_imm;
  3618. bits<4> Rn;
  3619. let Inst{27-20} = 0b01101010;
  3620. let Inst{11-4} = 0b11110011;
  3621. let Inst{15-12} = Rd;
  3622. let Inst{19-16} = sat_imm;
  3623. let Inst{3-0} = Rn;
  3624. }
  3625. def USAT : AI<(outs GPRnopc:$Rd),
  3626. (ins imm0_31:$sat_imm, GPRnopc:$Rn, shift_imm:$sh),
  3627. SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []>,
  3628. Requires<[IsARM,HasV6]> {
  3629. bits<4> Rd;
  3630. bits<5> sat_imm;
  3631. bits<4> Rn;
  3632. bits<8> sh;
  3633. let Inst{27-21} = 0b0110111;
  3634. let Inst{5-4} = 0b01;
  3635. let Inst{15-12} = Rd;
  3636. let Inst{11-7} = sh{4-0};
  3637. let Inst{6} = sh{5};
  3638. let Inst{20-16} = sat_imm;
  3639. let Inst{3-0} = Rn;
  3640. }
  3641. def USAT16 : AI<(outs GPRnopc:$Rd),
  3642. (ins imm0_15:$sat_imm, GPRnopc:$Rn), SatFrm,
  3643. NoItinerary, "usat16", "\t$Rd, $sat_imm, $Rn", []>,
  3644. Requires<[IsARM,HasV6]>{
  3645. bits<4> Rd;
  3646. bits<4> sat_imm;
  3647. bits<4> Rn;
  3648. let Inst{27-20} = 0b01101110;
  3649. let Inst{11-4} = 0b11110011;
  3650. let Inst{15-12} = Rd;
  3651. let Inst{19-16} = sat_imm;
  3652. let Inst{3-0} = Rn;
  3653. }
  3654. def : ARMV6Pat<(int_arm_ssat GPRnopc:$a, imm1_32:$pos),
  3655. (SSAT imm1_32:$pos, GPRnopc:$a, 0)>;
  3656. def : ARMV6Pat<(int_arm_usat GPRnopc:$a, imm0_31:$pos),
  3657. (USAT imm0_31:$pos, GPRnopc:$a, 0)>;
  3658. def : ARMPat<(ARMssat GPRnopc:$Rn, imm0_31:$imm),
  3659. (SSAT imm0_31:$imm, GPRnopc:$Rn, 0)>;
  3660. def : ARMPat<(ARMusat GPRnopc:$Rn, imm0_31:$imm),
  3661. (USAT imm0_31:$imm, GPRnopc:$Rn, 0)>;
  3662. def : ARMV6Pat<(int_arm_ssat16 GPRnopc:$a, imm1_16:$pos),
  3663. (SSAT16 imm1_16:$pos, GPRnopc:$a)>;
  3664. def : ARMV6Pat<(int_arm_usat16 GPRnopc:$a, imm0_15:$pos),
  3665. (USAT16 imm0_15:$pos, GPRnopc:$a)>;
  3666. def : ARMV6Pat<(int_arm_ssat (shl GPRnopc:$a, imm0_31:$shft), imm1_32:$pos),
  3667. (SSAT imm1_32:$pos, GPRnopc:$a, imm0_31:$shft)>;
  3668. def : ARMV6Pat<(int_arm_ssat (sra GPRnopc:$a, asr_imm:$shft), imm1_32:$pos),
  3669. (SSAT imm1_32:$pos, GPRnopc:$a, asr_imm:$shft)>;
  3670. def : ARMV6Pat<(int_arm_usat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos),
  3671. (USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>;
  3672. def : ARMV6Pat<(int_arm_usat (sra GPRnopc:$a, asr_imm:$shft), imm0_31:$pos),
  3673. (USAT imm0_31:$pos, GPRnopc:$a, asr_imm:$shft)>;
  3674. def : ARMPat<(ARMssat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos),
  3675. (SSAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>;
  3676. def : ARMPat<(ARMssat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos),
  3677. (SSAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>;
  3678. def : ARMPat<(ARMusat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos),
  3679. (USAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>;
  3680. def : ARMPat<(ARMusat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos),
  3681. (USAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>;
  3682. //===----------------------------------------------------------------------===//
  3683. // Bitwise Instructions.
  3684. //
  3685. defm AND : AsI1_bin_irs<0b0000, "and",
  3686. IIC_iBITi, IIC_iBITr, IIC_iBITsr, and, 1>;
  3687. defm ORR : AsI1_bin_irs<0b1100, "orr",
  3688. IIC_iBITi, IIC_iBITr, IIC_iBITsr, or, 1>;
  3689. defm EOR : AsI1_bin_irs<0b0001, "eor",
  3690. IIC_iBITi, IIC_iBITr, IIC_iBITsr, xor, 1>;
  3691. defm BIC : AsI1_bin_irs<0b1110, "bic",
  3692. IIC_iBITi, IIC_iBITr, IIC_iBITsr,
  3693. BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
  3694. // FIXME: bf_inv_mask_imm should be two operands, the lsb and the msb, just
  3695. // like in the actual instruction encoding. The complexity of mapping the mask
  3696. // to the lsb/msb pair should be handled by ISel, not encapsulated in the
  3697. // instruction description.
  3698. def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
  3699. AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
  3700. "bfc", "\t$Rd, $imm", "$src = $Rd",
  3701. [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
  3702. Requires<[IsARM, HasV6T2]> {
  3703. bits<4> Rd;
  3704. bits<10> imm;
  3705. let Inst{27-21} = 0b0111110;
  3706. let Inst{6-0} = 0b0011111;
  3707. let Inst{15-12} = Rd;
  3708. let Inst{11-7} = imm{4-0}; // lsb
  3709. let Inst{20-16} = imm{9-5}; // msb
  3710. }
  3711. // A8.6.18 BFI - Bitfield insert (Encoding A1)
  3712. def BFI:I<(outs GPRnopc:$Rd), (ins GPRnopc:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
  3713. AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
  3714. "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd",
  3715. [(set GPRnopc:$Rd, (ARMbfi GPRnopc:$src, GPR:$Rn,
  3716. bf_inv_mask_imm:$imm))]>,
  3717. Requires<[IsARM, HasV6T2]> {
  3718. bits<4> Rd;
  3719. bits<4> Rn;
  3720. bits<10> imm;
  3721. let Inst{27-21} = 0b0111110;
  3722. let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
  3723. let Inst{15-12} = Rd;
  3724. let Inst{11-7} = imm{4-0}; // lsb
  3725. let Inst{20-16} = imm{9-5}; // width
  3726. let Inst{3-0} = Rn;
  3727. }
  3728. def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
  3729. "mvn", "\t$Rd, $Rm",
  3730. [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP, Sched<[WriteALU]> {
  3731. bits<4> Rd;
  3732. bits<4> Rm;
  3733. let Inst{25} = 0;
  3734. let Inst{19-16} = 0b0000;
  3735. let Inst{11-4} = 0b00000000;
  3736. let Inst{15-12} = Rd;
  3737. let Inst{3-0} = Rm;
  3738. let Unpredictable{19-16} = 0b1111;
  3739. }
  3740. def MVNsi : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift),
  3741. DPSoRegImmFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift",
  3742. [(set GPR:$Rd, (not so_reg_imm:$shift))]>, UnaryDP,
  3743. Sched<[WriteALU]> {
  3744. bits<4> Rd;
  3745. bits<12> shift;
  3746. let Inst{25} = 0;
  3747. let Inst{19-16} = 0b0000;
  3748. let Inst{15-12} = Rd;
  3749. let Inst{11-5} = shift{11-5};
  3750. let Inst{4} = 0;
  3751. let Inst{3-0} = shift{3-0};
  3752. let Unpredictable{19-16} = 0b1111;
  3753. }
  3754. def MVNsr : AsI1<0b1111, (outs GPRnopc:$Rd), (ins so_reg_reg:$shift),
  3755. DPSoRegRegFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift",
  3756. [(set GPRnopc:$Rd, (not so_reg_reg:$shift))]>, UnaryDP,
  3757. Sched<[WriteALU]> {
  3758. bits<4> Rd;
  3759. bits<12> shift;
  3760. let Inst{25} = 0;
  3761. let Inst{19-16} = 0b0000;
  3762. let Inst{15-12} = Rd;
  3763. let Inst{11-8} = shift{11-8};
  3764. let Inst{7} = 0;
  3765. let Inst{6-5} = shift{6-5};
  3766. let Inst{4} = 1;
  3767. let Inst{3-0} = shift{3-0};
  3768. let Unpredictable{19-16} = 0b1111;
  3769. }
  3770. let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
  3771. def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins mod_imm:$imm), DPFrm,
  3772. IIC_iMVNi, "mvn", "\t$Rd, $imm",
  3773. [(set GPR:$Rd, mod_imm_not:$imm)]>,UnaryDP, Sched<[WriteALU]> {
  3774. bits<4> Rd;
  3775. bits<12> imm;
  3776. let Inst{25} = 1;
  3777. let Inst{19-16} = 0b0000;
  3778. let Inst{15-12} = Rd;
  3779. let Inst{11-0} = imm;
  3780. }
  3781. let AddedComplexity = 1 in
  3782. def : ARMPat<(and GPR:$src, mod_imm_not:$imm),
  3783. (BICri GPR:$src, mod_imm_not:$imm)>;
  3784. //===----------------------------------------------------------------------===//
  3785. // Multiply Instructions.
  3786. //
  3787. class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
  3788. string opc, string asm, list<dag> pattern>
  3789. : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
  3790. bits<4> Rd;
  3791. bits<4> Rm;
  3792. bits<4> Rn;
  3793. let Inst{19-16} = Rd;
  3794. let Inst{11-8} = Rm;
  3795. let Inst{3-0} = Rn;
  3796. }
  3797. class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
  3798. string opc, string asm, list<dag> pattern>
  3799. : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
  3800. bits<4> RdLo;
  3801. bits<4> RdHi;
  3802. bits<4> Rm;
  3803. bits<4> Rn;
  3804. let Inst{19-16} = RdHi;
  3805. let Inst{15-12} = RdLo;
  3806. let Inst{11-8} = Rm;
  3807. let Inst{3-0} = Rn;
  3808. }
  3809. class AsMla1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
  3810. string opc, string asm, list<dag> pattern>
  3811. : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> {
  3812. bits<4> RdLo;
  3813. bits<4> RdHi;
  3814. bits<4> Rm;
  3815. bits<4> Rn;
  3816. let Inst{19-16} = RdHi;
  3817. let Inst{15-12} = RdLo;
  3818. let Inst{11-8} = Rm;
  3819. let Inst{3-0} = Rn;
  3820. }
  3821. // FIXME: The v5 pseudos are only necessary for the additional Constraint
  3822. // property. Remove them when it's possible to add those properties
  3823. // on an individual MachineInstr, not just an instruction description.
  3824. let isCommutable = 1, TwoOperandAliasConstraint = "$Rn = $Rd" in {
  3825. def MUL : AsMul1I32<0b0000000, (outs GPRnopc:$Rd),
  3826. (ins GPRnopc:$Rn, GPRnopc:$Rm),
  3827. IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
  3828. [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))]>,
  3829. Requires<[IsARM, HasV6]>,
  3830. Sched<[WriteMUL32, ReadMUL, ReadMUL]> {
  3831. let Inst{15-12} = 0b0000;
  3832. let Unpredictable{15-12} = 0b1111;
  3833. }
  3834. let Constraints = "@earlyclobber $Rd" in
  3835. def MULv5: ARMPseudoExpand<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm,
  3836. pred:$p, cc_out:$s),
  3837. 4, IIC_iMUL32,
  3838. [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))],
  3839. (MUL GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, cc_out:$s)>,
  3840. Requires<[IsARM, NoV6, UseMulOps]>,
  3841. Sched<[WriteMUL32, ReadMUL, ReadMUL]>;
  3842. }
  3843. def MLA : AsMul1I32<0b0000001, (outs GPRnopc:$Rd),
  3844. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra),
  3845. IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
  3846. [(set GPRnopc:$Rd, (add (mul GPRnopc:$Rn, GPRnopc:$Rm), GPRnopc:$Ra))]>,
  3847. Requires<[IsARM, HasV6, UseMulOps]>,
  3848. Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]> {
  3849. bits<4> Ra;
  3850. let Inst{15-12} = Ra;
  3851. }
  3852. let Constraints = "@earlyclobber $Rd" in
  3853. def MLAv5: ARMPseudoExpand<(outs GPRnopc:$Rd),
  3854. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra,
  3855. pred:$p, cc_out:$s), 4, IIC_iMAC32,
  3856. [(set GPRnopc:$Rd, (add (mul GPRnopc:$Rn, GPRnopc:$Rm), GPRnopc:$Ra))],
  3857. (MLA GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra, pred:$p, cc_out:$s)>,
  3858. Requires<[IsARM, NoV6]>,
  3859. Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>;
  3860. def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
  3861. IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
  3862. [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
  3863. Requires<[IsARM, HasV6T2, UseMulOps]>,
  3864. Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]> {
  3865. bits<4> Rd;
  3866. bits<4> Rm;
  3867. bits<4> Rn;
  3868. bits<4> Ra;
  3869. let Inst{19-16} = Rd;
  3870. let Inst{15-12} = Ra;
  3871. let Inst{11-8} = Rm;
  3872. let Inst{3-0} = Rn;
  3873. }
  3874. // Extra precision multiplies with low / high results
  3875. let hasSideEffects = 0 in {
  3876. let isCommutable = 1 in {
  3877. def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
  3878. (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
  3879. "smull", "\t$RdLo, $RdHi, $Rn, $Rm",
  3880. [(set GPR:$RdLo, GPR:$RdHi,
  3881. (smullohi GPR:$Rn, GPR:$Rm))]>,
  3882. Requires<[IsARM, HasV6]>,
  3883. Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>;
  3884. def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
  3885. (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
  3886. "umull", "\t$RdLo, $RdHi, $Rn, $Rm",
  3887. [(set GPR:$RdLo, GPR:$RdHi,
  3888. (umullohi GPR:$Rn, GPR:$Rm))]>,
  3889. Requires<[IsARM, HasV6]>,
  3890. Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL]>;
  3891. let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
  3892. def SMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
  3893. (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
  3894. 4, IIC_iMUL64,
  3895. [(set GPR:$RdLo, GPR:$RdHi,
  3896. (smullohi GPR:$Rn, GPR:$Rm))],
  3897. (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
  3898. Requires<[IsARM, NoV6]>,
  3899. Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>;
  3900. def UMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
  3901. (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
  3902. 4, IIC_iMUL64,
  3903. [(set GPR:$RdLo, GPR:$RdHi,
  3904. (umullohi GPR:$Rn, GPR:$Rm))],
  3905. (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
  3906. Requires<[IsARM, NoV6]>,
  3907. Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>;
  3908. }
  3909. }
  3910. // Multiply + accumulate
  3911. def SMLAL : AsMla1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
  3912. (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), IIC_iMAC64,
  3913. "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
  3914. RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>,
  3915. Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>;
  3916. def UMLAL : AsMla1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
  3917. (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), IIC_iMAC64,
  3918. "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
  3919. RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>,
  3920. Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>;
  3921. def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
  3922. (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi),
  3923. IIC_iMAC64,
  3924. "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
  3925. RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>,
  3926. Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]> {
  3927. bits<4> RdLo;
  3928. bits<4> RdHi;
  3929. bits<4> Rm;
  3930. bits<4> Rn;
  3931. let Inst{19-16} = RdHi;
  3932. let Inst{15-12} = RdLo;
  3933. let Inst{11-8} = Rm;
  3934. let Inst{3-0} = Rn;
  3935. }
  3936. let Constraints =
  3937. "@earlyclobber $RdLo,@earlyclobber $RdHi,$RLo = $RdLo,$RHi = $RdHi" in {
  3938. def SMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
  3939. (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, pred:$p, cc_out:$s),
  3940. 4, IIC_iMAC64, [],
  3941. (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi,
  3942. pred:$p, cc_out:$s)>,
  3943. Requires<[IsARM, NoV6]>,
  3944. Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>;
  3945. def UMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
  3946. (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, pred:$p, cc_out:$s),
  3947. 4, IIC_iMAC64, [],
  3948. (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi,
  3949. pred:$p, cc_out:$s)>,
  3950. Requires<[IsARM, NoV6]>,
  3951. Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>;
  3952. }
  3953. } // hasSideEffects
  3954. // Most significant word multiply
  3955. def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
  3956. IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm",
  3957. [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>,
  3958. Requires<[IsARM, HasV6]>,
  3959. Sched<[WriteMUL32, ReadMUL, ReadMUL]> {
  3960. let Inst{15-12} = 0b1111;
  3961. }
  3962. def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
  3963. IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm",
  3964. [(set GPR:$Rd, (ARMsmmlar GPR:$Rn, GPR:$Rm, (i32 0)))]>,
  3965. Requires<[IsARM, HasV6]>,
  3966. Sched<[WriteMUL32, ReadMUL, ReadMUL]> {
  3967. let Inst{15-12} = 0b1111;
  3968. }
  3969. def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd),
  3970. (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
  3971. IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra",
  3972. [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
  3973. Requires<[IsARM, HasV6, UseMulOps]>,
  3974. Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>;
  3975. def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd),
  3976. (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
  3977. IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra",
  3978. [(set GPR:$Rd, (ARMsmmlar GPR:$Rn, GPR:$Rm, GPR:$Ra))]>,
  3979. Requires<[IsARM, HasV6]>,
  3980. Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>;
  3981. def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd),
  3982. (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
  3983. IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra", []>,
  3984. Requires<[IsARM, HasV6, UseMulOps]>,
  3985. Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>;
  3986. def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
  3987. (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
  3988. IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra",
  3989. [(set GPR:$Rd, (ARMsmmlsr GPR:$Rn, GPR:$Rm, GPR:$Ra))]>,
  3990. Requires<[IsARM, HasV6]>,
  3991. Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>;
  3992. multiclass AI_smul<string opc> {
  3993. def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
  3994. IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
  3995. [(set GPR:$Rd, (bb_mul GPR:$Rn, GPR:$Rm))]>,
  3996. Requires<[IsARM, HasV5TE]>,
  3997. Sched<[WriteMUL16, ReadMUL, ReadMUL]>;
  3998. def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
  3999. IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
  4000. [(set GPR:$Rd, (bt_mul GPR:$Rn, GPR:$Rm))]>,
  4001. Requires<[IsARM, HasV5TE]>,
  4002. Sched<[WriteMUL16, ReadMUL, ReadMUL]>;
  4003. def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
  4004. IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
  4005. [(set GPR:$Rd, (tb_mul GPR:$Rn, GPR:$Rm))]>,
  4006. Requires<[IsARM, HasV5TE]>,
  4007. Sched<[WriteMUL16, ReadMUL, ReadMUL]>;
  4008. def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
  4009. IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
  4010. [(set GPR:$Rd, (tt_mul GPR:$Rn, GPR:$Rm))]>,
  4011. Requires<[IsARM, HasV5TE]>,
  4012. Sched<[WriteMUL16, ReadMUL, ReadMUL]>;
  4013. def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
  4014. IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
  4015. [(set GPR:$Rd, (ARMsmulwb GPR:$Rn, GPR:$Rm))]>,
  4016. Requires<[IsARM, HasV5TE]>,
  4017. Sched<[WriteMUL16, ReadMUL, ReadMUL]>;
  4018. def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
  4019. IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
  4020. [(set GPR:$Rd, (ARMsmulwt GPR:$Rn, GPR:$Rm))]>,
  4021. Requires<[IsARM, HasV5TE]>,
  4022. Sched<[WriteMUL16, ReadMUL, ReadMUL]>;
  4023. }
  4024. multiclass AI_smla<string opc> {
  4025. let DecoderMethod = "DecodeSMLAInstruction" in {
  4026. def BB : AMulxyIa<0b0001000, 0b00, (outs GPRnopc:$Rd),
  4027. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4028. IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
  4029. [(set GPRnopc:$Rd, (add GPR:$Ra,
  4030. (bb_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>,
  4031. Requires<[IsARM, HasV5TE, UseMulOps]>,
  4032. Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>;
  4033. def BT : AMulxyIa<0b0001000, 0b10, (outs GPRnopc:$Rd),
  4034. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4035. IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
  4036. [(set GPRnopc:$Rd, (add GPR:$Ra,
  4037. (bt_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>,
  4038. Requires<[IsARM, HasV5TE, UseMulOps]>,
  4039. Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>;
  4040. def TB : AMulxyIa<0b0001000, 0b01, (outs GPRnopc:$Rd),
  4041. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4042. IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
  4043. [(set GPRnopc:$Rd, (add GPR:$Ra,
  4044. (tb_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>,
  4045. Requires<[IsARM, HasV5TE, UseMulOps]>,
  4046. Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>;
  4047. def TT : AMulxyIa<0b0001000, 0b11, (outs GPRnopc:$Rd),
  4048. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4049. IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
  4050. [(set GPRnopc:$Rd, (add GPR:$Ra,
  4051. (tt_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>,
  4052. Requires<[IsARM, HasV5TE, UseMulOps]>,
  4053. Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>;
  4054. def WB : AMulxyIa<0b0001001, 0b00, (outs GPRnopc:$Rd),
  4055. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4056. IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
  4057. [(set GPRnopc:$Rd,
  4058. (add GPR:$Ra, (ARMsmulwb GPRnopc:$Rn, GPRnopc:$Rm)))]>,
  4059. Requires<[IsARM, HasV5TE, UseMulOps]>,
  4060. Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>;
  4061. def WT : AMulxyIa<0b0001001, 0b10, (outs GPRnopc:$Rd),
  4062. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4063. IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
  4064. [(set GPRnopc:$Rd,
  4065. (add GPR:$Ra, (ARMsmulwt GPRnopc:$Rn, GPRnopc:$Rm)))]>,
  4066. Requires<[IsARM, HasV5TE, UseMulOps]>,
  4067. Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>;
  4068. }
  4069. }
  4070. defm SMUL : AI_smul<"smul">;
  4071. defm SMLA : AI_smla<"smla">;
  4072. // Halfword multiply accumulate long: SMLAL<x><y>.
  4073. class SMLAL<bits<2> opc1, string asm>
  4074. : AMulxyI64<0b0001010, opc1,
  4075. (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
  4076. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi),
  4077. IIC_iMAC64, asm, "\t$RdLo, $RdHi, $Rn, $Rm", []>,
  4078. RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">,
  4079. Requires<[IsARM, HasV5TE]>,
  4080. Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>;
  4081. def SMLALBB : SMLAL<0b00, "smlalbb">;
  4082. def SMLALBT : SMLAL<0b10, "smlalbt">;
  4083. def SMLALTB : SMLAL<0b01, "smlaltb">;
  4084. def SMLALTT : SMLAL<0b11, "smlaltt">;
  4085. def : ARMV5TEPat<(ARMsmlalbb GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi),
  4086. (SMLALBB $Rn, $Rm, $RLo, $RHi)>;
  4087. def : ARMV5TEPat<(ARMsmlalbt GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi),
  4088. (SMLALBT $Rn, $Rm, $RLo, $RHi)>;
  4089. def : ARMV5TEPat<(ARMsmlaltb GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi),
  4090. (SMLALTB $Rn, $Rm, $RLo, $RHi)>;
  4091. def : ARMV5TEPat<(ARMsmlaltt GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi),
  4092. (SMLALTT $Rn, $Rm, $RLo, $RHi)>;
  4093. // Helper class for AI_smld.
  4094. class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops,
  4095. InstrItinClass itin, string opc, string asm>
  4096. : AI<oops, iops, MulFrm, itin, opc, asm, []>,
  4097. Requires<[IsARM, HasV6]> {
  4098. bits<4> Rn;
  4099. bits<4> Rm;
  4100. let Inst{27-23} = 0b01110;
  4101. let Inst{22} = long;
  4102. let Inst{21-20} = 0b00;
  4103. let Inst{11-8} = Rm;
  4104. let Inst{7} = 0;
  4105. let Inst{6} = sub;
  4106. let Inst{5} = swap;
  4107. let Inst{4} = 1;
  4108. let Inst{3-0} = Rn;
  4109. }
  4110. class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
  4111. InstrItinClass itin, string opc, string asm>
  4112. : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
  4113. bits<4> Rd;
  4114. let Inst{15-12} = 0b1111;
  4115. let Inst{19-16} = Rd;
  4116. }
  4117. class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops,
  4118. InstrItinClass itin, string opc, string asm>
  4119. : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
  4120. bits<4> Ra;
  4121. bits<4> Rd;
  4122. let Inst{19-16} = Rd;
  4123. let Inst{15-12} = Ra;
  4124. }
  4125. class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops,
  4126. InstrItinClass itin, string opc, string asm>
  4127. : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> {
  4128. bits<4> RdLo;
  4129. bits<4> RdHi;
  4130. let Inst{19-16} = RdHi;
  4131. let Inst{15-12} = RdLo;
  4132. }
  4133. multiclass AI_smld<bit sub, string opc> {
  4134. def D : AMulDualIa<0, sub, 0, (outs GPRnopc:$Rd),
  4135. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4136. NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">,
  4137. Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>;
  4138. def DX: AMulDualIa<0, sub, 1, (outs GPRnopc:$Rd),
  4139. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4140. NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">,
  4141. Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>;
  4142. def LD: AMulDualI64<1, sub, 0, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
  4143. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi),
  4144. NoItinerary,
  4145. !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">,
  4146. RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">,
  4147. Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>;
  4148. def LDX : AMulDualI64<1, sub, 1, (outs GPRnopc:$RdLo, GPRnopc:$RdHi),
  4149. (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi),
  4150. NoItinerary,
  4151. !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">,
  4152. RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">,
  4153. Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>;
  4154. }
  4155. defm SMLA : AI_smld<0, "smla">;
  4156. defm SMLS : AI_smld<1, "smls">;
  4157. def : ARMV6Pat<(int_arm_smlad GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4158. (SMLAD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>;
  4159. def : ARMV6Pat<(int_arm_smladx GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4160. (SMLADX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>;
  4161. def : ARMV6Pat<(int_arm_smlsd GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4162. (SMLSD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>;
  4163. def : ARMV6Pat<(int_arm_smlsdx GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra),
  4164. (SMLSDX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>;
  4165. def : ARMV6Pat<(ARMSmlald GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi),
  4166. (SMLALD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>;
  4167. def : ARMV6Pat<(ARMSmlaldx GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi),
  4168. (SMLALDX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>;
  4169. def : ARMV6Pat<(ARMSmlsld GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi),
  4170. (SMLSLD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>;
  4171. def : ARMV6Pat<(ARMSmlsldx GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi),
  4172. (SMLSLDX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>;
  4173. multiclass AI_sdml<bit sub, string opc> {
  4174. def D:AMulDualI<0, sub, 0, (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm),
  4175. NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">,
  4176. Sched<[WriteMUL32, ReadMUL, ReadMUL]>;
  4177. def DX:AMulDualI<0, sub, 1, (outs GPRnopc:$Rd),(ins GPRnopc:$Rn, GPRnopc:$Rm),
  4178. NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">,
  4179. Sched<[WriteMUL32, ReadMUL, ReadMUL]>;
  4180. }
  4181. defm SMUA : AI_sdml<0, "smua">;
  4182. defm SMUS : AI_sdml<1, "smus">;
  4183. def : ARMV6Pat<(int_arm_smuad GPRnopc:$Rn, GPRnopc:$Rm),
  4184. (SMUAD GPRnopc:$Rn, GPRnopc:$Rm)>;
  4185. def : ARMV6Pat<(int_arm_smuadx GPRnopc:$Rn, GPRnopc:$Rm),
  4186. (SMUADX GPRnopc:$Rn, GPRnopc:$Rm)>;
  4187. def : ARMV6Pat<(int_arm_smusd GPRnopc:$Rn, GPRnopc:$Rm),
  4188. (SMUSD GPRnopc:$Rn, GPRnopc:$Rm)>;
  4189. def : ARMV6Pat<(int_arm_smusdx GPRnopc:$Rn, GPRnopc:$Rm),
  4190. (SMUSDX GPRnopc:$Rn, GPRnopc:$Rm)>;
  4191. //===----------------------------------------------------------------------===//
  4192. // Division Instructions (ARMv7-A with virtualization extension)
  4193. //
  4194. def SDIV : ADivA1I<0b001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), IIC_iDIV,
  4195. "sdiv", "\t$Rd, $Rn, $Rm",
  4196. [(set GPR:$Rd, (sdiv GPR:$Rn, GPR:$Rm))]>,
  4197. Requires<[IsARM, HasDivideInARM]>,
  4198. Sched<[WriteDIV]>;
  4199. def UDIV : ADivA1I<0b011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), IIC_iDIV,
  4200. "udiv", "\t$Rd, $Rn, $Rm",
  4201. [(set GPR:$Rd, (udiv GPR:$Rn, GPR:$Rm))]>,
  4202. Requires<[IsARM, HasDivideInARM]>,
  4203. Sched<[WriteDIV]>;
  4204. //===----------------------------------------------------------------------===//
  4205. // Misc. Arithmetic Instructions.
  4206. //
  4207. def CLZ : AMiscA1I<0b00010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
  4208. IIC_iUNAr, "clz", "\t$Rd, $Rm",
  4209. [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>,
  4210. Sched<[WriteALU]>;
  4211. def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
  4212. IIC_iUNAr, "rbit", "\t$Rd, $Rm",
  4213. [(set GPR:$Rd, (bitreverse GPR:$Rm))]>,
  4214. Requires<[IsARM, HasV6T2]>,
  4215. Sched<[WriteALU]>;
  4216. def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
  4217. IIC_iUNAr, "rev", "\t$Rd, $Rm",
  4218. [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>,
  4219. Sched<[WriteALU]>;
  4220. let AddedComplexity = 5 in
  4221. def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
  4222. IIC_iUNAr, "rev16", "\t$Rd, $Rm",
  4223. [(set GPR:$Rd, (rotr (bswap GPR:$Rm), (i32 16)))]>,
  4224. Requires<[IsARM, HasV6]>,
  4225. Sched<[WriteALU]>;
  4226. def : ARMV6Pat<(srl (bswap (extloadi16 addrmode3:$addr)), (i32 16)),
  4227. (REV16 (LDRH addrmode3:$addr))>;
  4228. def : ARMV6Pat<(truncstorei16 (srl (bswap GPR:$Rn), (i32 16)), addrmode3:$addr),
  4229. (STRH (REV16 GPR:$Rn), addrmode3:$addr)>;
  4230. def : ARMV6Pat<(srl (bswap top16Zero:$Rn), (i32 16)),
  4231. (REV16 GPR:$Rn)>;
  4232. let AddedComplexity = 5 in
  4233. def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
  4234. IIC_iUNAr, "revsh", "\t$Rd, $Rm",
  4235. [(set GPR:$Rd, (sra (bswap GPR:$Rm), (i32 16)))]>,
  4236. Requires<[IsARM, HasV6]>,
  4237. Sched<[WriteALU]>;
  4238. def : ARMV6Pat<(or (sra (shl GPR:$Rm, (i32 24)), (i32 16)),
  4239. (and (srl GPR:$Rm, (i32 8)), 0xFF)),
  4240. (REVSH GPR:$Rm)>;
  4241. def PKHBT : APKHI<0b01101000, 0, (outs GPRnopc:$Rd),
  4242. (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_lsl_amt:$sh),
  4243. IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
  4244. [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF),
  4245. (and (shl GPRnopc:$Rm, pkh_lsl_amt:$sh),
  4246. 0xFFFF0000)))]>,
  4247. Requires<[IsARM, HasV6]>,
  4248. Sched<[WriteALUsi, ReadALU]>;
  4249. // Alternate cases for PKHBT where identities eliminate some nodes.
  4250. def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (and GPRnopc:$Rm, 0xFFFF0000)),
  4251. (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, 0)>;
  4252. def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (shl GPRnopc:$Rm, imm16_31:$sh)),
  4253. (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, imm16_31:$sh)>;
  4254. // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
  4255. // will match the pattern below.
  4256. def PKHTB : APKHI<0b01101000, 1, (outs GPRnopc:$Rd),
  4257. (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_asr_amt:$sh),
  4258. IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
  4259. [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF0000),
  4260. (and (sra GPRnopc:$Rm, pkh_asr_amt:$sh),
  4261. 0xFFFF)))]>,
  4262. Requires<[IsARM, HasV6]>,
  4263. Sched<[WriteALUsi, ReadALU]>;
  4264. // Alternate cases for PKHTB where identities eliminate some nodes. Note that
  4265. // a shift amount of 0 is *not legal* here, it is PKHBT instead.
  4266. // We also can not replace a srl (17..31) by an arithmetic shift we would use in
  4267. // pkhtb src1, src2, asr (17..31).
  4268. def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000),
  4269. (srl GPRnopc:$src2, imm16:$sh)),
  4270. (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16:$sh)>;
  4271. def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000),
  4272. (sra GPRnopc:$src2, imm16_31:$sh)),
  4273. (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16_31:$sh)>;
  4274. def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000),
  4275. (and (srl GPRnopc:$src2, imm1_15:$sh), 0xFFFF)),
  4276. (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm1_15:$sh)>;
  4277. //===----------------------------------------------------------------------===//
  4278. // CRC Instructions
  4279. //
  4280. // Polynomials:
  4281. // + CRC32{B,H,W} 0x04C11DB7
  4282. // + CRC32C{B,H,W} 0x1EDC6F41
  4283. //
  4284. class AI_crc32<bit C, bits<2> sz, string suffix, SDPatternOperator builtin>
  4285. : AInoP<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm), MiscFrm, NoItinerary,
  4286. !strconcat("crc32", suffix), "\t$Rd, $Rn, $Rm",
  4287. [(set GPRnopc:$Rd, (builtin GPRnopc:$Rn, GPRnopc:$Rm))]>,
  4288. Requires<[IsARM, HasV8, HasCRC]> {
  4289. bits<4> Rd;
  4290. bits<4> Rn;
  4291. bits<4> Rm;
  4292. let Inst{31-28} = 0b1110;
  4293. let Inst{27-23} = 0b00010;
  4294. let Inst{22-21} = sz;
  4295. let Inst{20} = 0;
  4296. let Inst{19-16} = Rn;
  4297. let Inst{15-12} = Rd;
  4298. let Inst{11-10} = 0b00;
  4299. let Inst{9} = C;
  4300. let Inst{8} = 0;
  4301. let Inst{7-4} = 0b0100;
  4302. let Inst{3-0} = Rm;
  4303. let Unpredictable{11-8} = 0b1101;
  4304. }
  4305. def CRC32B : AI_crc32<0, 0b00, "b", int_arm_crc32b>;
  4306. def CRC32CB : AI_crc32<1, 0b00, "cb", int_arm_crc32cb>;
  4307. def CRC32H : AI_crc32<0, 0b01, "h", int_arm_crc32h>;
  4308. def CRC32CH : AI_crc32<1, 0b01, "ch", int_arm_crc32ch>;
  4309. def CRC32W : AI_crc32<0, 0b10, "w", int_arm_crc32w>;
  4310. def CRC32CW : AI_crc32<1, 0b10, "cw", int_arm_crc32cw>;
  4311. //===----------------------------------------------------------------------===//
  4312. // ARMv8.1a Privilege Access Never extension
  4313. //
  4314. // SETPAN #imm1
  4315. def SETPAN : AInoP<(outs), (ins imm0_1:$imm), MiscFrm, NoItinerary, "setpan",
  4316. "\t$imm", []>, Requires<[IsARM, HasV8, HasV8_1a]> {
  4317. bits<1> imm;
  4318. let Inst{31-28} = 0b1111;
  4319. let Inst{27-20} = 0b00010001;
  4320. let Inst{19-16} = 0b0000;
  4321. let Inst{15-10} = 0b000000;
  4322. let Inst{9} = imm;
  4323. let Inst{8} = 0b0;
  4324. let Inst{7-4} = 0b0000;
  4325. let Inst{3-0} = 0b0000;
  4326. let Unpredictable{19-16} = 0b1111;
  4327. let Unpredictable{15-10} = 0b111111;
  4328. let Unpredictable{8} = 0b1;
  4329. let Unpredictable{3-0} = 0b1111;
  4330. }
  4331. //===----------------------------------------------------------------------===//
  4332. // Comparison Instructions...
  4333. //
  4334. defm CMP : AI1_cmp_irs<0b1010, "cmp",
  4335. IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr, ARMcmp>;
  4336. // ARMcmpZ can re-use the above instruction definitions.
  4337. def : ARMPat<(ARMcmpZ GPR:$src, mod_imm:$imm),
  4338. (CMPri GPR:$src, mod_imm:$imm)>;
  4339. def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
  4340. (CMPrr GPR:$src, GPR:$rhs)>;
  4341. def : ARMPat<(ARMcmpZ GPR:$src, so_reg_imm:$rhs),
  4342. (CMPrsi GPR:$src, so_reg_imm:$rhs)>;
  4343. def : ARMPat<(ARMcmpZ GPR:$src, so_reg_reg:$rhs),
  4344. (CMPrsr GPR:$src, so_reg_reg:$rhs)>;
  4345. // Following patterns aimed to prevent usage of CMPrsi and CMPrsr for a comparison
  4346. // with zero. Usage of CMPri in these cases helps to replace cmp with S-versions of
  4347. // shift instructions during peephole optimizations pass.
  4348. def : ARMPat<(ARMcmpZ so_reg_imm:$rhs, 0),
  4349. (CMPri (MOVsi so_reg_imm:$rhs), 0)>;
  4350. def : ARMPat<(ARMcmpZ so_reg_reg:$rhs, 0),
  4351. (CMPri (MOVsr so_reg_reg:$rhs), 0)>;
  4352. // CMN register-integer
  4353. let isCompare = 1, Defs = [CPSR] in {
  4354. def CMNri : AI1<0b1011, (outs), (ins GPR:$Rn, mod_imm:$imm), DPFrm, IIC_iCMPi,
  4355. "cmn", "\t$Rn, $imm",
  4356. [(ARMcmn GPR:$Rn, mod_imm:$imm)]>,
  4357. Sched<[WriteCMP, ReadALU]> {
  4358. bits<4> Rn;
  4359. bits<12> imm;
  4360. let Inst{25} = 1;
  4361. let Inst{20} = 1;
  4362. let Inst{19-16} = Rn;
  4363. let Inst{15-12} = 0b0000;
  4364. let Inst{11-0} = imm;
  4365. let Unpredictable{15-12} = 0b1111;
  4366. }
  4367. // CMN register-register/shift
  4368. def CMNzrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr,
  4369. "cmn", "\t$Rn, $Rm",
  4370. [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
  4371. GPR:$Rn, GPR:$Rm)]>, Sched<[WriteCMP, ReadALU, ReadALU]> {
  4372. bits<4> Rn;
  4373. bits<4> Rm;
  4374. let isCommutable = 1;
  4375. let Inst{25} = 0;
  4376. let Inst{20} = 1;
  4377. let Inst{19-16} = Rn;
  4378. let Inst{15-12} = 0b0000;
  4379. let Inst{11-4} = 0b00000000;
  4380. let Inst{3-0} = Rm;
  4381. let Unpredictable{15-12} = 0b1111;
  4382. }
  4383. def CMNzrsi : AI1<0b1011, (outs),
  4384. (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, IIC_iCMPsr,
  4385. "cmn", "\t$Rn, $shift",
  4386. [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
  4387. GPR:$Rn, so_reg_imm:$shift)]>,
  4388. Sched<[WriteCMPsi, ReadALU]> {
  4389. bits<4> Rn;
  4390. bits<12> shift;
  4391. let Inst{25} = 0;
  4392. let Inst{20} = 1;
  4393. let Inst{19-16} = Rn;
  4394. let Inst{15-12} = 0b0000;
  4395. let Inst{11-5} = shift{11-5};
  4396. let Inst{4} = 0;
  4397. let Inst{3-0} = shift{3-0};
  4398. let Unpredictable{15-12} = 0b1111;
  4399. }
  4400. def CMNzrsr : AI1<0b1011, (outs),
  4401. (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, IIC_iCMPsr,
  4402. "cmn", "\t$Rn, $shift",
  4403. [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
  4404. GPRnopc:$Rn, so_reg_reg:$shift)]>,
  4405. Sched<[WriteCMPsr, ReadALU]> {
  4406. bits<4> Rn;
  4407. bits<12> shift;
  4408. let Inst{25} = 0;
  4409. let Inst{20} = 1;
  4410. let Inst{19-16} = Rn;
  4411. let Inst{15-12} = 0b0000;
  4412. let Inst{11-8} = shift{11-8};
  4413. let Inst{7} = 0;
  4414. let Inst{6-5} = shift{6-5};
  4415. let Inst{4} = 1;
  4416. let Inst{3-0} = shift{3-0};
  4417. let Unpredictable{15-12} = 0b1111;
  4418. }
  4419. }
  4420. def : ARMPat<(ARMcmp GPR:$src, mod_imm_neg:$imm),
  4421. (CMNri GPR:$src, mod_imm_neg:$imm)>;
  4422. def : ARMPat<(ARMcmpZ GPR:$src, mod_imm_neg:$imm),
  4423. (CMNri GPR:$src, mod_imm_neg:$imm)>;
  4424. // Note that TST/TEQ don't set all the same flags that CMP does!
  4425. defm TST : AI1_cmp_irs<0b1000, "tst",
  4426. IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
  4427. BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1,
  4428. "DecodeTSTInstruction">;
  4429. defm TEQ : AI1_cmp_irs<0b1001, "teq",
  4430. IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr,
  4431. BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>;
  4432. // Pseudo i64 compares for some floating point compares.
  4433. let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
  4434. Defs = [CPSR] in {
  4435. def BCCi64 : PseudoInst<(outs),
  4436. (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
  4437. IIC_Br,
  4438. [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>,
  4439. Sched<[WriteBr]>;
  4440. def BCCZi64 : PseudoInst<(outs),
  4441. (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br,
  4442. [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>,
  4443. Sched<[WriteBr]>;
  4444. } // usesCustomInserter
  4445. // Conditional moves
  4446. let hasSideEffects = 0 in {
  4447. let isCommutable = 1, isSelect = 1 in
  4448. def MOVCCr : ARMPseudoInst<(outs GPR:$Rd),
  4449. (ins GPR:$false, GPR:$Rm, cmovpred:$p),
  4450. 4, IIC_iCMOVr,
  4451. [(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm,
  4452. cmovpred:$p))]>,
  4453. RegConstraint<"$false = $Rd">, Sched<[WriteALU]>;
  4454. def MOVCCsi : ARMPseudoInst<(outs GPR:$Rd),
  4455. (ins GPR:$false, so_reg_imm:$shift, cmovpred:$p),
  4456. 4, IIC_iCMOVsr,
  4457. [(set GPR:$Rd,
  4458. (ARMcmov GPR:$false, so_reg_imm:$shift,
  4459. cmovpred:$p))]>,
  4460. RegConstraint<"$false = $Rd">, Sched<[WriteALU]>;
  4461. def MOVCCsr : ARMPseudoInst<(outs GPR:$Rd),
  4462. (ins GPR:$false, so_reg_reg:$shift, cmovpred:$p),
  4463. 4, IIC_iCMOVsr,
  4464. [(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_reg:$shift,
  4465. cmovpred:$p))]>,
  4466. RegConstraint<"$false = $Rd">, Sched<[WriteALU]>;
  4467. let isMoveImm = 1 in
  4468. def MOVCCi16
  4469. : ARMPseudoInst<(outs GPR:$Rd),
  4470. (ins GPR:$false, imm0_65535_expr:$imm, cmovpred:$p),
  4471. 4, IIC_iMOVi,
  4472. [(set GPR:$Rd, (ARMcmov GPR:$false, imm0_65535:$imm,
  4473. cmovpred:$p))]>,
  4474. RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>,
  4475. Sched<[WriteALU]>;
  4476. let isMoveImm = 1 in
  4477. def MOVCCi : ARMPseudoInst<(outs GPR:$Rd),
  4478. (ins GPR:$false, mod_imm:$imm, cmovpred:$p),
  4479. 4, IIC_iCMOVi,
  4480. [(set GPR:$Rd, (ARMcmov GPR:$false, mod_imm:$imm,
  4481. cmovpred:$p))]>,
  4482. RegConstraint<"$false = $Rd">, Sched<[WriteALU]>;
  4483. // Two instruction predicate mov immediate.
  4484. let isMoveImm = 1 in
  4485. def MOVCCi32imm
  4486. : ARMPseudoInst<(outs GPR:$Rd),
  4487. (ins GPR:$false, i32imm:$src, cmovpred:$p),
  4488. 8, IIC_iCMOVix2,
  4489. [(set GPR:$Rd, (ARMcmov GPR:$false, imm:$src,
  4490. cmovpred:$p))]>,
  4491. RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>;
  4492. let isMoveImm = 1 in
  4493. def MVNCCi : ARMPseudoInst<(outs GPR:$Rd),
  4494. (ins GPR:$false, mod_imm:$imm, cmovpred:$p),
  4495. 4, IIC_iCMOVi,
  4496. [(set GPR:$Rd, (ARMcmov GPR:$false, mod_imm_not:$imm,
  4497. cmovpred:$p))]>,
  4498. RegConstraint<"$false = $Rd">, Sched<[WriteALU]>;
  4499. } // hasSideEffects
  4500. //===----------------------------------------------------------------------===//
  4501. // Atomic operations intrinsics
  4502. //
  4503. def MemBarrierOptOperand : AsmOperandClass {
  4504. let Name = "MemBarrierOpt";
  4505. let ParserMethod = "parseMemBarrierOptOperand";
  4506. }
  4507. def memb_opt : Operand<i32> {
  4508. let PrintMethod = "printMemBOption";
  4509. let ParserMatchClass = MemBarrierOptOperand;
  4510. let DecoderMethod = "DecodeMemBarrierOption";
  4511. }
  4512. def InstSyncBarrierOptOperand : AsmOperandClass {
  4513. let Name = "InstSyncBarrierOpt";
  4514. let ParserMethod = "parseInstSyncBarrierOptOperand";
  4515. }
  4516. def instsyncb_opt : Operand<i32> {
  4517. let PrintMethod = "printInstSyncBOption";
  4518. let ParserMatchClass = InstSyncBarrierOptOperand;
  4519. let DecoderMethod = "DecodeInstSyncBarrierOption";
  4520. }
  4521. def TraceSyncBarrierOptOperand : AsmOperandClass {
  4522. let Name = "TraceSyncBarrierOpt";
  4523. let ParserMethod = "parseTraceSyncBarrierOptOperand";
  4524. }
  4525. def tsb_opt : Operand<i32> {
  4526. let PrintMethod = "printTraceSyncBOption";
  4527. let ParserMatchClass = TraceSyncBarrierOptOperand;
  4528. }
  4529. // Memory barriers protect the atomic sequences
  4530. let hasSideEffects = 1 in {
  4531. def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
  4532. "dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>,
  4533. Requires<[IsARM, HasDB]> {
  4534. bits<4> opt;
  4535. let Inst{31-4} = 0xf57ff05;
  4536. let Inst{3-0} = opt;
  4537. }
  4538. def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
  4539. "dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>,
  4540. Requires<[IsARM, HasDB]> {
  4541. bits<4> opt;
  4542. let Inst{31-4} = 0xf57ff04;
  4543. let Inst{3-0} = opt;
  4544. }
  4545. // ISB has only full system option
  4546. def ISB : AInoP<(outs), (ins instsyncb_opt:$opt), MiscFrm, NoItinerary,
  4547. "isb", "\t$opt", [(int_arm_isb (i32 imm0_15:$opt))]>,
  4548. Requires<[IsARM, HasDB]> {
  4549. bits<4> opt;
  4550. let Inst{31-4} = 0xf57ff06;
  4551. let Inst{3-0} = opt;
  4552. }
  4553. let hasNoSchedulingInfo = 1 in
  4554. def TSB : AInoP<(outs), (ins tsb_opt:$opt), MiscFrm, NoItinerary,
  4555. "tsb", "\t$opt", []>, Requires<[IsARM, HasV8_4a]> {
  4556. let Inst{31-0} = 0xe320f012;
  4557. let DecoderMethod = "DecodeTSBInstruction";
  4558. }
  4559. }
  4560. // Armv8.5-A speculation barrier
  4561. def SB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "sb", "", []>,
  4562. Requires<[IsARM, HasSB]>, Sched<[]> {
  4563. let Inst{31-0} = 0xf57ff070;
  4564. let Unpredictable = 0x000fff0f;
  4565. let hasSideEffects = 1;
  4566. }
  4567. let usesCustomInserter = 1, Defs = [CPSR], hasNoSchedulingInfo = 1 in {
  4568. // Pseudo instruction that combines movs + predicated rsbmi
  4569. // to implement integer ABS
  4570. def ABS : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$src), 8, NoItinerary, []>;
  4571. }
  4572. let usesCustomInserter = 1, Defs = [CPSR], hasNoSchedulingInfo = 1 in {
  4573. def COPY_STRUCT_BYVAL_I32 : PseudoInst<
  4574. (outs), (ins GPR:$dst, GPR:$src, i32imm:$size, i32imm:$alignment),
  4575. NoItinerary,
  4576. [(ARMcopystructbyval GPR:$dst, GPR:$src, imm:$size, imm:$alignment)]>;
  4577. }
  4578. let hasPostISelHook = 1, Constraints = "$newdst = $dst, $newsrc = $src" in {
  4579. // %newsrc, %newdst = MEMCPY %dst, %src, N, ...N scratch regs...
  4580. // Copies N registers worth of memory from address %src to address %dst
  4581. // and returns the incremented addresses. N scratch register will
  4582. // be attached for the copy to use.
  4583. def MEMCPY : PseudoInst<
  4584. (outs GPR:$newdst, GPR:$newsrc),
  4585. (ins GPR:$dst, GPR:$src, i32imm:$nreg, variable_ops),
  4586. NoItinerary,
  4587. [(set GPR:$newdst, GPR:$newsrc,
  4588. (ARMmemcopy GPR:$dst, GPR:$src, imm:$nreg))]>;
  4589. }
  4590. def ldrex_1 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{
  4591. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8;
  4592. }]>;
  4593. def ldrex_2 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{
  4594. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
  4595. }]>;
  4596. def ldrex_4 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{
  4597. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
  4598. }]>;
  4599. def strex_1 : PatFrag<(ops node:$val, node:$ptr),
  4600. (int_arm_strex node:$val, node:$ptr), [{
  4601. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8;
  4602. }]>;
  4603. def strex_2 : PatFrag<(ops node:$val, node:$ptr),
  4604. (int_arm_strex node:$val, node:$ptr), [{
  4605. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
  4606. }]>;
  4607. def strex_4 : PatFrag<(ops node:$val, node:$ptr),
  4608. (int_arm_strex node:$val, node:$ptr), [{
  4609. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
  4610. }]>;
  4611. def ldaex_1 : PatFrag<(ops node:$ptr), (int_arm_ldaex node:$ptr), [{
  4612. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8;
  4613. }]>;
  4614. def ldaex_2 : PatFrag<(ops node:$ptr), (int_arm_ldaex node:$ptr), [{
  4615. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
  4616. }]>;
  4617. def ldaex_4 : PatFrag<(ops node:$ptr), (int_arm_ldaex node:$ptr), [{
  4618. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
  4619. }]>;
  4620. def stlex_1 : PatFrag<(ops node:$val, node:$ptr),
  4621. (int_arm_stlex node:$val, node:$ptr), [{
  4622. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8;
  4623. }]>;
  4624. def stlex_2 : PatFrag<(ops node:$val, node:$ptr),
  4625. (int_arm_stlex node:$val, node:$ptr), [{
  4626. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
  4627. }]>;
  4628. def stlex_4 : PatFrag<(ops node:$val, node:$ptr),
  4629. (int_arm_stlex node:$val, node:$ptr), [{
  4630. return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
  4631. }]>;
  4632. let mayLoad = 1 in {
  4633. def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr),
  4634. NoItinerary, "ldrexb", "\t$Rt, $addr",
  4635. [(set GPR:$Rt, (ldrex_1 addr_offset_none:$addr))]>;
  4636. def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr),
  4637. NoItinerary, "ldrexh", "\t$Rt, $addr",
  4638. [(set GPR:$Rt, (ldrex_2 addr_offset_none:$addr))]>;
  4639. def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr),
  4640. NoItinerary, "ldrex", "\t$Rt, $addr",
  4641. [(set GPR:$Rt, (ldrex_4 addr_offset_none:$addr))]>;
  4642. let hasExtraDefRegAllocReq = 1 in
  4643. def LDREXD : AIldrex<0b01, (outs GPRPairOp:$Rt),(ins addr_offset_none:$addr),
  4644. NoItinerary, "ldrexd", "\t$Rt, $addr", []> {
  4645. let DecoderMethod = "DecodeDoubleRegLoad";
  4646. }
  4647. def LDAEXB : AIldaex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr),
  4648. NoItinerary, "ldaexb", "\t$Rt, $addr",
  4649. [(set GPR:$Rt, (ldaex_1 addr_offset_none:$addr))]>;
  4650. def LDAEXH : AIldaex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr),
  4651. NoItinerary, "ldaexh", "\t$Rt, $addr",
  4652. [(set GPR:$Rt, (ldaex_2 addr_offset_none:$addr))]>;
  4653. def LDAEX : AIldaex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr),
  4654. NoItinerary, "ldaex", "\t$Rt, $addr",
  4655. [(set GPR:$Rt, (ldaex_4 addr_offset_none:$addr))]>;
  4656. let hasExtraDefRegAllocReq = 1 in
  4657. def LDAEXD : AIldaex<0b01, (outs GPRPairOp:$Rt),(ins addr_offset_none:$addr),
  4658. NoItinerary, "ldaexd", "\t$Rt, $addr", []> {
  4659. let DecoderMethod = "DecodeDoubleRegLoad";
  4660. }
  4661. }
  4662. let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
  4663. def STREXB: AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
  4664. NoItinerary, "strexb", "\t$Rd, $Rt, $addr",
  4665. [(set GPR:$Rd, (strex_1 GPR:$Rt,
  4666. addr_offset_none:$addr))]>;
  4667. def STREXH: AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
  4668. NoItinerary, "strexh", "\t$Rd, $Rt, $addr",
  4669. [(set GPR:$Rd, (strex_2 GPR:$Rt,
  4670. addr_offset_none:$addr))]>;
  4671. def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
  4672. NoItinerary, "strex", "\t$Rd, $Rt, $addr",
  4673. [(set GPR:$Rd, (strex_4 GPR:$Rt,
  4674. addr_offset_none:$addr))]>;
  4675. let hasExtraSrcRegAllocReq = 1 in
  4676. def STREXD : AIstrex<0b01, (outs GPR:$Rd),
  4677. (ins GPRPairOp:$Rt, addr_offset_none:$addr),
  4678. NoItinerary, "strexd", "\t$Rd, $Rt, $addr", []> {
  4679. let DecoderMethod = "DecodeDoubleRegStore";
  4680. }
  4681. def STLEXB: AIstlex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
  4682. NoItinerary, "stlexb", "\t$Rd, $Rt, $addr",
  4683. [(set GPR:$Rd,
  4684. (stlex_1 GPR:$Rt, addr_offset_none:$addr))]>;
  4685. def STLEXH: AIstlex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
  4686. NoItinerary, "stlexh", "\t$Rd, $Rt, $addr",
  4687. [(set GPR:$Rd,
  4688. (stlex_2 GPR:$Rt, addr_offset_none:$addr))]>;
  4689. def STLEX : AIstlex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr),
  4690. NoItinerary, "stlex", "\t$Rd, $Rt, $addr",
  4691. [(set GPR:$Rd,
  4692. (stlex_4 GPR:$Rt, addr_offset_none:$addr))]>;
  4693. let hasExtraSrcRegAllocReq = 1 in
  4694. def STLEXD : AIstlex<0b01, (outs GPR:$Rd),
  4695. (ins GPRPairOp:$Rt, addr_offset_none:$addr),
  4696. NoItinerary, "stlexd", "\t$Rd, $Rt, $addr", []> {
  4697. let DecoderMethod = "DecodeDoubleRegStore";
  4698. }
  4699. }
  4700. def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
  4701. [(int_arm_clrex)]>,
  4702. Requires<[IsARM, HasV6K]> {
  4703. let Inst{31-0} = 0b11110101011111111111000000011111;
  4704. }
  4705. def : ARMPat<(strex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr),
  4706. (STREXB GPR:$Rt, addr_offset_none:$addr)>;
  4707. def : ARMPat<(strex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr),
  4708. (STREXH GPR:$Rt, addr_offset_none:$addr)>;
  4709. def : ARMPat<(stlex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr),
  4710. (STLEXB GPR:$Rt, addr_offset_none:$addr)>;
  4711. def : ARMPat<(stlex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr),
  4712. (STLEXH GPR:$Rt, addr_offset_none:$addr)>;
  4713. class acquiring_load<PatFrag base>
  4714. : PatFrag<(ops node:$ptr), (base node:$ptr), [{
  4715. AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering();
  4716. return isAcquireOrStronger(Ordering);
  4717. }]>;
  4718. def atomic_load_acquire_8 : acquiring_load<atomic_load_8>;
  4719. def atomic_load_acquire_16 : acquiring_load<atomic_load_16>;
  4720. def atomic_load_acquire_32 : acquiring_load<atomic_load_32>;
  4721. class releasing_store<PatFrag base>
  4722. : PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val), [{
  4723. AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering();
  4724. return isReleaseOrStronger(Ordering);
  4725. }]>;
  4726. def atomic_store_release_8 : releasing_store<atomic_store_8>;
  4727. def atomic_store_release_16 : releasing_store<atomic_store_16>;
  4728. def atomic_store_release_32 : releasing_store<atomic_store_32>;
  4729. let AddedComplexity = 8 in {
  4730. def : ARMPat<(atomic_load_acquire_8 addr_offset_none:$addr), (LDAB addr_offset_none:$addr)>;
  4731. def : ARMPat<(atomic_load_acquire_16 addr_offset_none:$addr), (LDAH addr_offset_none:$addr)>;
  4732. def : ARMPat<(atomic_load_acquire_32 addr_offset_none:$addr), (LDA addr_offset_none:$addr)>;
  4733. def : ARMPat<(atomic_store_release_8 addr_offset_none:$addr, GPR:$val), (STLB GPR:$val, addr_offset_none:$addr)>;
  4734. def : ARMPat<(atomic_store_release_16 addr_offset_none:$addr, GPR:$val), (STLH GPR:$val, addr_offset_none:$addr)>;
  4735. def : ARMPat<(atomic_store_release_32 addr_offset_none:$addr, GPR:$val), (STL GPR:$val, addr_offset_none:$addr)>;
  4736. }
  4737. // SWP/SWPB are deprecated in V6/V7 and optional in v7VE.
  4738. // FIXME Use InstAlias to generate LDREX/STREX pairs instead.
  4739. let mayLoad = 1, mayStore = 1 in {
  4740. def SWP : AIswp<0, (outs GPRnopc:$Rt),
  4741. (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swp", []>,
  4742. Requires<[IsARM,PreV8]>;
  4743. def SWPB: AIswp<1, (outs GPRnopc:$Rt),
  4744. (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swpb", []>,
  4745. Requires<[IsARM,PreV8]>;
  4746. }
  4747. //===----------------------------------------------------------------------===//
  4748. // Coprocessor Instructions.
  4749. //
  4750. def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1,
  4751. c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
  4752. NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
  4753. [(int_arm_cdp timm:$cop, timm:$opc1, timm:$CRd, timm:$CRn,
  4754. timm:$CRm, timm:$opc2)]>,
  4755. Requires<[IsARM,PreV8]> {
  4756. bits<4> opc1;
  4757. bits<4> CRn;
  4758. bits<4> CRd;
  4759. bits<4> cop;
  4760. bits<3> opc2;
  4761. bits<4> CRm;
  4762. let Inst{3-0} = CRm;
  4763. let Inst{4} = 0;
  4764. let Inst{7-5} = opc2;
  4765. let Inst{11-8} = cop;
  4766. let Inst{15-12} = CRd;
  4767. let Inst{19-16} = CRn;
  4768. let Inst{23-20} = opc1;
  4769. let DecoderNamespace = "CoProc";
  4770. }
  4771. def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1,
  4772. c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
  4773. NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
  4774. [(int_arm_cdp2 timm:$cop, timm:$opc1, timm:$CRd, timm:$CRn,
  4775. timm:$CRm, timm:$opc2)]>,
  4776. Requires<[IsARM,PreV8]> {
  4777. let Inst{31-28} = 0b1111;
  4778. bits<4> opc1;
  4779. bits<4> CRn;
  4780. bits<4> CRd;
  4781. bits<4> cop;
  4782. bits<3> opc2;
  4783. bits<4> CRm;
  4784. let Inst{3-0} = CRm;
  4785. let Inst{4} = 0;
  4786. let Inst{7-5} = opc2;
  4787. let Inst{11-8} = cop;
  4788. let Inst{15-12} = CRd;
  4789. let Inst{19-16} = CRn;
  4790. let Inst{23-20} = opc1;
  4791. let DecoderNamespace = "CoProc";
  4792. }
  4793. class ACI<dag oops, dag iops, string opc, string asm,
  4794. list<dag> pattern, IndexMode im = IndexModeNone,
  4795. AddrMode am = AddrModeNone>
  4796. : I<oops, iops, am, 4, im, BrFrm, NoItinerary,
  4797. opc, asm, "", pattern> {
  4798. let Inst{27-25} = 0b110;
  4799. }
  4800. class ACInoP<dag oops, dag iops, string opc, string asm,
  4801. list<dag> pattern, IndexMode im = IndexModeNone,
  4802. AddrMode am = AddrModeNone>
  4803. : InoP<oops, iops, am, 4, im, BrFrm, NoItinerary,
  4804. opc, asm, "", pattern> {
  4805. let Inst{31-28} = 0b1111;
  4806. let Inst{27-25} = 0b110;
  4807. }
  4808. let DecoderNamespace = "CoProc" in {
  4809. multiclass LdStCop<bit load, bit Dbit, string asm, list<dag> pattern> {
  4810. def _OFFSET : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
  4811. asm, "\t$cop, $CRd, $addr", pattern, IndexModeNone,
  4812. AddrMode5> {
  4813. bits<13> addr;
  4814. bits<4> cop;
  4815. bits<4> CRd;
  4816. let Inst{24} = 1; // P = 1
  4817. let Inst{23} = addr{8};
  4818. let Inst{22} = Dbit;
  4819. let Inst{21} = 0; // W = 0
  4820. let Inst{20} = load;
  4821. let Inst{19-16} = addr{12-9};
  4822. let Inst{15-12} = CRd;
  4823. let Inst{11-8} = cop;
  4824. let Inst{7-0} = addr{7-0};
  4825. let DecoderMethod = "DecodeCopMemInstruction";
  4826. }
  4827. def _PRE : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr),
  4828. asm, "\t$cop, $CRd, $addr!", [], IndexModePre> {
  4829. bits<13> addr;
  4830. bits<4> cop;
  4831. bits<4> CRd;
  4832. let Inst{24} = 1; // P = 1
  4833. let Inst{23} = addr{8};
  4834. let Inst{22} = Dbit;
  4835. let Inst{21} = 1; // W = 1
  4836. let Inst{20} = load;
  4837. let Inst{19-16} = addr{12-9};
  4838. let Inst{15-12} = CRd;
  4839. let Inst{11-8} = cop;
  4840. let Inst{7-0} = addr{7-0};
  4841. let DecoderMethod = "DecodeCopMemInstruction";
  4842. }
  4843. def _POST: ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
  4844. postidx_imm8s4:$offset),
  4845. asm, "\t$cop, $CRd, $addr, $offset", [], IndexModePost> {
  4846. bits<9> offset;
  4847. bits<4> addr;
  4848. bits<4> cop;
  4849. bits<4> CRd;
  4850. let Inst{24} = 0; // P = 0
  4851. let Inst{23} = offset{8};
  4852. let Inst{22} = Dbit;
  4853. let Inst{21} = 1; // W = 1
  4854. let Inst{20} = load;
  4855. let Inst{19-16} = addr;
  4856. let Inst{15-12} = CRd;
  4857. let Inst{11-8} = cop;
  4858. let Inst{7-0} = offset{7-0};
  4859. let DecoderMethod = "DecodeCopMemInstruction";
  4860. }
  4861. def _OPTION : ACI<(outs),
  4862. (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
  4863. coproc_option_imm:$option),
  4864. asm, "\t$cop, $CRd, $addr, $option", []> {
  4865. bits<8> option;
  4866. bits<4> addr;
  4867. bits<4> cop;
  4868. bits<4> CRd;
  4869. let Inst{24} = 0; // P = 0
  4870. let Inst{23} = 1; // U = 1
  4871. let Inst{22} = Dbit;
  4872. let Inst{21} = 0; // W = 0
  4873. let Inst{20} = load;
  4874. let Inst{19-16} = addr;
  4875. let Inst{15-12} = CRd;
  4876. let Inst{11-8} = cop;
  4877. let Inst{7-0} = option;
  4878. let DecoderMethod = "DecodeCopMemInstruction";
  4879. }
  4880. }
  4881. multiclass LdSt2Cop<bit load, bit Dbit, string asm, list<dag> pattern> {
  4882. def _OFFSET : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
  4883. asm, "\t$cop, $CRd, $addr", pattern, IndexModeNone,
  4884. AddrMode5> {
  4885. bits<13> addr;
  4886. bits<4> cop;
  4887. bits<4> CRd;
  4888. let Inst{24} = 1; // P = 1
  4889. let Inst{23} = addr{8};
  4890. let Inst{22} = Dbit;
  4891. let Inst{21} = 0; // W = 0
  4892. let Inst{20} = load;
  4893. let Inst{19-16} = addr{12-9};
  4894. let Inst{15-12} = CRd;
  4895. let Inst{11-8} = cop;
  4896. let Inst{7-0} = addr{7-0};
  4897. let DecoderMethod = "DecodeCopMemInstruction";
  4898. }
  4899. def _PRE : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr),
  4900. asm, "\t$cop, $CRd, $addr!", [], IndexModePre> {
  4901. bits<13> addr;
  4902. bits<4> cop;
  4903. bits<4> CRd;
  4904. let Inst{24} = 1; // P = 1
  4905. let Inst{23} = addr{8};
  4906. let Inst{22} = Dbit;
  4907. let Inst{21} = 1; // W = 1
  4908. let Inst{20} = load;
  4909. let Inst{19-16} = addr{12-9};
  4910. let Inst{15-12} = CRd;
  4911. let Inst{11-8} = cop;
  4912. let Inst{7-0} = addr{7-0};
  4913. let DecoderMethod = "DecodeCopMemInstruction";
  4914. }
  4915. def _POST: ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
  4916. postidx_imm8s4:$offset),
  4917. asm, "\t$cop, $CRd, $addr, $offset", [], IndexModePost> {
  4918. bits<9> offset;
  4919. bits<4> addr;
  4920. bits<4> cop;
  4921. bits<4> CRd;
  4922. let Inst{24} = 0; // P = 0
  4923. let Inst{23} = offset{8};
  4924. let Inst{22} = Dbit;
  4925. let Inst{21} = 1; // W = 1
  4926. let Inst{20} = load;
  4927. let Inst{19-16} = addr;
  4928. let Inst{15-12} = CRd;
  4929. let Inst{11-8} = cop;
  4930. let Inst{7-0} = offset{7-0};
  4931. let DecoderMethod = "DecodeCopMemInstruction";
  4932. }
  4933. def _OPTION : ACInoP<(outs),
  4934. (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
  4935. coproc_option_imm:$option),
  4936. asm, "\t$cop, $CRd, $addr, $option", []> {
  4937. bits<8> option;
  4938. bits<4> addr;
  4939. bits<4> cop;
  4940. bits<4> CRd;
  4941. let Inst{24} = 0; // P = 0
  4942. let Inst{23} = 1; // U = 1
  4943. let Inst{22} = Dbit;
  4944. let Inst{21} = 0; // W = 0
  4945. let Inst{20} = load;
  4946. let Inst{19-16} = addr;
  4947. let Inst{15-12} = CRd;
  4948. let Inst{11-8} = cop;
  4949. let Inst{7-0} = option;
  4950. let DecoderMethod = "DecodeCopMemInstruction";
  4951. }
  4952. }
  4953. defm LDC : LdStCop <1, 0, "ldc", [(int_arm_ldc timm:$cop, timm:$CRd, addrmode5:$addr)]>;
  4954. defm LDCL : LdStCop <1, 1, "ldcl", [(int_arm_ldcl timm:$cop, timm:$CRd, addrmode5:$addr)]>;
  4955. defm LDC2 : LdSt2Cop<1, 0, "ldc2", [(int_arm_ldc2 timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>;
  4956. defm LDC2L : LdSt2Cop<1, 1, "ldc2l", [(int_arm_ldc2l timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>;
  4957. defm STC : LdStCop <0, 0, "stc", [(int_arm_stc timm:$cop, timm:$CRd, addrmode5:$addr)]>;
  4958. defm STCL : LdStCop <0, 1, "stcl", [(int_arm_stcl timm:$cop, timm:$CRd, addrmode5:$addr)]>;
  4959. defm STC2 : LdSt2Cop<0, 0, "stc2", [(int_arm_stc2 timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>;
  4960. defm STC2L : LdSt2Cop<0, 1, "stc2l", [(int_arm_stc2l timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>;
  4961. } // DecoderNamespace = "CoProc"
  4962. //===----------------------------------------------------------------------===//
  4963. // Move between coprocessor and ARM core register.
  4964. //
  4965. class MovRCopro<string opc, bit direction, dag oops, dag iops,
  4966. list<dag> pattern>
  4967. : ABI<0b1110, oops, iops, NoItinerary, opc,
  4968. "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2", pattern> {
  4969. let Inst{20} = direction;
  4970. let Inst{4} = 1;
  4971. bits<4> Rt;
  4972. bits<4> cop;
  4973. bits<3> opc1;
  4974. bits<3> opc2;
  4975. bits<4> CRm;
  4976. bits<4> CRn;
  4977. let Inst{15-12} = Rt;
  4978. let Inst{11-8} = cop;
  4979. let Inst{23-21} = opc1;
  4980. let Inst{7-5} = opc2;
  4981. let Inst{3-0} = CRm;
  4982. let Inst{19-16} = CRn;
  4983. let DecoderNamespace = "CoProc";
  4984. }
  4985. def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */,
  4986. (outs),
  4987. (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
  4988. c_imm:$CRm, imm0_7:$opc2),
  4989. [(int_arm_mcr timm:$cop, timm:$opc1, GPR:$Rt, timm:$CRn,
  4990. timm:$CRm, timm:$opc2)]>,
  4991. ComplexDeprecationPredicate<"MCR">;
  4992. def : ARMInstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm",
  4993. (MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
  4994. c_imm:$CRm, 0, pred:$p)>;
  4995. def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */,
  4996. (outs GPRwithAPSR:$Rt),
  4997. (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm,
  4998. imm0_7:$opc2), []>,
  4999. ComplexDeprecationPredicate<"MRC">;
  5000. def : ARMInstAlias<"mrc${p} $cop, $opc1, $Rt, $CRn, $CRm",
  5001. (MRC GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
  5002. c_imm:$CRm, 0, pred:$p)>;
  5003. def : ARMPat<(int_arm_mrc timm:$cop, timm:$opc1, timm:$CRn, timm:$CRm, timm:$opc2),
  5004. (MRC p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2)>;
  5005. class MovRCopro2<string opc, bit direction, dag oops, dag iops,
  5006. list<dag> pattern>
  5007. : ABXI<0b1110, oops, iops, NoItinerary,
  5008. !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"), pattern> {
  5009. let Inst{31-24} = 0b11111110;
  5010. let Inst{20} = direction;
  5011. let Inst{4} = 1;
  5012. bits<4> Rt;
  5013. bits<4> cop;
  5014. bits<3> opc1;
  5015. bits<3> opc2;
  5016. bits<4> CRm;
  5017. bits<4> CRn;
  5018. let Inst{15-12} = Rt;
  5019. let Inst{11-8} = cop;
  5020. let Inst{23-21} = opc1;
  5021. let Inst{7-5} = opc2;
  5022. let Inst{3-0} = CRm;
  5023. let Inst{19-16} = CRn;
  5024. let DecoderNamespace = "CoProc";
  5025. }
  5026. def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */,
  5027. (outs),
  5028. (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
  5029. c_imm:$CRm, imm0_7:$opc2),
  5030. [(int_arm_mcr2 timm:$cop, timm:$opc1, GPR:$Rt, timm:$CRn,
  5031. timm:$CRm, timm:$opc2)]>,
  5032. Requires<[IsARM,PreV8]>;
  5033. def : ARMInstAlias<"mcr2 $cop, $opc1, $Rt, $CRn, $CRm",
  5034. (MCR2 p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
  5035. c_imm:$CRm, 0)>;
  5036. def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */,
  5037. (outs GPRwithAPSR:$Rt),
  5038. (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm,
  5039. imm0_7:$opc2), []>,
  5040. Requires<[IsARM,PreV8]>;
  5041. def : ARMInstAlias<"mrc2 $cop, $opc1, $Rt, $CRn, $CRm",
  5042. (MRC2 GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
  5043. c_imm:$CRm, 0)>;
  5044. def : ARMV5TPat<(int_arm_mrc2 timm:$cop, timm:$opc1, timm:$CRn,
  5045. timm:$CRm, timm:$opc2),
  5046. (MRC2 p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2)>;
  5047. class MovRRCopro<string opc, bit direction, dag oops, dag iops, list<dag>
  5048. pattern = []>
  5049. : ABI<0b1100, oops, iops, NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm",
  5050. pattern> {
  5051. let Inst{23-21} = 0b010;
  5052. let Inst{20} = direction;
  5053. bits<4> Rt;
  5054. bits<4> Rt2;
  5055. bits<4> cop;
  5056. bits<4> opc1;
  5057. bits<4> CRm;
  5058. let Inst{15-12} = Rt;
  5059. let Inst{19-16} = Rt2;
  5060. let Inst{11-8} = cop;
  5061. let Inst{7-4} = opc1;
  5062. let Inst{3-0} = CRm;
  5063. }
  5064. def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */,
  5065. (outs), (ins p_imm:$cop, imm0_15:$opc1, GPRnopc:$Rt,
  5066. GPRnopc:$Rt2, c_imm:$CRm),
  5067. [(int_arm_mcrr timm:$cop, timm:$opc1, GPRnopc:$Rt,
  5068. GPRnopc:$Rt2, timm:$CRm)]>;
  5069. def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */,
  5070. (outs GPRnopc:$Rt, GPRnopc:$Rt2),
  5071. (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm), []>;
  5072. class MovRRCopro2<string opc, bit direction, dag oops, dag iops,
  5073. list<dag> pattern = []>
  5074. : ABXI<0b1100, oops, iops, NoItinerary,
  5075. !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern>,
  5076. Requires<[IsARM,PreV8]> {
  5077. let Inst{31-28} = 0b1111;
  5078. let Inst{23-21} = 0b010;
  5079. let Inst{20} = direction;
  5080. bits<4> Rt;
  5081. bits<4> Rt2;
  5082. bits<4> cop;
  5083. bits<4> opc1;
  5084. bits<4> CRm;
  5085. let Inst{15-12} = Rt;
  5086. let Inst{19-16} = Rt2;
  5087. let Inst{11-8} = cop;
  5088. let Inst{7-4} = opc1;
  5089. let Inst{3-0} = CRm;
  5090. let DecoderMethod = "DecoderForMRRC2AndMCRR2";
  5091. }
  5092. def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */,
  5093. (outs), (ins p_imm:$cop, imm0_15:$opc1, GPRnopc:$Rt,
  5094. GPRnopc:$Rt2, c_imm:$CRm),
  5095. [(int_arm_mcrr2 timm:$cop, timm:$opc1, GPRnopc:$Rt,
  5096. GPRnopc:$Rt2, timm:$CRm)]>;
  5097. def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */,
  5098. (outs GPRnopc:$Rt, GPRnopc:$Rt2),
  5099. (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm), []>;
  5100. //===----------------------------------------------------------------------===//
  5101. // Move between special register and ARM core register
  5102. //
  5103. // Move to ARM core register from Special Register
  5104. def MRS : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary,
  5105. "mrs", "\t$Rd, apsr", []> {
  5106. bits<4> Rd;
  5107. let Inst{23-16} = 0b00001111;
  5108. let Unpredictable{19-17} = 0b111;
  5109. let Inst{15-12} = Rd;
  5110. let Inst{11-0} = 0b000000000000;
  5111. let Unpredictable{11-0} = 0b110100001111;
  5112. }
  5113. def : InstAlias<"mrs${p} $Rd, cpsr", (MRS GPRnopc:$Rd, pred:$p), 0>,
  5114. Requires<[IsARM]>;
  5115. // The MRSsys instruction is the MRS instruction from the ARM ARM,
  5116. // section B9.3.9, with the R bit set to 1.
  5117. def MRSsys : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary,
  5118. "mrs", "\t$Rd, spsr", []> {
  5119. bits<4> Rd;
  5120. let Inst{23-16} = 0b01001111;
  5121. let Unpredictable{19-16} = 0b1111;
  5122. let Inst{15-12} = Rd;
  5123. let Inst{11-0} = 0b000000000000;
  5124. let Unpredictable{11-0} = 0b110100001111;
  5125. }
  5126. // However, the MRS (banked register) system instruction (ARMv7VE) *does* have a
  5127. // separate encoding (distinguished by bit 5.
  5128. def MRSbanked : ABI<0b0001, (outs GPRnopc:$Rd), (ins banked_reg:$banked),
  5129. NoItinerary, "mrs", "\t$Rd, $banked", []>,
  5130. Requires<[IsARM, HasVirtualization]> {
  5131. bits<6> banked;
  5132. bits<4> Rd;
  5133. let Inst{23} = 0;
  5134. let Inst{22} = banked{5}; // R bit
  5135. let Inst{21-20} = 0b00;
  5136. let Inst{19-16} = banked{3-0};
  5137. let Inst{15-12} = Rd;
  5138. let Inst{11-9} = 0b001;
  5139. let Inst{8} = banked{4};
  5140. let Inst{7-0} = 0b00000000;
  5141. }
  5142. // Move from ARM core register to Special Register
  5143. //
  5144. // No need to have both system and application versions of MSR (immediate) or
  5145. // MSR (register), the encodings are the same and the assembly parser has no way
  5146. // to distinguish between them. The mask operand contains the special register
  5147. // (R Bit) in bit 4 and bits 3-0 contains the mask with the fields to be
  5148. // accessed in the special register.
  5149. let Defs = [CPSR] in
  5150. def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary,
  5151. "msr", "\t$mask, $Rn", []> {
  5152. bits<5> mask;
  5153. bits<4> Rn;
  5154. let Inst{23} = 0;
  5155. let Inst{22} = mask{4}; // R bit
  5156. let Inst{21-20} = 0b10;
  5157. let Inst{19-16} = mask{3-0};
  5158. let Inst{15-12} = 0b1111;
  5159. let Inst{11-4} = 0b00000000;
  5160. let Inst{3-0} = Rn;
  5161. }
  5162. let Defs = [CPSR] in
  5163. def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask, mod_imm:$imm), NoItinerary,
  5164. "msr", "\t$mask, $imm", []> {
  5165. bits<5> mask;
  5166. bits<12> imm;
  5167. let Inst{23} = 0;
  5168. let Inst{22} = mask{4}; // R bit
  5169. let Inst{21-20} = 0b10;
  5170. let Inst{19-16} = mask{3-0};
  5171. let Inst{15-12} = 0b1111;
  5172. let Inst{11-0} = imm;
  5173. }
  5174. // However, the MSR (banked register) system instruction (ARMv7VE) *does* have a
  5175. // separate encoding (distinguished by bit 5.
  5176. def MSRbanked : ABI<0b0001, (outs), (ins banked_reg:$banked, GPRnopc:$Rn),
  5177. NoItinerary, "msr", "\t$banked, $Rn", []>,
  5178. Requires<[IsARM, HasVirtualization]> {
  5179. bits<6> banked;
  5180. bits<4> Rn;
  5181. let Inst{23} = 0;
  5182. let Inst{22} = banked{5}; // R bit
  5183. let Inst{21-20} = 0b10;
  5184. let Inst{19-16} = banked{3-0};
  5185. let Inst{15-12} = 0b1111;
  5186. let Inst{11-9} = 0b001;
  5187. let Inst{8} = banked{4};
  5188. let Inst{7-4} = 0b0000;
  5189. let Inst{3-0} = Rn;
  5190. }
  5191. // Dynamic stack allocation yields a _chkstk for Windows targets. These calls
  5192. // are needed to probe the stack when allocating more than
  5193. // 4k bytes in one go. Touching the stack at 4K increments is necessary to
  5194. // ensure that the guard pages used by the OS virtual memory manager are
  5195. // allocated in correct sequence.
  5196. // The main point of having separate instruction are extra unmodelled effects
  5197. // (compared to ordinary calls) like stack pointer change.
  5198. def win__chkstk : SDNode<"ARMISD::WIN__CHKSTK", SDTNone,
  5199. [SDNPHasChain, SDNPSideEffect]>;
  5200. let usesCustomInserter = 1, Uses = [R4], Defs = [R4, SP], hasNoSchedulingInfo = 1 in
  5201. def WIN__CHKSTK : PseudoInst<(outs), (ins), NoItinerary, [(win__chkstk)]>;
  5202. def win__dbzchk : SDNode<"ARMISD::WIN__DBZCHK", SDT_WIN__DBZCHK,
  5203. [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
  5204. let usesCustomInserter = 1, Defs = [CPSR], hasNoSchedulingInfo = 1 in
  5205. def WIN__DBZCHK : PseudoInst<(outs), (ins tGPR:$divisor), NoItinerary,
  5206. [(win__dbzchk tGPR:$divisor)]>;
  5207. //===----------------------------------------------------------------------===//
  5208. // TLS Instructions
  5209. //
  5210. // __aeabi_read_tp preserves the registers r1-r3.
  5211. // This is a pseudo inst so that we can get the encoding right,
  5212. // complete with fixup for the aeabi_read_tp function.
  5213. // TPsoft is valid for ARM mode only, in case of Thumb mode a tTPsoft pattern
  5214. // is defined in "ARMInstrThumb.td".
  5215. let isCall = 1,
  5216. Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
  5217. def TPsoft : ARMPseudoInst<(outs), (ins), 4, IIC_Br,
  5218. [(set R0, ARMthread_pointer)]>, Sched<[WriteBr]>,
  5219. Requires<[IsARM, IsReadTPSoft]>;
  5220. }
  5221. // Reading thread pointer from coprocessor register
  5222. def : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 3)>,
  5223. Requires<[IsARM, IsReadTPHard]>;
  5224. //===----------------------------------------------------------------------===//
  5225. // SJLJ Exception handling intrinsics
  5226. // eh_sjlj_setjmp() is an instruction sequence to store the return
  5227. // address and save #0 in R0 for the non-longjmp case.
  5228. // Since by its nature we may be coming from some other function to get
  5229. // here, and we're using the stack frame for the containing function to
  5230. // save/restore registers, we can't keep anything live in regs across
  5231. // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
  5232. // when we get here from a longjmp(). We force everything out of registers
  5233. // except for our own input by listing the relevant registers in Defs. By
  5234. // doing so, we also cause the prologue/epilogue code to actively preserve
  5235. // all of the callee-saved registers, which is exactly what we want.
  5236. // A constant value is passed in $val, and we use the location as a scratch.
  5237. //
  5238. // These are pseudo-instructions and are lowered to individual MC-insts, so
  5239. // no encoding information is necessary.
  5240. // This gets lowered to an instruction sequence of 20 bytes
  5241. let Defs =
  5242. [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR,
  5243. Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ],
  5244. hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, Size = 20 in {
  5245. def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
  5246. NoItinerary,
  5247. [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
  5248. Requires<[IsARM, HasVFP2]>;
  5249. }
  5250. // This gets lowered to an instruction sequence of 20 bytes
  5251. let Defs =
  5252. [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ],
  5253. hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, Size = 20 in {
  5254. def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
  5255. NoItinerary,
  5256. [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
  5257. Requires<[IsARM, NoVFP]>;
  5258. }
  5259. // This gets lowered to an instruction sequence of 16 bytes
  5260. // FIXME: Non-IOS version(s)
  5261. let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, Size = 16,
  5262. Defs = [ R7, LR, SP ] in {
  5263. def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
  5264. NoItinerary,
  5265. [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
  5266. Requires<[IsARM]>;
  5267. }
  5268. let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1 in
  5269. def Int_eh_sjlj_setup_dispatch : PseudoInst<(outs), (ins), NoItinerary,
  5270. [(ARMeh_sjlj_setup_dispatch)]>;
  5271. // eh.sjlj.dispatchsetup pseudo-instruction.
  5272. // This pseudo is used for both ARM and Thumb. Any differences are handled when
  5273. // the pseudo is expanded (which happens before any passes that need the
  5274. // instruction size).
  5275. let isBarrier = 1 in
  5276. def Int_eh_sjlj_dispatchsetup : PseudoInst<(outs), (ins), NoItinerary, []>;
  5277. //===----------------------------------------------------------------------===//
  5278. // Non-Instruction Patterns
  5279. //
  5280. // ARMv4 indirect branch using (MOVr PC, dst)
  5281. let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in
  5282. def MOVPCRX : ARMPseudoExpand<(outs), (ins GPR:$dst),
  5283. 4, IIC_Br, [(brind GPR:$dst)],
  5284. (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>,
  5285. Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>;
  5286. let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in
  5287. def TAILJMPr4 : ARMPseudoExpand<(outs), (ins GPR:$dst),
  5288. 4, IIC_Br, [],
  5289. (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>,
  5290. Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>;
  5291. // Large immediate handling.
  5292. // 32-bit immediate using two piece mod_imms or movw + movt.
  5293. // This is a single pseudo instruction, the benefit is that it can be remat'd
  5294. // as a single unit instead of having to handle reg inputs.
  5295. // FIXME: Remove this when we can do generalized remat.
  5296. let isReMaterializable = 1, isMoveImm = 1, Size = 8 in
  5297. def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
  5298. [(set GPR:$dst, (arm_i32imm:$src))]>,
  5299. Requires<[IsARM]>;
  5300. def LDRLIT_ga_abs : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iLoad_i,
  5301. [(set GPR:$dst, (ARMWrapper tglobaladdr:$src))]>,
  5302. Requires<[IsARM, DontUseMovt]>;
  5303. // Pseudo instruction that combines movw + movt + add pc (if PIC).
  5304. // It also makes it possible to rematerialize the instructions.
  5305. // FIXME: Remove this when we can do generalized remat and when machine licm
  5306. // can properly the instructions.
  5307. let isReMaterializable = 1 in {
  5308. def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
  5309. IIC_iMOVix2addpc,
  5310. [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
  5311. Requires<[IsARM, UseMovtInPic]>;
  5312. def LDRLIT_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
  5313. IIC_iLoadiALU,
  5314. [(set GPR:$dst,
  5315. (ARMWrapperPIC tglobaladdr:$addr))]>,
  5316. Requires<[IsARM, DontUseMovtInPic]>;
  5317. let AddedComplexity = 10 in
  5318. def LDRLIT_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
  5319. NoItinerary,
  5320. [(set GPR:$dst,
  5321. (load (ARMWrapperPIC tglobaladdr:$addr)))]>,
  5322. Requires<[IsARM, DontUseMovtInPic]>;
  5323. let AddedComplexity = 10 in
  5324. def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr),
  5325. IIC_iMOVix2ld,
  5326. [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>,
  5327. Requires<[IsARM, UseMovtInPic]>;
  5328. } // isReMaterializable
  5329. // The many different faces of TLS access.
  5330. def : ARMPat<(ARMWrapper tglobaltlsaddr :$dst),
  5331. (MOVi32imm tglobaltlsaddr :$dst)>,
  5332. Requires<[IsARM, UseMovt]>;
  5333. def : Pat<(ARMWrapper tglobaltlsaddr:$src),
  5334. (LDRLIT_ga_abs tglobaltlsaddr:$src)>,
  5335. Requires<[IsARM, DontUseMovt]>;
  5336. def : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr),
  5337. (MOV_ga_pcrel tglobaltlsaddr:$addr)>, Requires<[IsARM, UseMovtInPic]>;
  5338. def : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr),
  5339. (LDRLIT_ga_pcrel tglobaltlsaddr:$addr)>,
  5340. Requires<[IsARM, DontUseMovtInPic]>;
  5341. let AddedComplexity = 10 in
  5342. def : Pat<(load (ARMWrapperPIC tglobaltlsaddr:$addr)),
  5343. (MOV_ga_pcrel_ldr tglobaltlsaddr:$addr)>,
  5344. Requires<[IsARM, UseMovtInPic]>;
  5345. // ConstantPool, GlobalAddress, and JumpTable
  5346. def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
  5347. def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
  5348. Requires<[IsARM, UseMovt]>;
  5349. def : ARMPat<(ARMWrapper texternalsym :$dst), (MOVi32imm texternalsym :$dst)>,
  5350. Requires<[IsARM, UseMovt]>;
  5351. def : ARMPat<(ARMWrapperJT tjumptable:$dst),
  5352. (LEApcrelJT tjumptable:$dst)>;
  5353. // TODO: add,sub,and, 3-instr forms?
  5354. // Tail calls. These patterns also apply to Thumb mode.
  5355. def : Pat<(ARMtcret tcGPR:$dst, (i32 timm:$SPDiff)),
  5356. (TCRETURNri tcGPR:$dst, timm:$SPDiff)>;
  5357. def : Pat<(ARMtcret (i32 tglobaladdr:$dst), (i32 timm:$SPDiff)),
  5358. (TCRETURNdi texternalsym:$dst, (i32 timm:$SPDiff))>;
  5359. def : Pat<(ARMtcret (i32 texternalsym:$dst), (i32 timm:$SPDiff)),
  5360. (TCRETURNdi texternalsym:$dst, i32imm:$SPDiff)>;
  5361. // Direct calls
  5362. def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>;
  5363. def : ARMPat<(ARMcall_nolink texternalsym:$func),
  5364. (BMOVPCB_CALL texternalsym:$func)>;
  5365. // zextload i1 -> zextload i8
  5366. def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
  5367. def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
  5368. // extload -> zextload
  5369. def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
  5370. def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
  5371. def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
  5372. def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
  5373. def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
  5374. def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
  5375. def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
  5376. // smul* and smla*
  5377. def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
  5378. (SMULBB GPR:$a, GPR:$b)>;
  5379. def : ARMV5TEPat<(mul sext_16_node:$a, (sext_bottom_16 GPR:$b)),
  5380. (SMULBB GPR:$a, GPR:$b)>;
  5381. def : ARMV5TEPat<(mul sext_16_node:$a, (sext_top_16 GPR:$b)),
  5382. (SMULBT GPR:$a, GPR:$b)>;
  5383. def : ARMV5TEPat<(mul (sext_top_16 GPR:$a), sext_16_node:$b),
  5384. (SMULTB GPR:$a, GPR:$b)>;
  5385. def : ARMV5MOPat<(add GPR:$acc, (mul sext_16_node:$a, sext_16_node:$b)),
  5386. (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
  5387. def : ARMV5MOPat<(add GPR:$acc, (mul sext_16_node:$a, (sext_bottom_16 GPR:$b))),
  5388. (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
  5389. def : ARMV5MOPat<(add GPR:$acc, (mul sext_16_node:$a, (sext_top_16 GPR:$b))),
  5390. (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
  5391. def : ARMV5MOPat<(add GPR:$acc, (mul (sext_top_16 GPR:$a), sext_16_node:$b)),
  5392. (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
  5393. def : ARMV5TEPat<(int_arm_smulbb GPR:$a, GPR:$b),
  5394. (SMULBB GPR:$a, GPR:$b)>;
  5395. def : ARMV5TEPat<(int_arm_smulbt GPR:$a, GPR:$b),
  5396. (SMULBT GPR:$a, GPR:$b)>;
  5397. def : ARMV5TEPat<(int_arm_smultb GPR:$a, GPR:$b),
  5398. (SMULTB GPR:$a, GPR:$b)>;
  5399. def : ARMV5TEPat<(int_arm_smultt GPR:$a, GPR:$b),
  5400. (SMULTT GPR:$a, GPR:$b)>;
  5401. def : ARMV5TEPat<(int_arm_smulwb GPR:$a, GPR:$b),
  5402. (SMULWB GPR:$a, GPR:$b)>;
  5403. def : ARMV5TEPat<(int_arm_smulwt GPR:$a, GPR:$b),
  5404. (SMULWT GPR:$a, GPR:$b)>;
  5405. def : ARMV5TEPat<(int_arm_smlabb GPR:$a, GPR:$b, GPR:$acc),
  5406. (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
  5407. def : ARMV5TEPat<(int_arm_smlabt GPR:$a, GPR:$b, GPR:$acc),
  5408. (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
  5409. def : ARMV5TEPat<(int_arm_smlatb GPR:$a, GPR:$b, GPR:$acc),
  5410. (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
  5411. def : ARMV5TEPat<(int_arm_smlatt GPR:$a, GPR:$b, GPR:$acc),
  5412. (SMLATT GPR:$a, GPR:$b, GPR:$acc)>;
  5413. def : ARMV5TEPat<(int_arm_smlawb GPR:$a, GPR:$b, GPR:$acc),
  5414. (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
  5415. def : ARMV5TEPat<(int_arm_smlawt GPR:$a, GPR:$b, GPR:$acc),
  5416. (SMLAWT GPR:$a, GPR:$b, GPR:$acc)>;
  5417. // Pre-v7 uses MCR for synchronization barriers.
  5418. def : ARMPat<(ARMMemBarrierMCR GPR:$zero), (MCR 15, 0, GPR:$zero, 7, 10, 5)>,
  5419. Requires<[IsARM, HasV6]>;
  5420. // SXT/UXT with no rotate
  5421. let AddedComplexity = 16 in {
  5422. def : ARMV6Pat<(and GPR:$Src, 0x000000FF), (UXTB GPR:$Src, 0)>;
  5423. def : ARMV6Pat<(and GPR:$Src, 0x0000FFFF), (UXTH GPR:$Src, 0)>;
  5424. def : ARMV6Pat<(and GPR:$Src, 0x00FF00FF), (UXTB16 GPR:$Src, 0)>;
  5425. def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0x00FF)),
  5426. (UXTAB GPR:$Rn, GPR:$Rm, 0)>;
  5427. def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0xFFFF)),
  5428. (UXTAH GPR:$Rn, GPR:$Rm, 0)>;
  5429. }
  5430. def : ARMV6Pat<(sext_inreg GPR:$Src, i8), (SXTB GPR:$Src, 0)>;
  5431. def : ARMV6Pat<(sext_inreg GPR:$Src, i16), (SXTH GPR:$Src, 0)>;
  5432. def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i8)),
  5433. (SXTAB GPR:$Rn, GPRnopc:$Rm, 0)>;
  5434. def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i16)),
  5435. (SXTAH GPR:$Rn, GPRnopc:$Rm, 0)>;
  5436. // Atomic load/store patterns
  5437. def : ARMPat<(atomic_load_8 ldst_so_reg:$src),
  5438. (LDRBrs ldst_so_reg:$src)>;
  5439. def : ARMPat<(atomic_load_8 addrmode_imm12:$src),
  5440. (LDRBi12 addrmode_imm12:$src)>;
  5441. def : ARMPat<(atomic_load_16 addrmode3:$src),
  5442. (LDRH addrmode3:$src)>;
  5443. def : ARMPat<(atomic_load_32 ldst_so_reg:$src),
  5444. (LDRrs ldst_so_reg:$src)>;
  5445. def : ARMPat<(atomic_load_32 addrmode_imm12:$src),
  5446. (LDRi12 addrmode_imm12:$src)>;
  5447. def : ARMPat<(atomic_store_8 ldst_so_reg:$ptr, GPR:$val),
  5448. (STRBrs GPR:$val, ldst_so_reg:$ptr)>;
  5449. def : ARMPat<(atomic_store_8 addrmode_imm12:$ptr, GPR:$val),
  5450. (STRBi12 GPR:$val, addrmode_imm12:$ptr)>;
  5451. def : ARMPat<(atomic_store_16 addrmode3:$ptr, GPR:$val),
  5452. (STRH GPR:$val, addrmode3:$ptr)>;
  5453. def : ARMPat<(atomic_store_32 ldst_so_reg:$ptr, GPR:$val),
  5454. (STRrs GPR:$val, ldst_so_reg:$ptr)>;
  5455. def : ARMPat<(atomic_store_32 addrmode_imm12:$ptr, GPR:$val),
  5456. (STRi12 GPR:$val, addrmode_imm12:$ptr)>;
  5457. //===----------------------------------------------------------------------===//
  5458. // Thumb Support
  5459. //
  5460. include "ARMInstrThumb.td"
  5461. //===----------------------------------------------------------------------===//
  5462. // Thumb2 Support
  5463. //
  5464. include "ARMInstrThumb2.td"
  5465. //===----------------------------------------------------------------------===//
  5466. // Floating Point Support
  5467. //
  5468. include "ARMInstrVFP.td"
  5469. //===----------------------------------------------------------------------===//
  5470. // Advanced SIMD (NEON) Support
  5471. //
  5472. include "ARMInstrNEON.td"
  5473. //===----------------------------------------------------------------------===//
  5474. // MVE Support
  5475. //
  5476. include "ARMInstrMVE.td"
  5477. //===----------------------------------------------------------------------===//
  5478. // CDE (Custom Datapath Extension)
  5479. //
  5480. include "ARMInstrCDE.td"
  5481. //===----------------------------------------------------------------------===//
  5482. // Assembler aliases
  5483. //
  5484. // Memory barriers
  5485. def : InstAlias<"dmb", (DMB 0xf), 0>, Requires<[IsARM, HasDB]>;
  5486. def : InstAlias<"dsb", (DSB 0xf), 0>, Requires<[IsARM, HasDB]>;
  5487. def : InstAlias<"ssbb", (DSB 0x0), 1>, Requires<[IsARM, HasDB]>;
  5488. def : InstAlias<"pssbb", (DSB 0x4), 1>, Requires<[IsARM, HasDB]>;
  5489. def : InstAlias<"isb", (ISB 0xf), 0>, Requires<[IsARM, HasDB]>;
  5490. // Armv8-R 'Data Full Barrier'
  5491. def : InstAlias<"dfb", (DSB 0xc), 1>, Requires<[IsARM, HasDFB]>;
  5492. // System instructions
  5493. def : MnemonicAlias<"swi", "svc">;
  5494. // Load / Store Multiple
  5495. def : MnemonicAlias<"ldmfd", "ldm">;
  5496. def : MnemonicAlias<"ldmia", "ldm">;
  5497. def : MnemonicAlias<"ldmea", "ldmdb">;
  5498. def : MnemonicAlias<"stmfd", "stmdb">;
  5499. def : MnemonicAlias<"stmia", "stm">;
  5500. def : MnemonicAlias<"stmea", "stm">;
  5501. // PKHBT/PKHTB with default shift amount. PKHTB is equivalent to PKHBT with the
  5502. // input operands swapped when the shift amount is zero (i.e., unspecified).
  5503. def : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm",
  5504. (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p), 0>,
  5505. Requires<[IsARM, HasV6]>;
  5506. def : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm",
  5507. (PKHBT GPRnopc:$Rd, GPRnopc:$Rm, GPRnopc:$Rn, 0, pred:$p), 0>,
  5508. Requires<[IsARM, HasV6]>;
  5509. // PUSH/POP aliases for STM/LDM
  5510. def : ARMInstAlias<"push${p} $regs", (STMDB_UPD SP, pred:$p, reglist:$regs)>;
  5511. def : ARMInstAlias<"pop${p} $regs", (LDMIA_UPD SP, pred:$p, reglist:$regs)>;
  5512. // SSAT/USAT optional shift operand.
  5513. def : ARMInstAlias<"ssat${p} $Rd, $sat_imm, $Rn",
  5514. (SSAT GPRnopc:$Rd, imm1_32:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>;
  5515. def : ARMInstAlias<"usat${p} $Rd, $sat_imm, $Rn",
  5516. (USAT GPRnopc:$Rd, imm0_31:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>;
  5517. // Extend instruction optional rotate operand.
  5518. def : ARMInstAlias<"sxtab${p} $Rd, $Rn, $Rm",
  5519. (SXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
  5520. def : ARMInstAlias<"sxtah${p} $Rd, $Rn, $Rm",
  5521. (SXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
  5522. def : ARMInstAlias<"sxtab16${p} $Rd, $Rn, $Rm",
  5523. (SXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
  5524. def : ARMInstAlias<"sxtb${p} $Rd, $Rm",
  5525. (SXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
  5526. def : ARMInstAlias<"sxtb16${p} $Rd, $Rm",
  5527. (SXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
  5528. def : ARMInstAlias<"sxth${p} $Rd, $Rm",
  5529. (SXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
  5530. def : ARMInstAlias<"uxtab${p} $Rd, $Rn, $Rm",
  5531. (UXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
  5532. def : ARMInstAlias<"uxtah${p} $Rd, $Rn, $Rm",
  5533. (UXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
  5534. def : ARMInstAlias<"uxtab16${p} $Rd, $Rn, $Rm",
  5535. (UXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>;
  5536. def : ARMInstAlias<"uxtb${p} $Rd, $Rm",
  5537. (UXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
  5538. def : ARMInstAlias<"uxtb16${p} $Rd, $Rm",
  5539. (UXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
  5540. def : ARMInstAlias<"uxth${p} $Rd, $Rm",
  5541. (UXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>;
  5542. // RFE aliases
  5543. def : MnemonicAlias<"rfefa", "rfeda">;
  5544. def : MnemonicAlias<"rfeea", "rfedb">;
  5545. def : MnemonicAlias<"rfefd", "rfeia">;
  5546. def : MnemonicAlias<"rfeed", "rfeib">;
  5547. def : MnemonicAlias<"rfe", "rfeia">;
  5548. // SRS aliases
  5549. def : MnemonicAlias<"srsfa", "srsib">;
  5550. def : MnemonicAlias<"srsea", "srsia">;
  5551. def : MnemonicAlias<"srsfd", "srsdb">;
  5552. def : MnemonicAlias<"srsed", "srsda">;
  5553. def : MnemonicAlias<"srs", "srsia">;
  5554. // QSAX == QSUBADDX
  5555. def : MnemonicAlias<"qsubaddx", "qsax">;
  5556. // SASX == SADDSUBX
  5557. def : MnemonicAlias<"saddsubx", "sasx">;
  5558. // SHASX == SHADDSUBX
  5559. def : MnemonicAlias<"shaddsubx", "shasx">;
  5560. // SHSAX == SHSUBADDX
  5561. def : MnemonicAlias<"shsubaddx", "shsax">;
  5562. // SSAX == SSUBADDX
  5563. def : MnemonicAlias<"ssubaddx", "ssax">;
  5564. // UASX == UADDSUBX
  5565. def : MnemonicAlias<"uaddsubx", "uasx">;
  5566. // UHASX == UHADDSUBX
  5567. def : MnemonicAlias<"uhaddsubx", "uhasx">;
  5568. // UHSAX == UHSUBADDX
  5569. def : MnemonicAlias<"uhsubaddx", "uhsax">;
  5570. // UQASX == UQADDSUBX
  5571. def : MnemonicAlias<"uqaddsubx", "uqasx">;
  5572. // UQSAX == UQSUBADDX
  5573. def : MnemonicAlias<"uqsubaddx", "uqsax">;
  5574. // USAX == USUBADDX
  5575. def : MnemonicAlias<"usubaddx", "usax">;
  5576. // "mov Rd, mod_imm_not" can be handled via "mvn" in assembly, just like
  5577. // for isel.
  5578. def : ARMInstSubst<"mov${s}${p} $Rd, $imm",
  5579. (MVNi rGPR:$Rd, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
  5580. def : ARMInstSubst<"mvn${s}${p} $Rd, $imm",
  5581. (MOVi rGPR:$Rd, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
  5582. // Same for AND <--> BIC
  5583. def : ARMInstSubst<"bic${s}${p} $Rd, $Rn, $imm",
  5584. (ANDri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm,
  5585. pred:$p, cc_out:$s)>;
  5586. def : ARMInstSubst<"bic${s}${p} $Rdn, $imm",
  5587. (ANDri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm,
  5588. pred:$p, cc_out:$s)>;
  5589. def : ARMInstSubst<"and${s}${p} $Rd, $Rn, $imm",
  5590. (BICri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm,
  5591. pred:$p, cc_out:$s)>;
  5592. def : ARMInstSubst<"and${s}${p} $Rdn, $imm",
  5593. (BICri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm,
  5594. pred:$p, cc_out:$s)>;
  5595. // Likewise, "add Rd, mod_imm_neg" -> sub
  5596. def : ARMInstSubst<"add${s}${p} $Rd, $Rn, $imm",
  5597. (SUBri GPR:$Rd, GPR:$Rn, mod_imm_neg:$imm, pred:$p, cc_out:$s)>;
  5598. def : ARMInstSubst<"add${s}${p} $Rd, $imm",
  5599. (SUBri GPR:$Rd, GPR:$Rd, mod_imm_neg:$imm, pred:$p, cc_out:$s)>;
  5600. // Likewise, "sub Rd, mod_imm_neg" -> add
  5601. def : ARMInstSubst<"sub${s}${p} $Rd, $Rn, $imm",
  5602. (ADDri GPR:$Rd, GPR:$Rn, mod_imm_neg:$imm, pred:$p, cc_out:$s)>;
  5603. def : ARMInstSubst<"sub${s}${p} $Rd, $imm",
  5604. (ADDri GPR:$Rd, GPR:$Rd, mod_imm_neg:$imm, pred:$p, cc_out:$s)>;
  5605. def : ARMInstSubst<"adc${s}${p} $Rd, $Rn, $imm",
  5606. (SBCri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
  5607. def : ARMInstSubst<"adc${s}${p} $Rdn, $imm",
  5608. (SBCri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
  5609. def : ARMInstSubst<"sbc${s}${p} $Rd, $Rn, $imm",
  5610. (ADCri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
  5611. def : ARMInstSubst<"sbc${s}${p} $Rdn, $imm",
  5612. (ADCri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
  5613. // Same for CMP <--> CMN via mod_imm_neg
  5614. def : ARMInstSubst<"cmp${p} $Rd, $imm",
  5615. (CMNri rGPR:$Rd, mod_imm_neg:$imm, pred:$p)>;
  5616. def : ARMInstSubst<"cmn${p} $Rd, $imm",
  5617. (CMPri rGPR:$Rd, mod_imm_neg:$imm, pred:$p)>;
  5618. // The shifter forms of the MOV instruction are aliased to the ASR, LSL,
  5619. // LSR, ROR, and RRX instructions.
  5620. // FIXME: We need C++ parser hooks to map the alias to the MOV
  5621. // encoding. It seems we should be able to do that sort of thing
  5622. // in tblgen, but it could get ugly.
  5623. let TwoOperandAliasConstraint = "$Rm = $Rd" in {
  5624. def ASRi : ARMAsmPseudo<"asr${s}${p} $Rd, $Rm, $imm",
  5625. (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p,
  5626. cc_out:$s)>;
  5627. def LSRi : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rm, $imm",
  5628. (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p,
  5629. cc_out:$s)>;
  5630. def LSLi : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rm, $imm",
  5631. (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p,
  5632. cc_out:$s)>;
  5633. def RORi : ARMAsmPseudo<"ror${s}${p} $Rd, $Rm, $imm",
  5634. (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p,
  5635. cc_out:$s)>;
  5636. }
  5637. def RRXi : ARMAsmPseudo<"rrx${s}${p} $Rd, $Rm",
  5638. (ins GPR:$Rd, GPR:$Rm, pred:$p, cc_out:$s)>;
  5639. let TwoOperandAliasConstraint = "$Rn = $Rd" in {
  5640. def ASRr : ARMAsmPseudo<"asr${s}${p} $Rd, $Rn, $Rm",
  5641. (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
  5642. cc_out:$s)>;
  5643. def LSRr : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rn, $Rm",
  5644. (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
  5645. cc_out:$s)>;
  5646. def LSLr : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rn, $Rm",
  5647. (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
  5648. cc_out:$s)>;
  5649. def RORr : ARMAsmPseudo<"ror${s}${p} $Rd, $Rn, $Rm",
  5650. (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p,
  5651. cc_out:$s)>;
  5652. }
  5653. // "neg" is and alias for "rsb rd, rn, #0"
  5654. def : ARMInstAlias<"neg${s}${p} $Rd, $Rm",
  5655. (RSBri GPR:$Rd, GPR:$Rm, 0, pred:$p, cc_out:$s)>;
  5656. // Pre-v6, 'mov r0, r0' was used as a NOP encoding.
  5657. def : InstAlias<"nop${p}", (MOVr R0, R0, pred:$p, zero_reg), 0>,
  5658. Requires<[IsARM, NoV6]>;
  5659. // MUL/UMLAL/SMLAL/UMULL/SMULL are available on all arches, but
  5660. // the instruction definitions need difference constraints pre-v6.
  5661. // Use these aliases for the assembly parsing on pre-v6.
  5662. def : InstAlias<"mul${s}${p} $Rd, $Rn, $Rm",
  5663. (MUL GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, cc_out:$s), 0>,
  5664. Requires<[IsARM, NoV6]>;
  5665. def : InstAlias<"mla${s}${p} $Rd, $Rn, $Rm, $Ra",
  5666. (MLA GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra,
  5667. pred:$p, cc_out:$s), 0>,
  5668. Requires<[IsARM, NoV6]>;
  5669. def : InstAlias<"smlal${s}${p} $RdLo, $RdHi, $Rn, $Rm",
  5670. (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>,
  5671. Requires<[IsARM, NoV6]>;
  5672. def : InstAlias<"umlal${s}${p} $RdLo, $RdHi, $Rn, $Rm",
  5673. (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>,
  5674. Requires<[IsARM, NoV6]>;
  5675. def : InstAlias<"smull${s}${p} $RdLo, $RdHi, $Rn, $Rm",
  5676. (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>,
  5677. Requires<[IsARM, NoV6]>;
  5678. def : InstAlias<"umull${s}${p} $RdLo, $RdHi, $Rn, $Rm",
  5679. (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>,
  5680. Requires<[IsARM, NoV6]>;
  5681. // 'it' blocks in ARM mode just validate the predicates. The IT itself
  5682. // is discarded.
  5683. def ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>;
  5684. let mayLoad = 1, mayStore =1, hasSideEffects = 1, hasNoSchedulingInfo = 1 in
  5685. def SPACE : PseudoInst<(outs GPR:$Rd), (ins i32imm:$size, GPR:$Rn),
  5686. NoItinerary,
  5687. [(set GPR:$Rd, (int_arm_space timm:$size, GPR:$Rn))]>;
  5688. // SpeculationBarrierEndBB must only be used after an unconditional control
  5689. // flow, i.e. after a terminator for which isBarrier is True.
  5690. let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
  5691. // This gets lowered to a pair of 4-byte instructions
  5692. let Size = 8 in
  5693. def SpeculationBarrierISBDSBEndBB
  5694. : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
  5695. // This gets lowered to a single 4-byte instructions
  5696. let Size = 4 in
  5697. def SpeculationBarrierSBEndBB
  5698. : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
  5699. }
  5700. //===----------------------------------
  5701. // Atomic cmpxchg for -O0
  5702. //===----------------------------------
  5703. // The fast register allocator used during -O0 inserts spills to cover any VRegs
  5704. // live across basic block boundaries. When this happens between an LDXR and an
  5705. // STXR it can clear the exclusive monitor, causing all cmpxchg attempts to
  5706. // fail.
  5707. // Unfortunately, this means we have to have an alternative (expanded
  5708. // post-regalloc) path for -O0 compilations. Fortunately this path can be
  5709. // significantly more naive than the standard expansion: we conservatively
  5710. // assume seq_cst, strong cmpxchg and omit clrex on failure.
  5711. let Constraints = "@earlyclobber $Rd,@earlyclobber $temp",
  5712. mayLoad = 1, mayStore = 1 in {
  5713. def CMP_SWAP_8 : PseudoInst<(outs GPR:$Rd, GPR:$temp),
  5714. (ins GPR:$addr, GPR:$desired, GPR:$new),
  5715. NoItinerary, []>, Sched<[]>;
  5716. def CMP_SWAP_16 : PseudoInst<(outs GPR:$Rd, GPR:$temp),
  5717. (ins GPR:$addr, GPR:$desired, GPR:$new),
  5718. NoItinerary, []>, Sched<[]>;
  5719. def CMP_SWAP_32 : PseudoInst<(outs GPR:$Rd, GPR:$temp),
  5720. (ins GPR:$addr, GPR:$desired, GPR:$new),
  5721. NoItinerary, []>, Sched<[]>;
  5722. def CMP_SWAP_64 : PseudoInst<(outs GPRPair:$Rd, GPR:$temp),
  5723. (ins GPR:$addr, GPRPair:$desired, GPRPair:$new),
  5724. NoItinerary, []>, Sched<[]>;
  5725. }
  5726. def : Pat<(atomic_fence (timm), 0), (MEMBARRIER)>;
  5727. //===----------------------------------------------------------------------===//
  5728. // Instructions used for emitting unwind opcodes on Windows.
  5729. //===----------------------------------------------------------------------===//
  5730. let isPseudo = 1 in {
  5731. def SEH_StackAlloc : PseudoInst<(outs), (ins i32imm:$size, i32imm:$wide), NoItinerary, []>, Sched<[]>;
  5732. def SEH_SaveRegs : PseudoInst<(outs), (ins i32imm:$mask, i32imm:$wide), NoItinerary, []>, Sched<[]>;
  5733. let isTerminator = 1 in
  5734. def SEH_SaveRegs_Ret : PseudoInst<(outs), (ins i32imm:$mask, i32imm:$wide), NoItinerary, []>, Sched<[]>;
  5735. def SEH_SaveSP : PseudoInst<(outs), (ins i32imm:$reg), NoItinerary, []>, Sched<[]>;
  5736. def SEH_SaveFRegs : PseudoInst<(outs), (ins i32imm:$first, i32imm:$last), NoItinerary, []>, Sched<[]>;
  5737. let isTerminator = 1 in
  5738. def SEH_SaveLR : PseudoInst<(outs), (ins i32imm:$offst), NoItinerary, []>, Sched<[]>;
  5739. def SEH_Nop : PseudoInst<(outs), (ins i32imm:$wide), NoItinerary, []>, Sched<[]>;
  5740. let isTerminator = 1 in
  5741. def SEH_Nop_Ret : PseudoInst<(outs), (ins i32imm:$wide), NoItinerary, []>, Sched<[]>;
  5742. def SEH_PrologEnd : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
  5743. def SEH_EpilogStart : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
  5744. let isTerminator = 1 in
  5745. def SEH_EpilogEnd : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
  5746. }