ARMInstrInfo.td 248 KB

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