AArch64InstrFormats.td 439 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504
  1. //===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===//
  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. // Describe AArch64 instructions format here
  10. //
  11. // Format specifies the encoding used by the instruction. This is part of the
  12. // ad-hoc solution used to emit machine instruction encodings by our machine
  13. // code emitter.
  14. class Format<bits<2> val> {
  15. bits<2> Value = val;
  16. }
  17. def PseudoFrm : Format<0>;
  18. def NormalFrm : Format<1>; // Do we need any others?
  19. // Enum describing whether an instruction is
  20. // destructive in its first source operand.
  21. class DestructiveInstTypeEnum<bits<4> val> {
  22. bits<4> Value = val;
  23. }
  24. def NotDestructive : DestructiveInstTypeEnum<0>;
  25. // Destructive in its first operand and can be MOVPRFX'd, but has no other
  26. // special properties.
  27. def DestructiveOther : DestructiveInstTypeEnum<1>;
  28. def DestructiveUnary : DestructiveInstTypeEnum<2>;
  29. def DestructiveBinaryImm : DestructiveInstTypeEnum<3>;
  30. def DestructiveBinaryShImmUnpred : DestructiveInstTypeEnum<4>;
  31. def DestructiveBinary : DestructiveInstTypeEnum<5>;
  32. def DestructiveBinaryComm : DestructiveInstTypeEnum<6>;
  33. def DestructiveBinaryCommWithRev : DestructiveInstTypeEnum<7>;
  34. def DestructiveTernaryCommWithRev : DestructiveInstTypeEnum<8>;
  35. def DestructiveUnaryPassthru : DestructiveInstTypeEnum<9>;
  36. class FalseLanesEnum<bits<2> val> {
  37. bits<2> Value = val;
  38. }
  39. def FalseLanesNone : FalseLanesEnum<0>;
  40. def FalseLanesZero : FalseLanesEnum<1>;
  41. def FalseLanesUndef : FalseLanesEnum<2>;
  42. // AArch64 Instruction Format
  43. class AArch64Inst<Format f, string cstr> : Instruction {
  44. field bits<32> Inst; // Instruction encoding.
  45. // Mask of bits that cause an encoding to be UNPREDICTABLE.
  46. // If a bit is set, then if the corresponding bit in the
  47. // target encoding differs from its value in the "Inst" field,
  48. // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
  49. field bits<32> Unpredictable = 0;
  50. // SoftFail is the generic name for this field, but we alias it so
  51. // as to make it more obvious what it means in ARM-land.
  52. field bits<32> SoftFail = Unpredictable;
  53. let Namespace = "AArch64";
  54. Format F = f;
  55. bits<2> Form = F.Value;
  56. // Defaults
  57. bit isWhile = 0;
  58. bit isPTestLike = 0;
  59. FalseLanesEnum FalseLanes = FalseLanesNone;
  60. DestructiveInstTypeEnum DestructiveInstType = NotDestructive;
  61. ElementSizeEnum ElementSize = ElementSizeNone;
  62. let TSFlags{10} = isPTestLike;
  63. let TSFlags{9} = isWhile;
  64. let TSFlags{8-7} = FalseLanes.Value;
  65. let TSFlags{6-3} = DestructiveInstType.Value;
  66. let TSFlags{2-0} = ElementSize.Value;
  67. let Pattern = [];
  68. let Constraints = cstr;
  69. }
  70. class InstSubst<string Asm, dag Result, bit EmitPriority = 0>
  71. : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>;
  72. // Pseudo instructions (don't have encoding information)
  73. class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
  74. : AArch64Inst<PseudoFrm, cstr> {
  75. dag OutOperandList = oops;
  76. dag InOperandList = iops;
  77. let Pattern = pattern;
  78. let isCodeGenOnly = 1;
  79. let isPseudo = 1;
  80. }
  81. // Real instructions (have encoding information)
  82. class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
  83. let Pattern = pattern;
  84. let Size = 4;
  85. }
  86. // Normal instructions
  87. class I<dag oops, dag iops, string asm, string operands, string cstr,
  88. list<dag> pattern>
  89. : EncodedI<cstr, pattern> {
  90. dag OutOperandList = oops;
  91. dag InOperandList = iops;
  92. let AsmString = !strconcat(asm, operands);
  93. }
  94. class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
  95. class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
  96. class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>;
  97. // Helper fragment for an extract of the high portion of a 128-bit vector.
  98. def extract_high_v16i8 :
  99. UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>;
  100. def extract_high_v8i16 :
  101. UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>;
  102. def extract_high_v4i32 :
  103. UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>;
  104. def extract_high_v2i64 :
  105. UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>;
  106. //===----------------------------------------------------------------------===//
  107. // Asm Operand Classes.
  108. //
  109. // Shifter operand for arithmetic shifted encodings.
  110. def ShifterOperand : AsmOperandClass {
  111. let Name = "Shifter";
  112. }
  113. // Shifter operand for mov immediate encodings.
  114. def MovImm32ShifterOperand : AsmOperandClass {
  115. let SuperClasses = [ShifterOperand];
  116. let Name = "MovImm32Shifter";
  117. let RenderMethod = "addShifterOperands";
  118. let DiagnosticType = "InvalidMovImm32Shift";
  119. }
  120. def MovImm64ShifterOperand : AsmOperandClass {
  121. let SuperClasses = [ShifterOperand];
  122. let Name = "MovImm64Shifter";
  123. let RenderMethod = "addShifterOperands";
  124. let DiagnosticType = "InvalidMovImm64Shift";
  125. }
  126. // Shifter operand for arithmetic register shifted encodings.
  127. class ArithmeticShifterOperand<int width> : AsmOperandClass {
  128. let SuperClasses = [ShifterOperand];
  129. let Name = "ArithmeticShifter" # width;
  130. let PredicateMethod = "isArithmeticShifter<" # width # ">";
  131. let RenderMethod = "addShifterOperands";
  132. let DiagnosticType = "AddSubRegShift" # width;
  133. }
  134. def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
  135. def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
  136. // Shifter operand for logical register shifted encodings.
  137. class LogicalShifterOperand<int width> : AsmOperandClass {
  138. let SuperClasses = [ShifterOperand];
  139. let Name = "LogicalShifter" # width;
  140. let PredicateMethod = "isLogicalShifter<" # width # ">";
  141. let RenderMethod = "addShifterOperands";
  142. let DiagnosticType = "AddSubRegShift" # width;
  143. }
  144. def LogicalShifterOperand32 : LogicalShifterOperand<32>;
  145. def LogicalShifterOperand64 : LogicalShifterOperand<64>;
  146. // Shifter operand for logical vector 128/64-bit shifted encodings.
  147. def LogicalVecShifterOperand : AsmOperandClass {
  148. let SuperClasses = [ShifterOperand];
  149. let Name = "LogicalVecShifter";
  150. let RenderMethod = "addShifterOperands";
  151. }
  152. def LogicalVecHalfWordShifterOperand : AsmOperandClass {
  153. let SuperClasses = [LogicalVecShifterOperand];
  154. let Name = "LogicalVecHalfWordShifter";
  155. let RenderMethod = "addShifterOperands";
  156. }
  157. // The "MSL" shifter on the vector MOVI instruction.
  158. def MoveVecShifterOperand : AsmOperandClass {
  159. let SuperClasses = [ShifterOperand];
  160. let Name = "MoveVecShifter";
  161. let RenderMethod = "addShifterOperands";
  162. }
  163. // Extend operand for arithmetic encodings.
  164. def ExtendOperand : AsmOperandClass {
  165. let Name = "Extend";
  166. let DiagnosticType = "AddSubRegExtendLarge";
  167. }
  168. def ExtendOperand64 : AsmOperandClass {
  169. let SuperClasses = [ExtendOperand];
  170. let Name = "Extend64";
  171. let DiagnosticType = "AddSubRegExtendSmall";
  172. }
  173. // 'extend' that's a lsl of a 64-bit register.
  174. def ExtendOperandLSL64 : AsmOperandClass {
  175. let SuperClasses = [ExtendOperand];
  176. let Name = "ExtendLSL64";
  177. let RenderMethod = "addExtend64Operands";
  178. let DiagnosticType = "AddSubRegExtendLarge";
  179. }
  180. // 8-bit floating-point immediate encodings.
  181. def FPImmOperand : AsmOperandClass {
  182. let Name = "FPImm";
  183. let ParserMethod = "tryParseFPImm<true>";
  184. let DiagnosticType = "InvalidFPImm";
  185. }
  186. def CondCode : AsmOperandClass {
  187. let Name = "CondCode";
  188. let DiagnosticType = "InvalidCondCode";
  189. }
  190. // A 32-bit register pasrsed as 64-bit
  191. def GPR32as64Operand : AsmOperandClass {
  192. let Name = "GPR32as64";
  193. let ParserMethod =
  194. "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>";
  195. }
  196. def GPR32as64 : RegisterOperand<GPR32> {
  197. let ParserMatchClass = GPR32as64Operand;
  198. }
  199. // A 64-bit register pasrsed as 32-bit
  200. def GPR64as32Operand : AsmOperandClass {
  201. let Name = "GPR64as32";
  202. let ParserMethod =
  203. "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>";
  204. }
  205. def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> {
  206. let ParserMatchClass = GPR64as32Operand;
  207. }
  208. // 8-bit immediate for AdvSIMD where 64-bit values of the form:
  209. // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
  210. // are encoded as the eight bit value 'abcdefgh'.
  211. def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
  212. class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
  213. let Name = "UImm" # Width # "s" # Scale;
  214. let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width;
  215. let RenderMethod = "addImmScaledOperands<" # Scale # ">";
  216. let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">";
  217. }
  218. class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
  219. let Name = "SImm" # Width # "s" # Scale;
  220. let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width;
  221. let RenderMethod = "addImmScaledOperands<" # Scale # ">";
  222. let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">";
  223. }
  224. //===----------------------------------------------------------------------===//
  225. // Operand Definitions.
  226. //
  227. // ADR[P] instruction labels.
  228. def AdrpOperand : AsmOperandClass {
  229. let Name = "AdrpLabel";
  230. let ParserMethod = "tryParseAdrpLabel";
  231. let DiagnosticType = "InvalidLabel";
  232. }
  233. def adrplabel : Operand<i64> {
  234. let EncoderMethod = "getAdrLabelOpValue";
  235. let PrintMethod = "printAdrpLabel";
  236. let ParserMatchClass = AdrpOperand;
  237. let OperandType = "OPERAND_PCREL";
  238. }
  239. def AdrOperand : AsmOperandClass {
  240. let Name = "AdrLabel";
  241. let ParserMethod = "tryParseAdrLabel";
  242. let DiagnosticType = "InvalidLabel";
  243. }
  244. def adrlabel : Operand<i64> {
  245. let EncoderMethod = "getAdrLabelOpValue";
  246. let ParserMatchClass = AdrOperand;
  247. }
  248. class SImmOperand<int width> : AsmOperandClass {
  249. let Name = "SImm" # width;
  250. let DiagnosticType = "InvalidMemoryIndexedSImm" # width;
  251. let RenderMethod = "addImmOperands";
  252. let PredicateMethod = "isSImm<" # width # ">";
  253. }
  254. class AsmImmRange<int Low, int High> : AsmOperandClass {
  255. let Name = "Imm" # Low # "_" # High;
  256. let DiagnosticType = "InvalidImm" # Low # "_" # High;
  257. let RenderMethod = "addImmOperands";
  258. let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";
  259. }
  260. // Authenticated loads for v8.3 can have scaled 10-bit immediate offsets.
  261. def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>;
  262. def simm10Scaled : Operand<i64> {
  263. let ParserMatchClass = SImm10s8Operand;
  264. let DecoderMethod = "DecodeSImm<10>";
  265. let PrintMethod = "printImmScale<8>";
  266. }
  267. def simm9s16 : Operand<i64> {
  268. let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>;
  269. let DecoderMethod = "DecodeSImm<9>";
  270. let PrintMethod = "printImmScale<16>";
  271. }
  272. // uimm6 predicate - True if the immediate is in the range [0, 63].
  273. def UImm6Operand : AsmOperandClass {
  274. let Name = "UImm6";
  275. let DiagnosticType = "InvalidImm0_63";
  276. }
  277. def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
  278. let ParserMatchClass = UImm6Operand;
  279. }
  280. def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{
  281. let ParserMatchClass = AsmImmRange<0, 65535>;
  282. }
  283. def SImm9Operand : SImmOperand<9>;
  284. def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
  285. let ParserMatchClass = SImm9Operand;
  286. let DecoderMethod = "DecodeSImm<9>";
  287. }
  288. def SImm8Operand : SImmOperand<8>;
  289. def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> {
  290. let ParserMatchClass = SImm8Operand;
  291. let DecoderMethod = "DecodeSImm<8>";
  292. }
  293. def SImm6Operand : SImmOperand<6>;
  294. def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> {
  295. let ParserMatchClass = SImm6Operand;
  296. let DecoderMethod = "DecodeSImm<6>";
  297. }
  298. def SImm5Operand : SImmOperand<5>;
  299. def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> {
  300. let ParserMatchClass = SImm5Operand;
  301. let DecoderMethod = "DecodeSImm<5>";
  302. }
  303. def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> {
  304. let ParserMatchClass = SImm5Operand;
  305. let DecoderMethod = "DecodeSImm<5>";
  306. }
  307. def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> {
  308. let ParserMatchClass = SImm5Operand;
  309. let DecoderMethod = "DecodeSImm<5>";
  310. let PrintMethod = "printSImm<8>";
  311. }
  312. def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> {
  313. let ParserMatchClass = SImm5Operand;
  314. let DecoderMethod = "DecodeSImm<5>";
  315. let PrintMethod = "printSImm<16>";
  316. }
  317. // simm7sN predicate - True if the immediate is a multiple of N in the range
  318. // [-64 * N, 63 * N].
  319. def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>;
  320. def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>;
  321. def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>;
  322. def simm7s4 : Operand<i32> {
  323. let ParserMatchClass = SImm7s4Operand;
  324. let PrintMethod = "printImmScale<4>";
  325. }
  326. def simm7s8 : Operand<i32> {
  327. let ParserMatchClass = SImm7s8Operand;
  328. let PrintMethod = "printImmScale<8>";
  329. }
  330. def simm7s16 : Operand<i32> {
  331. let ParserMatchClass = SImm7s16Operand;
  332. let PrintMethod = "printImmScale<16>";
  333. }
  334. def am_sve_fi : ComplexPattern<iPTR, 2, "SelectAddrModeFrameIndexSVE", []>;
  335. def am_indexed7s8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S8", []>;
  336. def am_indexed7s16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S16", []>;
  337. def am_indexed7s32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S32", []>;
  338. def am_indexed7s64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S64", []>;
  339. def am_indexed7s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S128", []>;
  340. def am_indexedu6s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedU6S128", []>;
  341. def am_indexeds9s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedS9S128", []>;
  342. def UImmS1XForm : SDNodeXForm<imm, [{
  343. return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64);
  344. }]>;
  345. def UImmS2XForm : SDNodeXForm<imm, [{
  346. return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64);
  347. }]>;
  348. def UImmS4XForm : SDNodeXForm<imm, [{
  349. return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64);
  350. }]>;
  351. def UImmS8XForm : SDNodeXForm<imm, [{
  352. return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64);
  353. }]>;
  354. // uimm5sN predicate - True if the immediate is a multiple of N in the range
  355. // [0 * N, 32 * N].
  356. def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>;
  357. def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>;
  358. def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>;
  359. def uimm5s2 : Operand<i64>, ImmLeaf<i64,
  360. [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
  361. UImmS2XForm> {
  362. let ParserMatchClass = UImm5s2Operand;
  363. let PrintMethod = "printImmScale<2>";
  364. }
  365. def uimm5s4 : Operand<i64>, ImmLeaf<i64,
  366. [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
  367. UImmS4XForm> {
  368. let ParserMatchClass = UImm5s4Operand;
  369. let PrintMethod = "printImmScale<4>";
  370. }
  371. def uimm5s8 : Operand<i64>, ImmLeaf<i64,
  372. [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
  373. UImmS8XForm> {
  374. let ParserMatchClass = UImm5s8Operand;
  375. let PrintMethod = "printImmScale<8>";
  376. }
  377. // tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant)
  378. // instead of ImmLeaf (Constant)
  379. def tuimm5s2 : Operand<i64>, TImmLeaf<i64,
  380. [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],
  381. UImmS2XForm> {
  382. let ParserMatchClass = UImm5s2Operand;
  383. let PrintMethod = "printImmScale<2>";
  384. }
  385. def tuimm5s4 : Operand<i64>, TImmLeaf<i64,
  386. [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
  387. UImmS4XForm> {
  388. let ParserMatchClass = UImm5s4Operand;
  389. let PrintMethod = "printImmScale<4>";
  390. }
  391. def tuimm5s8 : Operand<i64>, TImmLeaf<i64,
  392. [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
  393. UImmS8XForm> {
  394. let ParserMatchClass = UImm5s8Operand;
  395. let PrintMethod = "printImmScale<8>";
  396. }
  397. // uimm6sN predicate - True if the immediate is a multiple of N in the range
  398. // [0 * N, 64 * N].
  399. def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>;
  400. def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>;
  401. def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>;
  402. def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>;
  403. def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>;
  404. def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
  405. let ParserMatchClass = UImm6s1Operand;
  406. }
  407. def uimm6s2 : Operand<i64>, ImmLeaf<i64,
  408. [{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> {
  409. let PrintMethod = "printImmScale<2>";
  410. let ParserMatchClass = UImm6s2Operand;
  411. }
  412. def uimm6s4 : Operand<i64>, ImmLeaf<i64,
  413. [{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> {
  414. let PrintMethod = "printImmScale<4>";
  415. let ParserMatchClass = UImm6s4Operand;
  416. }
  417. def uimm6s8 : Operand<i64>, ImmLeaf<i64,
  418. [{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> {
  419. let PrintMethod = "printImmScale<8>";
  420. let ParserMatchClass = UImm6s8Operand;
  421. }
  422. def uimm6s16 : Operand<i64>, ImmLeaf<i64,
  423. [{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> {
  424. let PrintMethod = "printImmScale<16>";
  425. let ParserMatchClass = UImm6s16Operand;
  426. }
  427. def SImmS2XForm : SDNodeXForm<imm, [{
  428. return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64);
  429. }]>;
  430. def SImmS3XForm : SDNodeXForm<imm, [{
  431. return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64);
  432. }]>;
  433. def SImmS4XForm : SDNodeXForm<imm, [{
  434. return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64);
  435. }]>;
  436. def SImmS16XForm : SDNodeXForm<imm, [{
  437. return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64);
  438. }]>;
  439. def SImmS32XForm : SDNodeXForm<imm, [{
  440. return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64);
  441. }]>;
  442. // simm6sN predicate - True if the immediate is a multiple of N in the range
  443. // [-32 * N, 31 * N].
  444. def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>;
  445. def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> {
  446. let ParserMatchClass = SImm6s1Operand;
  447. let DecoderMethod = "DecodeSImm<6>";
  448. }
  449. // simm4sN predicate - True if the immediate is a multiple of N in the range
  450. // [ -8* N, 7 * N].
  451. def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>;
  452. def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>;
  453. def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>;
  454. def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>;
  455. def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>;
  456. def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>;
  457. def simm4s1 : Operand<i64>, ImmLeaf<i64,
  458. [{ return Imm >=-8 && Imm <= 7; }]> {
  459. let ParserMatchClass = SImm4s1Operand;
  460. let DecoderMethod = "DecodeSImm<4>";
  461. }
  462. def simm4s2 : Operand<i64>, ImmLeaf<i64,
  463. [{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> {
  464. let PrintMethod = "printImmScale<2>";
  465. let ParserMatchClass = SImm4s2Operand;
  466. let DecoderMethod = "DecodeSImm<4>";
  467. }
  468. def simm4s3 : Operand<i64>, ImmLeaf<i64,
  469. [{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> {
  470. let PrintMethod = "printImmScale<3>";
  471. let ParserMatchClass = SImm4s3Operand;
  472. let DecoderMethod = "DecodeSImm<4>";
  473. }
  474. def simm4s4 : Operand<i64>, ImmLeaf<i64,
  475. [{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> {
  476. let PrintMethod = "printImmScale<4>";
  477. let ParserMatchClass = SImm4s4Operand;
  478. let DecoderMethod = "DecodeSImm<4>";
  479. }
  480. def simm4s16 : Operand<i64>, ImmLeaf<i64,
  481. [{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> {
  482. let PrintMethod = "printImmScale<16>";
  483. let ParserMatchClass = SImm4s16Operand;
  484. let DecoderMethod = "DecodeSImm<4>";
  485. }
  486. def simm4s32 : Operand<i64>, ImmLeaf<i64,
  487. [{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> {
  488. let PrintMethod = "printImmScale<32>";
  489. let ParserMatchClass = SImm4s32Operand;
  490. let DecoderMethod = "DecodeSImm<4>";
  491. }
  492. def Imm1_8Operand : AsmImmRange<1, 8>;
  493. def Imm1_16Operand : AsmImmRange<1, 16>;
  494. def Imm1_32Operand : AsmImmRange<1, 32>;
  495. def Imm1_64Operand : AsmImmRange<1, 64>;
  496. class BranchTarget<int N> : AsmOperandClass {
  497. let Name = "BranchTarget" # N;
  498. let DiagnosticType = "InvalidLabel";
  499. let PredicateMethod = "isBranchTarget<" # N # ">";
  500. }
  501. class PCRelLabel<int N> : BranchTarget<N> {
  502. let Name = "PCRelLabel" # N;
  503. }
  504. def BranchTarget14Operand : BranchTarget<14>;
  505. def BranchTarget26Operand : BranchTarget<26>;
  506. def PCRelLabel19Operand : PCRelLabel<19>;
  507. def MovWSymbolG3AsmOperand : AsmOperandClass {
  508. let Name = "MovWSymbolG3";
  509. let RenderMethod = "addImmOperands";
  510. }
  511. def movw_symbol_g3 : Operand<i32> {
  512. let ParserMatchClass = MovWSymbolG3AsmOperand;
  513. }
  514. def MovWSymbolG2AsmOperand : AsmOperandClass {
  515. let Name = "MovWSymbolG2";
  516. let RenderMethod = "addImmOperands";
  517. }
  518. def movw_symbol_g2 : Operand<i32> {
  519. let ParserMatchClass = MovWSymbolG2AsmOperand;
  520. }
  521. def MovWSymbolG1AsmOperand : AsmOperandClass {
  522. let Name = "MovWSymbolG1";
  523. let RenderMethod = "addImmOperands";
  524. }
  525. def movw_symbol_g1 : Operand<i32> {
  526. let ParserMatchClass = MovWSymbolG1AsmOperand;
  527. }
  528. def MovWSymbolG0AsmOperand : AsmOperandClass {
  529. let Name = "MovWSymbolG0";
  530. let RenderMethod = "addImmOperands";
  531. }
  532. def movw_symbol_g0 : Operand<i32> {
  533. let ParserMatchClass = MovWSymbolG0AsmOperand;
  534. }
  535. class fixedpoint_i32<ValueType FloatVT>
  536. : Operand<FloatVT>,
  537. ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
  538. let EncoderMethod = "getFixedPointScaleOpValue";
  539. let DecoderMethod = "DecodeFixedPointScaleImm32";
  540. let ParserMatchClass = Imm1_32Operand;
  541. }
  542. class fixedpoint_i64<ValueType FloatVT>
  543. : Operand<FloatVT>,
  544. ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
  545. let EncoderMethod = "getFixedPointScaleOpValue";
  546. let DecoderMethod = "DecodeFixedPointScaleImm64";
  547. let ParserMatchClass = Imm1_64Operand;
  548. }
  549. def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
  550. def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
  551. def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
  552. def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
  553. def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
  554. def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
  555. def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
  556. return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
  557. }]> {
  558. let EncoderMethod = "getVecShiftR8OpValue";
  559. let DecoderMethod = "DecodeVecShiftR8Imm";
  560. let ParserMatchClass = Imm1_8Operand;
  561. }
  562. def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
  563. return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
  564. }]> {
  565. let EncoderMethod = "getVecShiftR16OpValue";
  566. let DecoderMethod = "DecodeVecShiftR16Imm";
  567. let ParserMatchClass = Imm1_16Operand;
  568. }
  569. def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
  570. return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
  571. }]> {
  572. let EncoderMethod = "getVecShiftR16OpValue";
  573. let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
  574. let ParserMatchClass = Imm1_8Operand;
  575. }
  576. def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
  577. return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
  578. }]> {
  579. let EncoderMethod = "getVecShiftR32OpValue";
  580. let DecoderMethod = "DecodeVecShiftR32Imm";
  581. let ParserMatchClass = Imm1_32Operand;
  582. }
  583. def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
  584. return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
  585. }]> {
  586. let EncoderMethod = "getVecShiftR32OpValue";
  587. let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
  588. let ParserMatchClass = Imm1_16Operand;
  589. }
  590. def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
  591. return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
  592. }]> {
  593. let EncoderMethod = "getVecShiftR64OpValue";
  594. let DecoderMethod = "DecodeVecShiftR64Imm";
  595. let ParserMatchClass = Imm1_64Operand;
  596. }
  597. def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
  598. return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
  599. }]> {
  600. let EncoderMethod = "getVecShiftR64OpValue";
  601. let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
  602. let ParserMatchClass = Imm1_32Operand;
  603. }
  604. // Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant
  605. // (ImmLeaf)
  606. def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{
  607. return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
  608. }]> {
  609. let EncoderMethod = "getVecShiftR8OpValue";
  610. let DecoderMethod = "DecodeVecShiftR8Imm";
  611. let ParserMatchClass = Imm1_8Operand;
  612. }
  613. def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{
  614. return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
  615. }]> {
  616. let EncoderMethod = "getVecShiftR16OpValue";
  617. let DecoderMethod = "DecodeVecShiftR16Imm";
  618. let ParserMatchClass = Imm1_16Operand;
  619. }
  620. def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{
  621. return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
  622. }]> {
  623. let EncoderMethod = "getVecShiftR32OpValue";
  624. let DecoderMethod = "DecodeVecShiftR32Imm";
  625. let ParserMatchClass = Imm1_32Operand;
  626. }
  627. def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{
  628. return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
  629. }]> {
  630. let EncoderMethod = "getVecShiftR64OpValue";
  631. let DecoderMethod = "DecodeVecShiftR64Imm";
  632. let ParserMatchClass = Imm1_64Operand;
  633. }
  634. def Imm0_0Operand : AsmImmRange<0, 0>;
  635. def Imm0_1Operand : AsmImmRange<0, 1>;
  636. def Imm0_3Operand : AsmImmRange<0, 3>;
  637. def Imm0_7Operand : AsmImmRange<0, 7>;
  638. def Imm0_15Operand : AsmImmRange<0, 15>;
  639. def Imm0_31Operand : AsmImmRange<0, 31>;
  640. def Imm0_63Operand : AsmImmRange<0, 63>;
  641. def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
  642. return (((uint32_t)Imm) < 8);
  643. }]> {
  644. let EncoderMethod = "getVecShiftL8OpValue";
  645. let DecoderMethod = "DecodeVecShiftL8Imm";
  646. let ParserMatchClass = Imm0_7Operand;
  647. }
  648. def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
  649. return (((uint32_t)Imm) < 16);
  650. }]> {
  651. let EncoderMethod = "getVecShiftL16OpValue";
  652. let DecoderMethod = "DecodeVecShiftL16Imm";
  653. let ParserMatchClass = Imm0_15Operand;
  654. }
  655. def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
  656. return (((uint32_t)Imm) < 32);
  657. }]> {
  658. let EncoderMethod = "getVecShiftL32OpValue";
  659. let DecoderMethod = "DecodeVecShiftL32Imm";
  660. let ParserMatchClass = Imm0_31Operand;
  661. }
  662. def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
  663. return (((uint32_t)Imm) < 64);
  664. }]> {
  665. let EncoderMethod = "getVecShiftL64OpValue";
  666. let DecoderMethod = "DecodeVecShiftL64Imm";
  667. let ParserMatchClass = Imm0_63Operand;
  668. }
  669. // Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant
  670. // (ImmLeaf)
  671. def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{
  672. return (((uint32_t)Imm) < 8);
  673. }]> {
  674. let EncoderMethod = "getVecShiftL8OpValue";
  675. let DecoderMethod = "DecodeVecShiftL8Imm";
  676. let ParserMatchClass = Imm0_7Operand;
  677. }
  678. def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{
  679. return (((uint32_t)Imm) < 16);
  680. }]> {
  681. let EncoderMethod = "getVecShiftL16OpValue";
  682. let DecoderMethod = "DecodeVecShiftL16Imm";
  683. let ParserMatchClass = Imm0_15Operand;
  684. }
  685. def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{
  686. return (((uint32_t)Imm) < 32);
  687. }]> {
  688. let EncoderMethod = "getVecShiftL32OpValue";
  689. let DecoderMethod = "DecodeVecShiftL32Imm";
  690. let ParserMatchClass = Imm0_31Operand;
  691. }
  692. def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{
  693. return (((uint32_t)Imm) < 64);
  694. }]> {
  695. let EncoderMethod = "getVecShiftL64OpValue";
  696. let DecoderMethod = "DecodeVecShiftL64Imm";
  697. let ParserMatchClass = Imm0_63Operand;
  698. }
  699. // Crazy immediate formats used by 32-bit and 64-bit logical immediate
  700. // instructions for splatting repeating bit patterns across the immediate.
  701. def logical_imm32_XFORM : SDNodeXForm<imm, [{
  702. uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
  703. return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
  704. }]>;
  705. def logical_imm64_XFORM : SDNodeXForm<imm, [{
  706. uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
  707. return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
  708. }]>;
  709. def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">,
  710. GISDNodeXFormEquiv<logical_imm32_XFORM>;
  711. def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">,
  712. GISDNodeXFormEquiv<logical_imm64_XFORM>;
  713. let DiagnosticType = "LogicalSecondSource" in {
  714. def LogicalImm32Operand : AsmOperandClass {
  715. let Name = "LogicalImm32";
  716. let PredicateMethod = "isLogicalImm<int32_t>";
  717. let RenderMethod = "addLogicalImmOperands<int32_t>";
  718. }
  719. def LogicalImm64Operand : AsmOperandClass {
  720. let Name = "LogicalImm64";
  721. let PredicateMethod = "isLogicalImm<int64_t>";
  722. let RenderMethod = "addLogicalImmOperands<int64_t>";
  723. }
  724. def LogicalImm32NotOperand : AsmOperandClass {
  725. let Name = "LogicalImm32Not";
  726. let PredicateMethod = "isLogicalImm<int32_t>";
  727. let RenderMethod = "addLogicalImmNotOperands<int32_t>";
  728. }
  729. def LogicalImm64NotOperand : AsmOperandClass {
  730. let Name = "LogicalImm64Not";
  731. let PredicateMethod = "isLogicalImm<int64_t>";
  732. let RenderMethod = "addLogicalImmNotOperands<int64_t>";
  733. }
  734. }
  735. def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
  736. return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
  737. }], logical_imm32_XFORM> {
  738. let PrintMethod = "printLogicalImm<int32_t>";
  739. let ParserMatchClass = LogicalImm32Operand;
  740. }
  741. def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
  742. return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
  743. }], logical_imm64_XFORM> {
  744. let PrintMethod = "printLogicalImm<int64_t>";
  745. let ParserMatchClass = LogicalImm64Operand;
  746. }
  747. def logical_imm32_not : Operand<i32> {
  748. let ParserMatchClass = LogicalImm32NotOperand;
  749. }
  750. def logical_imm64_not : Operand<i64> {
  751. let ParserMatchClass = LogicalImm64NotOperand;
  752. }
  753. // immXX_0_65535 predicates - True if the immediate is in the range [0,65535].
  754. let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in {
  755. def timm32_0_65535 : Operand<i32>, TImmLeaf<i32, [{
  756. return ((uint32_t)Imm) < 65536;
  757. }]>;
  758. def timm64_0_65535 : Operand<i64>, TImmLeaf<i64, [{
  759. return ((uint64_t)Imm) < 65536;
  760. }]>;
  761. }
  762. // imm0_255 predicate - True if the immediate is in the range [0,255].
  763. def Imm0_255Operand : AsmImmRange<0,255>;
  764. def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
  765. return ((uint32_t)Imm) < 256;
  766. }]> {
  767. let ParserMatchClass = Imm0_255Operand;
  768. let PrintMethod = "printImm";
  769. }
  770. // imm0_127 predicate - True if the immediate is in the range [0,127]
  771. def Imm0_127Operand : AsmImmRange<0, 127>;
  772. def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
  773. return ((uint32_t)Imm) < 128;
  774. }]> {
  775. let ParserMatchClass = Imm0_127Operand;
  776. let PrintMethod = "printImm";
  777. }
  778. def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{
  779. return ((uint64_t)Imm) < 128;
  780. }]> {
  781. let ParserMatchClass = Imm0_127Operand;
  782. let PrintMethod = "printImm";
  783. }
  784. // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
  785. // for all shift-amounts.
  786. // imm0_63 predicate - True if the immediate is in the range [0,63]
  787. def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
  788. return ((uint64_t)Imm) < 64;
  789. }]> {
  790. let ParserMatchClass = Imm0_63Operand;
  791. }
  792. def timm0_63 : Operand<i64>, TImmLeaf<i64, [{
  793. return ((uint64_t)Imm) < 64;
  794. }]> {
  795. let ParserMatchClass = Imm0_63Operand;
  796. }
  797. // imm0_31 predicate - True if the immediate is in the range [0,31]
  798. def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
  799. return ((uint64_t)Imm) < 32;
  800. }]> {
  801. let ParserMatchClass = Imm0_31Operand;
  802. }
  803. // timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf)
  804. // instead of Constant (ImmLeaf)
  805. def timm0_31 : Operand<i64>, TImmLeaf<i64, [{
  806. return ((uint64_t)Imm) < 32;
  807. }]> {
  808. let ParserMatchClass = Imm0_31Operand;
  809. }
  810. // True if the 32-bit immediate is in the range [0,31]
  811. def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
  812. return ((uint64_t)Imm) < 32;
  813. }]> {
  814. let ParserMatchClass = Imm0_31Operand;
  815. }
  816. // imm0_1 predicate - True if the immediate is in the range [0,1]
  817. def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
  818. return ((uint64_t)Imm) < 2;
  819. }]> {
  820. let ParserMatchClass = Imm0_1Operand;
  821. }
  822. // timm0_1 - as above, but use TargetConstant (TImmLeaf)
  823. def timm0_1 : Operand<i64>, TImmLeaf<i64, [{
  824. return ((uint64_t)Imm) < 2;
  825. }]> {
  826. let ParserMatchClass = Imm0_1Operand;
  827. }
  828. // imm0_15 predicate - True if the immediate is in the range [0,15]
  829. def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
  830. return ((uint64_t)Imm) < 16;
  831. }]> {
  832. let ParserMatchClass = Imm0_15Operand;
  833. }
  834. // imm0_7 predicate - True if the immediate is in the range [0,7]
  835. def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
  836. return ((uint64_t)Imm) < 8;
  837. }]> {
  838. let ParserMatchClass = Imm0_7Operand;
  839. }
  840. // imm0_3 predicate - True if the immediate is in the range [0,3]
  841. def imm0_3 : Operand<i64>, ImmLeaf<i64, [{
  842. return ((uint64_t)Imm) < 4;
  843. }]> {
  844. let ParserMatchClass = Imm0_3Operand;
  845. }
  846. // timm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7]
  847. def timm32_0_7 : Operand<i32>, TImmLeaf<i32, [{
  848. return ((uint32_t)Imm) < 8;
  849. }]> {
  850. let ParserMatchClass = Imm0_7Operand;
  851. }
  852. // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
  853. def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
  854. return ((uint32_t)Imm) < 16;
  855. }]> {
  856. let ParserMatchClass = Imm0_15Operand;
  857. }
  858. // An arithmetic shifter operand:
  859. // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
  860. // {5-0} - imm6
  861. class arith_shift<ValueType Ty, int width> : Operand<Ty> {
  862. let PrintMethod = "printShifter";
  863. let ParserMatchClass = !cast<AsmOperandClass>(
  864. "ArithmeticShifterOperand" # width);
  865. }
  866. def arith_shift32 : arith_shift<i32, 32>;
  867. def arith_shift64 : arith_shift<i64, 64>;
  868. class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
  869. : Operand<Ty>,
  870. ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
  871. let PrintMethod = "printShiftedRegister";
  872. let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
  873. }
  874. def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
  875. def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
  876. def gi_arith_shifted_reg32 :
  877. GIComplexOperandMatcher<s32, "selectArithShiftedRegister">,
  878. GIComplexPatternEquiv<arith_shifted_reg32>;
  879. def gi_arith_shifted_reg64 :
  880. GIComplexOperandMatcher<s64, "selectArithShiftedRegister">,
  881. GIComplexPatternEquiv<arith_shifted_reg64>;
  882. // An arithmetic shifter operand:
  883. // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
  884. // {5-0} - imm6
  885. class logical_shift<int width> : Operand<i32> {
  886. let PrintMethod = "printShifter";
  887. let ParserMatchClass = !cast<AsmOperandClass>(
  888. "LogicalShifterOperand" # width);
  889. }
  890. def logical_shift32 : logical_shift<32>;
  891. def logical_shift64 : logical_shift<64>;
  892. class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
  893. : Operand<Ty>,
  894. ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
  895. let PrintMethod = "printShiftedRegister";
  896. let MIOperandInfo = (ops regclass, shiftop);
  897. }
  898. def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
  899. def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
  900. def gi_logical_shifted_reg32 :
  901. GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">,
  902. GIComplexPatternEquiv<logical_shifted_reg32>;
  903. def gi_logical_shifted_reg64 :
  904. GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">,
  905. GIComplexPatternEquiv<logical_shifted_reg64>;
  906. // A logical vector shifter operand:
  907. // {7-6} - shift type: 00 = lsl
  908. // {5-0} - imm6: #0, #8, #16, or #24
  909. def logical_vec_shift : Operand<i32> {
  910. let PrintMethod = "printShifter";
  911. let EncoderMethod = "getVecShifterOpValue";
  912. let ParserMatchClass = LogicalVecShifterOperand;
  913. }
  914. // A logical vector half-word shifter operand:
  915. // {7-6} - shift type: 00 = lsl
  916. // {5-0} - imm6: #0 or #8
  917. def logical_vec_hw_shift : Operand<i32> {
  918. let PrintMethod = "printShifter";
  919. let EncoderMethod = "getVecShifterOpValue";
  920. let ParserMatchClass = LogicalVecHalfWordShifterOperand;
  921. }
  922. // A vector move shifter operand:
  923. // {0} - imm1: #8 or #16
  924. def move_vec_shift : Operand<i32> {
  925. let PrintMethod = "printShifter";
  926. let EncoderMethod = "getMoveVecShifterOpValue";
  927. let ParserMatchClass = MoveVecShifterOperand;
  928. }
  929. let DiagnosticType = "AddSubSecondSource" in {
  930. def AddSubImmOperand : AsmOperandClass {
  931. let Name = "AddSubImm";
  932. let ParserMethod = "tryParseImmWithOptionalShift";
  933. let RenderMethod = "addImmWithOptionalShiftOperands<12>";
  934. }
  935. def AddSubImmNegOperand : AsmOperandClass {
  936. let Name = "AddSubImmNeg";
  937. let ParserMethod = "tryParseImmWithOptionalShift";
  938. let RenderMethod = "addImmNegWithOptionalShiftOperands<12>";
  939. }
  940. }
  941. // An ADD/SUB immediate shifter operand:
  942. // second operand:
  943. // {7-6} - shift type: 00 = lsl
  944. // {5-0} - imm6: #0 or #12
  945. class addsub_shifted_imm<ValueType Ty>
  946. : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
  947. let PrintMethod = "printAddSubImm";
  948. let EncoderMethod = "getAddSubImmOpValue";
  949. let ParserMatchClass = AddSubImmOperand;
  950. let MIOperandInfo = (ops i32imm, i32imm);
  951. }
  952. class addsub_shifted_imm_neg<ValueType Ty>
  953. : Operand<Ty> {
  954. let EncoderMethod = "getAddSubImmOpValue";
  955. let ParserMatchClass = AddSubImmNegOperand;
  956. let MIOperandInfo = (ops i32imm, i32imm);
  957. }
  958. def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
  959. def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
  960. def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
  961. def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
  962. def gi_addsub_shifted_imm32 :
  963. GIComplexOperandMatcher<s32, "selectArithImmed">,
  964. GIComplexPatternEquiv<addsub_shifted_imm32>;
  965. def gi_addsub_shifted_imm64 :
  966. GIComplexOperandMatcher<s64, "selectArithImmed">,
  967. GIComplexPatternEquiv<addsub_shifted_imm64>;
  968. class neg_addsub_shifted_imm<ValueType Ty>
  969. : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
  970. let PrintMethod = "printAddSubImm";
  971. let EncoderMethod = "getAddSubImmOpValue";
  972. let ParserMatchClass = AddSubImmOperand;
  973. let MIOperandInfo = (ops i32imm, i32imm);
  974. }
  975. def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
  976. def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
  977. def gi_neg_addsub_shifted_imm32 :
  978. GIComplexOperandMatcher<s32, "selectNegArithImmed">,
  979. GIComplexPatternEquiv<neg_addsub_shifted_imm32>;
  980. def gi_neg_addsub_shifted_imm64 :
  981. GIComplexOperandMatcher<s64, "selectNegArithImmed">,
  982. GIComplexPatternEquiv<neg_addsub_shifted_imm64>;
  983. // An extend operand:
  984. // {5-3} - extend type
  985. // {2-0} - imm3
  986. def arith_extend : Operand<i32> {
  987. let PrintMethod = "printArithExtend";
  988. let ParserMatchClass = ExtendOperand;
  989. }
  990. def arith_extend64 : Operand<i32> {
  991. let PrintMethod = "printArithExtend";
  992. let ParserMatchClass = ExtendOperand64;
  993. }
  994. // 'extend' that's a lsl of a 64-bit register.
  995. def arith_extendlsl64 : Operand<i32> {
  996. let PrintMethod = "printArithExtend";
  997. let ParserMatchClass = ExtendOperandLSL64;
  998. }
  999. class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
  1000. ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
  1001. let PrintMethod = "printExtendedRegister";
  1002. let MIOperandInfo = (ops GPR32, arith_extend);
  1003. }
  1004. class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
  1005. ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
  1006. let PrintMethod = "printExtendedRegister";
  1007. let MIOperandInfo = (ops GPR32, arith_extend64);
  1008. }
  1009. def arith_extended_reg32_i32 : arith_extended_reg32<i32>;
  1010. def gi_arith_extended_reg32_i32 :
  1011. GIComplexOperandMatcher<s32, "selectArithExtendedRegister">,
  1012. GIComplexPatternEquiv<arith_extended_reg32_i32>;
  1013. def arith_extended_reg32_i64 : arith_extended_reg32<i64>;
  1014. def gi_arith_extended_reg32_i64 :
  1015. GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
  1016. GIComplexPatternEquiv<arith_extended_reg32_i64>;
  1017. def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>;
  1018. def gi_arith_extended_reg32to64_i64 :
  1019. GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,
  1020. GIComplexPatternEquiv<arith_extended_reg32to64_i64>;
  1021. // Floating-point immediate.
  1022. def fpimm16XForm : SDNodeXForm<fpimm, [{
  1023. APFloat InVal = N->getValueAPF();
  1024. uint32_t enc = AArch64_AM::getFP16Imm(InVal);
  1025. return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
  1026. }]>;
  1027. def fpimm32XForm : SDNodeXForm<fpimm, [{
  1028. APFloat InVal = N->getValueAPF();
  1029. uint32_t enc = AArch64_AM::getFP32Imm(InVal);
  1030. return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
  1031. }]>;
  1032. def fpimm64XForm : SDNodeXForm<fpimm, [{
  1033. APFloat InVal = N->getValueAPF();
  1034. uint32_t enc = AArch64_AM::getFP64Imm(InVal);
  1035. return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
  1036. }]>;
  1037. def fpimm16 : Operand<f16>,
  1038. FPImmLeaf<f16, [{
  1039. return AArch64_AM::getFP16Imm(Imm) != -1;
  1040. }], fpimm16XForm> {
  1041. let ParserMatchClass = FPImmOperand;
  1042. let PrintMethod = "printFPImmOperand";
  1043. }
  1044. def fpimm32 : Operand<f32>,
  1045. FPImmLeaf<f32, [{
  1046. return AArch64_AM::getFP32Imm(Imm) != -1;
  1047. }], fpimm32XForm> {
  1048. let ParserMatchClass = FPImmOperand;
  1049. let PrintMethod = "printFPImmOperand";
  1050. }
  1051. def fpimm64 : Operand<f64>,
  1052. FPImmLeaf<f64, [{
  1053. return AArch64_AM::getFP64Imm(Imm) != -1;
  1054. }], fpimm64XForm> {
  1055. let ParserMatchClass = FPImmOperand;
  1056. let PrintMethod = "printFPImmOperand";
  1057. }
  1058. def fpimm8 : Operand<i32> {
  1059. let ParserMatchClass = FPImmOperand;
  1060. let PrintMethod = "printFPImmOperand";
  1061. }
  1062. def fpimm0 : FPImmLeaf<fAny, [{
  1063. return Imm.isExactlyValue(+0.0);
  1064. }]>;
  1065. def fpimm_half : FPImmLeaf<fAny, [{
  1066. return Imm.isExactlyValue(+0.5);
  1067. }]>;
  1068. def fpimm_one : FPImmLeaf<fAny, [{
  1069. return Imm.isExactlyValue(+1.0);
  1070. }]>;
  1071. def fpimm_two : FPImmLeaf<fAny, [{
  1072. return Imm.isExactlyValue(+2.0);
  1073. }]>;
  1074. def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">,
  1075. GISDNodeXFormEquiv<fpimm16XForm>;
  1076. def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">,
  1077. GISDNodeXFormEquiv<fpimm32XForm>;
  1078. def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">,
  1079. GISDNodeXFormEquiv<fpimm64XForm>;
  1080. // Vector lane operands
  1081. class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass {
  1082. let Name = NamePrefix # "IndexRange" # Min # "_" # Max;
  1083. let DiagnosticType = "Invalid" # Name;
  1084. let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">";
  1085. let RenderMethod = "addVectorIndexOperands";
  1086. }
  1087. class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc>
  1088. : Operand<ty> {
  1089. let ParserMatchClass = mc;
  1090. let PrintMethod = "printVectorIndex";
  1091. }
  1092. multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> {
  1093. def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>;
  1094. def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>;
  1095. }
  1096. def VectorIndex0Operand : AsmVectorIndex<0, 0>;
  1097. def VectorIndex1Operand : AsmVectorIndex<1, 1>;
  1098. def VectorIndexBOperand : AsmVectorIndex<0, 15>;
  1099. def VectorIndexHOperand : AsmVectorIndex<0, 7>;
  1100. def VectorIndexSOperand : AsmVectorIndex<0, 3>;
  1101. def VectorIndexDOperand : AsmVectorIndex<0, 1>;
  1102. defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand,
  1103. [{ return ((uint64_t)Imm) == 0; }]>;
  1104. defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand,
  1105. [{ return ((uint64_t)Imm) == 1; }]>;
  1106. defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand,
  1107. [{ return ((uint64_t)Imm) < 16; }]>;
  1108. defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand,
  1109. [{ return ((uint64_t)Imm) < 8; }]>;
  1110. defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand,
  1111. [{ return ((uint64_t)Imm) < 4; }]>;
  1112. defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand,
  1113. [{ return ((uint64_t)Imm) < 2; }]>;
  1114. defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand,
  1115. [{ return ((uint64_t)Imm) == 1; }]>;
  1116. defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand,
  1117. [{ return ((uint64_t)Imm) < 16; }]>;
  1118. defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand,
  1119. [{ return ((uint64_t)Imm) < 8; }]>;
  1120. defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand,
  1121. [{ return ((uint64_t)Imm) < 4; }]>;
  1122. defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand,
  1123. [{ return ((uint64_t)Imm) < 2; }]>;
  1124. def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">;
  1125. def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">;
  1126. def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">;
  1127. def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">;
  1128. def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">;
  1129. defm sve_elm_idx_extdup_b
  1130. : VectorIndex<i64, SVEVectorIndexExtDupBOperand,
  1131. [{ return ((uint64_t)Imm) < 64; }]>;
  1132. defm sve_elm_idx_extdup_h
  1133. : VectorIndex<i64, SVEVectorIndexExtDupHOperand,
  1134. [{ return ((uint64_t)Imm) < 32; }]>;
  1135. defm sve_elm_idx_extdup_s
  1136. : VectorIndex<i64, SVEVectorIndexExtDupSOperand,
  1137. [{ return ((uint64_t)Imm) < 16; }]>;
  1138. defm sve_elm_idx_extdup_d
  1139. : VectorIndex<i64, SVEVectorIndexExtDupDOperand,
  1140. [{ return ((uint64_t)Imm) < 8; }]>;
  1141. defm sve_elm_idx_extdup_q
  1142. : VectorIndex<i64, SVEVectorIndexExtDupQOperand,
  1143. [{ return ((uint64_t)Imm) < 4; }]>;
  1144. def sme_elm_idx0_0 : Operand<i64>, ImmLeaf<i64, [{
  1145. return ((uint64_t)Imm) == 0;
  1146. }]> {
  1147. let ParserMatchClass = Imm0_0Operand;
  1148. let PrintMethod = "printMatrixIndex";
  1149. }
  1150. def sme_elm_idx0_1 : Operand<i64>, ImmLeaf<i64, [{
  1151. return ((uint64_t)Imm) <= 1;
  1152. }]> {
  1153. let ParserMatchClass = Imm0_1Operand;
  1154. let PrintMethod = "printMatrixIndex";
  1155. }
  1156. def sme_elm_idx0_3 : Operand<i64>, ImmLeaf<i64, [{
  1157. return ((uint64_t)Imm) <= 3;
  1158. }]> {
  1159. let ParserMatchClass = Imm0_3Operand;
  1160. let PrintMethod = "printMatrixIndex";
  1161. }
  1162. def sme_elm_idx0_7 : Operand<i64>, ImmLeaf<i64, [{
  1163. return ((uint64_t)Imm) <= 7;
  1164. }]> {
  1165. let ParserMatchClass = Imm0_7Operand;
  1166. let PrintMethod = "printMatrixIndex";
  1167. }
  1168. def sme_elm_idx0_15 : Operand<i64>, ImmLeaf<i64, [{
  1169. return ((uint64_t)Imm) <= 15;
  1170. }]> {
  1171. let ParserMatchClass = Imm0_15Operand;
  1172. let PrintMethod = "printMatrixIndex";
  1173. }
  1174. // 8-bit immediate for AdvSIMD where 64-bit values of the form:
  1175. // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
  1176. // are encoded as the eight bit value 'abcdefgh'.
  1177. def simdimmtype10 : Operand<i32>,
  1178. FPImmLeaf<f64, [{
  1179. return AArch64_AM::isAdvSIMDModImmType10(
  1180. Imm.bitcastToAPInt().getZExtValue());
  1181. }], SDNodeXForm<fpimm, [{
  1182. APFloat InVal = N->getValueAPF();
  1183. uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
  1184. .bitcastToAPInt()
  1185. .getZExtValue());
  1186. return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
  1187. }]>> {
  1188. let ParserMatchClass = SIMDImmType10Operand;
  1189. let PrintMethod = "printSIMDType10Operand";
  1190. }
  1191. //---
  1192. // System management
  1193. //---
  1194. // Base encoding for system instruction operands.
  1195. let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
  1196. class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
  1197. list<dag> pattern = []>
  1198. : I<oops, iops, asm, operands, "", pattern> {
  1199. let Inst{31-22} = 0b1101010100;
  1200. let Inst{21} = L;
  1201. }
  1202. // System instructions which do not have an Rt register.
  1203. class SimpleSystemI<bit L, dag iops, string asm, string operands,
  1204. list<dag> pattern = []>
  1205. : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
  1206. let Inst{4-0} = 0b11111;
  1207. }
  1208. // System instructions which have an Rt register.
  1209. class RtSystemI<bit L, dag oops, dag iops, string asm, string operands,
  1210. list<dag> pattern = []>
  1211. : BaseSystemI<L, oops, iops, asm, operands, pattern>,
  1212. Sched<[WriteSys]> {
  1213. bits<5> Rt;
  1214. let Inst{4-0} = Rt;
  1215. }
  1216. // System instructions for transactional memory extension
  1217. class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops,
  1218. string asm, string operands, list<dag> pattern>
  1219. : BaseSystemI<L, oops, iops, asm, operands, pattern>,
  1220. Sched<[WriteSys]> {
  1221. let Inst{20-12} = 0b000110011;
  1222. let Inst{11-8} = CRm;
  1223. let Inst{7-5} = op2;
  1224. let DecoderMethod = "";
  1225. let mayLoad = 1;
  1226. let mayStore = 1;
  1227. }
  1228. // System instructions for transactional memory - single input operand
  1229. class TMSystemI<bits<4> CRm, string asm, list<dag> pattern>
  1230. : TMBaseSystemI<0b1, CRm, 0b011,
  1231. (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> {
  1232. bits<5> Rt;
  1233. let Inst{4-0} = Rt;
  1234. }
  1235. // System instructions that pass a register argument
  1236. // This class assumes the register is for input rather than output.
  1237. class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm,
  1238. list<dag> pattern = []>
  1239. : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> {
  1240. let Inst{20-12} = 0b000110001;
  1241. let Inst{11-8} = CRm;
  1242. let Inst{7-5} = Op2;
  1243. }
  1244. // System instructions for transactional memory - no operand
  1245. class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern>
  1246. : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> {
  1247. let Inst{4-0} = 0b11111;
  1248. }
  1249. // System instructions for exit from transactions
  1250. class TMSystemException<bits<3> op1, string asm, list<dag> pattern>
  1251. : I<(outs), (ins timm64_0_65535:$imm), asm, "\t$imm", "", pattern>,
  1252. Sched<[WriteSys]> {
  1253. bits<16> imm;
  1254. let Inst{31-24} = 0b11010100;
  1255. let Inst{23-21} = op1;
  1256. let Inst{20-5} = imm;
  1257. let Inst{4-0} = 0b00000;
  1258. }
  1259. // Hint instructions that take both a CRm and a 3-bit immediate.
  1260. // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
  1261. // model patterns with sufficiently fine granularity
  1262. let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
  1263. class HintI<string mnemonic>
  1264. : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
  1265. [(int_aarch64_hint imm0_127:$imm)]>,
  1266. Sched<[WriteHint]> {
  1267. bits <7> imm;
  1268. let Inst{20-12} = 0b000110010;
  1269. let Inst{11-5} = imm;
  1270. }
  1271. // System instructions taking a single literal operand which encodes into
  1272. // CRm. op2 differentiates the opcodes.
  1273. def BarrierAsmOperand : AsmOperandClass {
  1274. let Name = "Barrier";
  1275. let ParserMethod = "tryParseBarrierOperand";
  1276. }
  1277. def barrier_op : Operand<i32> {
  1278. let PrintMethod = "printBarrierOption";
  1279. let ParserMatchClass = BarrierAsmOperand;
  1280. }
  1281. def BarriernXSAsmOperand : AsmOperandClass {
  1282. let Name = "BarriernXS";
  1283. let ParserMethod = "tryParseBarriernXSOperand";
  1284. }
  1285. def barrier_nxs_op : Operand<i32> {
  1286. let PrintMethod = "printBarriernXSOption";
  1287. let ParserMatchClass = BarriernXSAsmOperand;
  1288. }
  1289. class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
  1290. list<dag> pattern = []>
  1291. : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
  1292. Sched<[WriteBarrier]> {
  1293. bits<4> CRm;
  1294. let Inst{20-12} = 0b000110011;
  1295. let Inst{11-8} = CRm;
  1296. let Inst{7-5} = opc;
  1297. }
  1298. class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []>
  1299. : SimpleSystemI<0, (ins), asm, "", pattern>,
  1300. Sched<[]> {
  1301. bits<4> CRm;
  1302. let CRm = 0b0011;
  1303. let Inst{31-12} = 0b11010101000000110010;
  1304. let Inst{11-8} = CRm;
  1305. let Inst{7-5} = op2;
  1306. let Inst{4-0} = 0b11111;
  1307. }
  1308. // MRS/MSR system instructions. These have different operand classes because
  1309. // a different subset of registers can be accessed through each instruction.
  1310. def MRSSystemRegisterOperand : AsmOperandClass {
  1311. let Name = "MRSSystemRegister";
  1312. let ParserMethod = "tryParseSysReg";
  1313. let DiagnosticType = "MRS";
  1314. }
  1315. // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
  1316. def mrs_sysreg_op : Operand<i32> {
  1317. let ParserMatchClass = MRSSystemRegisterOperand;
  1318. let DecoderMethod = "DecodeMRSSystemRegister";
  1319. let PrintMethod = "printMRSSystemRegister";
  1320. }
  1321. def MSRSystemRegisterOperand : AsmOperandClass {
  1322. let Name = "MSRSystemRegister";
  1323. let ParserMethod = "tryParseSysReg";
  1324. let DiagnosticType = "MSR";
  1325. }
  1326. def msr_sysreg_op : Operand<i32> {
  1327. let ParserMatchClass = MSRSystemRegisterOperand;
  1328. let DecoderMethod = "DecodeMSRSystemRegister";
  1329. let PrintMethod = "printMSRSystemRegister";
  1330. }
  1331. def PSBHintOperand : AsmOperandClass {
  1332. let Name = "PSBHint";
  1333. let ParserMethod = "tryParsePSBHint";
  1334. }
  1335. def psbhint_op : Operand<i32> {
  1336. let ParserMatchClass = PSBHintOperand;
  1337. let PrintMethod = "printPSBHintOp";
  1338. let MCOperandPredicate = [{
  1339. // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
  1340. // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
  1341. if (!MCOp.isImm())
  1342. return false;
  1343. return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
  1344. }];
  1345. }
  1346. def BTIHintOperand : AsmOperandClass {
  1347. let Name = "BTIHint";
  1348. let ParserMethod = "tryParseBTIHint";
  1349. }
  1350. def btihint_op : Operand<i32> {
  1351. let ParserMatchClass = BTIHintOperand;
  1352. let PrintMethod = "printBTIHintOp";
  1353. let MCOperandPredicate = [{
  1354. // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields.
  1355. if (!MCOp.isImm())
  1356. return false;
  1357. return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr;
  1358. }];
  1359. }
  1360. class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
  1361. "mrs", "\t$Rt, $systemreg"> {
  1362. bits<16> systemreg;
  1363. let Inst{20-5} = systemreg;
  1364. let DecoderNamespace = "Fallback";
  1365. // The MRS is set as a NZCV setting instruction. Not all MRS instructions
  1366. // require doing this. The alternative was to explicitly model each one, but
  1367. // it feels like it is unnecessary because it seems there are no negative
  1368. // consequences setting these flags for all.
  1369. let Defs = [NZCV];
  1370. }
  1371. // FIXME: Some of these def NZCV, others don't. Best way to model that?
  1372. // Explicitly modeling each of the system register as a register class
  1373. // would do it, but feels like overkill at this point.
  1374. class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
  1375. "msr", "\t$systemreg, $Rt"> {
  1376. bits<16> systemreg;
  1377. let Inst{20-5} = systemreg;
  1378. let DecoderNamespace = "Fallback";
  1379. }
  1380. def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
  1381. let Name = "SystemPStateFieldWithImm0_15";
  1382. let ParserMethod = "tryParseSysReg";
  1383. }
  1384. def pstatefield4_op : Operand<i32> {
  1385. let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
  1386. let PrintMethod = "printSystemPStateField";
  1387. }
  1388. // Instructions to modify PSTATE, no input reg
  1389. let Defs = [NZCV] in
  1390. class PstateWriteSimple<dag iops, string asm, string operands>
  1391. : SimpleSystemI<0, iops, asm, operands> {
  1392. let Inst{20-19} = 0b00;
  1393. let Inst{15-12} = 0b0100;
  1394. }
  1395. class MSRpstateImm0_15
  1396. : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr",
  1397. "\t$pstatefield, $imm">,
  1398. Sched<[WriteSys]> {
  1399. bits<6> pstatefield;
  1400. bits<4> imm;
  1401. let Inst{18-16} = pstatefield{5-3};
  1402. let Inst{11-8} = imm;
  1403. let Inst{7-5} = pstatefield{2-0};
  1404. let DecoderMethod = "DecodeSystemPStateInstruction";
  1405. // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
  1406. // Fail the decoder should attempt to decode the instruction as MSRI.
  1407. let hasCompleteDecoder = 0;
  1408. }
  1409. def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
  1410. let Name = "SystemPStateFieldWithImm0_1";
  1411. let ParserMethod = "tryParseSysReg";
  1412. }
  1413. def pstatefield1_op : Operand<i32> {
  1414. let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
  1415. let PrintMethod = "printSystemPStateField";
  1416. }
  1417. class MSRpstateImm0_1
  1418. : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr",
  1419. "\t$pstatefield, $imm">,
  1420. Sched<[WriteSys]> {
  1421. bits<6> pstatefield;
  1422. bit imm;
  1423. let Inst{18-16} = pstatefield{5-3};
  1424. let Inst{11-9} = 0b000;
  1425. let Inst{8} = imm;
  1426. let Inst{7-5} = pstatefield{2-0};
  1427. let DecoderMethod = "DecodeSystemPStateInstruction";
  1428. // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
  1429. // Fail the decoder should attempt to decode the instruction as MSRI.
  1430. let hasCompleteDecoder = 0;
  1431. }
  1432. // SYS and SYSL generic system instructions.
  1433. def SysCRAsmOperand : AsmOperandClass {
  1434. let Name = "SysCR";
  1435. let ParserMethod = "tryParseSysCROperand";
  1436. }
  1437. def sys_cr_op : Operand<i32> {
  1438. let PrintMethod = "printSysCROperand";
  1439. let ParserMatchClass = SysCRAsmOperand;
  1440. }
  1441. class SystemXtI<bit L, string asm>
  1442. : RtSystemI<L, (outs),
  1443. (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
  1444. asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
  1445. bits<3> op1;
  1446. bits<4> Cn;
  1447. bits<4> Cm;
  1448. bits<3> op2;
  1449. let Inst{20-19} = 0b01;
  1450. let Inst{18-16} = op1;
  1451. let Inst{15-12} = Cn;
  1452. let Inst{11-8} = Cm;
  1453. let Inst{7-5} = op2;
  1454. }
  1455. class SystemLXtI<bit L, string asm>
  1456. : RtSystemI<L, (outs),
  1457. (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
  1458. asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
  1459. bits<3> op1;
  1460. bits<4> Cn;
  1461. bits<4> Cm;
  1462. bits<3> op2;
  1463. let Inst{20-19} = 0b01;
  1464. let Inst{18-16} = op1;
  1465. let Inst{15-12} = Cn;
  1466. let Inst{11-8} = Cm;
  1467. let Inst{7-5} = op2;
  1468. }
  1469. // Branch (register) instructions:
  1470. //
  1471. // case opc of
  1472. // 0001 blr
  1473. // 0000 br
  1474. // 0101 dret
  1475. // 0100 eret
  1476. // 0010 ret
  1477. // otherwise UNDEFINED
  1478. class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
  1479. string operands, list<dag> pattern>
  1480. : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
  1481. let Inst{31-25} = 0b1101011;
  1482. let Inst{24-21} = opc;
  1483. let Inst{20-16} = 0b11111;
  1484. let Inst{15-10} = 0b000000;
  1485. let Inst{4-0} = 0b00000;
  1486. }
  1487. class BranchReg<bits<4> opc, string asm, list<dag> pattern>
  1488. : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
  1489. bits<5> Rn;
  1490. let Inst{9-5} = Rn;
  1491. }
  1492. let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
  1493. class SpecialReturn<bits<4> opc, string asm>
  1494. : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
  1495. let Inst{9-5} = 0b11111;
  1496. }
  1497. let mayLoad = 1 in
  1498. class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
  1499. : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>,
  1500. Sched<[]> {
  1501. bits<5> Rn;
  1502. bits<5> Rt;
  1503. let Inst{31-30} = sz;
  1504. let Inst{29-10} = 0b11100010111111110000;
  1505. let Inst{9-5} = Rn;
  1506. let Inst{4-0} = Rt;
  1507. }
  1508. class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
  1509. list<dag> pattern>
  1510. : I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
  1511. let isAuthenticated = 1;
  1512. let Inst{31-25} = 0b1101011;
  1513. let Inst{20-11} = 0b1111100001;
  1514. let Inst{10} = M;
  1515. let Inst{4-0} = 0b11111;
  1516. }
  1517. class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm>
  1518. : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> {
  1519. bits<5> Rn;
  1520. bits<5> Rm;
  1521. let Inst{24-22} = 0b100;
  1522. let Inst{21} = op;
  1523. let Inst{9-5} = Rn;
  1524. let Inst{4-0} = Rm;
  1525. }
  1526. class AuthOneOperand<bits<3> opc, bits<1> M, string asm>
  1527. : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {
  1528. bits<5> Rn;
  1529. let Inst{24} = 0;
  1530. let Inst{23-21} = opc;
  1531. let Inst{9-5} = Rn;
  1532. }
  1533. let Uses = [LR,SP] in
  1534. class AuthReturn<bits<3> op, bits<1> M, string asm>
  1535. : AuthBase<M, (outs), (ins), asm, "", []> {
  1536. let Inst{24} = 0;
  1537. let Inst{23-21} = op;
  1538. let Inst{9-0} = 0b1111111111;
  1539. }
  1540. let mayLoad = 1 in
  1541. class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,
  1542. string operands, string cstr>
  1543. : I<oops, iops, asm, operands, cstr, []>, Sched<[]> {
  1544. bits<10> offset;
  1545. bits<5> Rn;
  1546. bits<5> Rt;
  1547. let isAuthenticated = 1;
  1548. let Inst{31-24} = 0b11111000;
  1549. let Inst{23} = M;
  1550. let Inst{22} = offset{9};
  1551. let Inst{21} = 1;
  1552. let Inst{20-12} = offset{8-0};
  1553. let Inst{11} = W;
  1554. let Inst{10} = 1;
  1555. let Inst{9-5} = Rn;
  1556. let Inst{4-0} = Rt;
  1557. let DecoderMethod = "DecodeAuthLoadInstruction";
  1558. }
  1559. multiclass AuthLoad<bit M, string asm, Operand opr> {
  1560. def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt),
  1561. (ins GPR64sp:$Rn, opr:$offset),
  1562. asm, "\t$Rt, [$Rn, $offset]", "">;
  1563. def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt),
  1564. (ins GPR64sp:$Rn, opr:$offset),
  1565. asm, "\t$Rt, [$Rn, $offset]!",
  1566. "$Rn = $wback,@earlyclobber $wback">;
  1567. def : InstAlias<asm # "\t$Rt, [$Rn]",
  1568. (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>;
  1569. def : InstAlias<asm # "\t$Rt, [$wback]!",
  1570. (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>;
  1571. }
  1572. //---
  1573. // Conditional branch instruction.
  1574. //---
  1575. // Condition code.
  1576. // 4-bit immediate. Pretty-printed as <cc>
  1577. def ccode : Operand<i32> {
  1578. let PrintMethod = "printCondCode";
  1579. let ParserMatchClass = CondCode;
  1580. }
  1581. def inv_ccode : Operand<i32> {
  1582. // AL and NV are invalid in the aliases which use inv_ccode
  1583. let PrintMethod = "printInverseCondCode";
  1584. let ParserMatchClass = CondCode;
  1585. let MCOperandPredicate = [{
  1586. return MCOp.isImm() &&
  1587. MCOp.getImm() != AArch64CC::AL &&
  1588. MCOp.getImm() != AArch64CC::NV;
  1589. }];
  1590. }
  1591. // Conditional branch target. 19-bit immediate. The low two bits of the target
  1592. // offset are implied zero and so are not part of the immediate.
  1593. def am_brcond : Operand<OtherVT> {
  1594. let EncoderMethod = "getCondBranchTargetOpValue";
  1595. let DecoderMethod = "DecodePCRelLabel19";
  1596. let PrintMethod = "printAlignedLabel";
  1597. let ParserMatchClass = PCRelLabel19Operand;
  1598. let OperandType = "OPERAND_PCREL";
  1599. }
  1600. class BranchCond<bit bit4, string mnemonic>
  1601. : I<(outs), (ins ccode:$cond, am_brcond:$target),
  1602. mnemonic, ".$cond\t$target", "",
  1603. [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> {
  1604. let isBranch = 1;
  1605. let isTerminator = 1;
  1606. let Uses = [NZCV];
  1607. bits<4> cond;
  1608. bits<19> target;
  1609. let Inst{31-24} = 0b01010100;
  1610. let Inst{23-5} = target;
  1611. let Inst{4} = bit4;
  1612. let Inst{3-0} = cond;
  1613. }
  1614. //---
  1615. // Compare-and-branch instructions.
  1616. //---
  1617. class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
  1618. : I<(outs), (ins regtype:$Rt, am_brcond:$target),
  1619. asm, "\t$Rt, $target", "",
  1620. [(node regtype:$Rt, bb:$target)]>,
  1621. Sched<[WriteBr]> {
  1622. let isBranch = 1;
  1623. let isTerminator = 1;
  1624. bits<5> Rt;
  1625. bits<19> target;
  1626. let Inst{30-25} = 0b011010;
  1627. let Inst{24} = op;
  1628. let Inst{23-5} = target;
  1629. let Inst{4-0} = Rt;
  1630. }
  1631. multiclass CmpBranch<bit op, string asm, SDNode node> {
  1632. def W : BaseCmpBranch<GPR32, op, asm, node> {
  1633. let Inst{31} = 0;
  1634. }
  1635. def X : BaseCmpBranch<GPR64, op, asm, node> {
  1636. let Inst{31} = 1;
  1637. }
  1638. }
  1639. //---
  1640. // Test-bit-and-branch instructions.
  1641. //---
  1642. // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
  1643. // the target offset are implied zero and so are not part of the immediate.
  1644. def am_tbrcond : Operand<OtherVT> {
  1645. let EncoderMethod = "getTestBranchTargetOpValue";
  1646. let PrintMethod = "printAlignedLabel";
  1647. let ParserMatchClass = BranchTarget14Operand;
  1648. let OperandType = "OPERAND_PCREL";
  1649. }
  1650. // AsmOperand classes to emit (or not) special diagnostics
  1651. def TBZImm0_31Operand : AsmOperandClass {
  1652. let Name = "TBZImm0_31";
  1653. let PredicateMethod = "isImmInRange<0,31>";
  1654. let RenderMethod = "addImmOperands";
  1655. }
  1656. def TBZImm32_63Operand : AsmOperandClass {
  1657. let Name = "Imm32_63";
  1658. let PredicateMethod = "isImmInRange<32,63>";
  1659. let DiagnosticType = "InvalidImm0_63";
  1660. let RenderMethod = "addImmOperands";
  1661. }
  1662. class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
  1663. return (((uint32_t)Imm) < 32);
  1664. }]> {
  1665. let ParserMatchClass = matcher;
  1666. }
  1667. def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
  1668. def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
  1669. def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
  1670. return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
  1671. }]> {
  1672. let ParserMatchClass = TBZImm32_63Operand;
  1673. }
  1674. class BaseTestBranch<RegisterClass regtype, Operand immtype,
  1675. bit op, string asm, SDNode node>
  1676. : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
  1677. asm, "\t$Rt, $bit_off, $target", "",
  1678. [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
  1679. Sched<[WriteBr]> {
  1680. let isBranch = 1;
  1681. let isTerminator = 1;
  1682. bits<5> Rt;
  1683. bits<6> bit_off;
  1684. bits<14> target;
  1685. let Inst{30-25} = 0b011011;
  1686. let Inst{24} = op;
  1687. let Inst{23-19} = bit_off{4-0};
  1688. let Inst{18-5} = target;
  1689. let Inst{4-0} = Rt;
  1690. let DecoderMethod = "DecodeTestAndBranch";
  1691. }
  1692. multiclass TestBranch<bit op, string asm, SDNode node> {
  1693. def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
  1694. let Inst{31} = 0;
  1695. }
  1696. def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
  1697. let Inst{31} = 1;
  1698. }
  1699. // Alias X-reg with 0-31 imm to W-Reg.
  1700. def : InstAlias<asm # "\t$Rd, $imm, $target",
  1701. (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
  1702. tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
  1703. def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
  1704. (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
  1705. tbz_imm0_31_diag:$imm, bb:$target)>;
  1706. }
  1707. //---
  1708. // Unconditional branch (immediate) instructions.
  1709. //---
  1710. def am_b_target : Operand<OtherVT> {
  1711. let EncoderMethod = "getBranchTargetOpValue";
  1712. let PrintMethod = "printAlignedLabel";
  1713. let ParserMatchClass = BranchTarget26Operand;
  1714. let OperandType = "OPERAND_PCREL";
  1715. }
  1716. def am_bl_target : Operand<i64> {
  1717. let EncoderMethod = "getBranchTargetOpValue";
  1718. let PrintMethod = "printAlignedLabel";
  1719. let ParserMatchClass = BranchTarget26Operand;
  1720. let OperandType = "OPERAND_PCREL";
  1721. }
  1722. class BImm<bit op, dag iops, string asm, list<dag> pattern>
  1723. : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
  1724. bits<26> addr;
  1725. let Inst{31} = op;
  1726. let Inst{30-26} = 0b00101;
  1727. let Inst{25-0} = addr;
  1728. let DecoderMethod = "DecodeUnconditionalBranch";
  1729. }
  1730. class BranchImm<bit op, string asm, list<dag> pattern>
  1731. : BImm<op, (ins am_b_target:$addr), asm, pattern>;
  1732. class CallImm<bit op, string asm, list<dag> pattern>
  1733. : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
  1734. //---
  1735. // Basic one-operand data processing instructions.
  1736. //---
  1737. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  1738. class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
  1739. SDPatternOperator node>
  1740. : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
  1741. [(set regtype:$Rd, (node regtype:$Rn))]>,
  1742. Sched<[WriteI, ReadI]> {
  1743. bits<5> Rd;
  1744. bits<5> Rn;
  1745. let Inst{30-13} = 0b101101011000000000;
  1746. let Inst{12-10} = opc;
  1747. let Inst{9-5} = Rn;
  1748. let Inst{4-0} = Rd;
  1749. }
  1750. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  1751. multiclass OneOperandData<bits<3> opc, string asm,
  1752. SDPatternOperator node = null_frag> {
  1753. def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
  1754. let Inst{31} = 0;
  1755. }
  1756. def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
  1757. let Inst{31} = 1;
  1758. }
  1759. }
  1760. class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
  1761. : BaseOneOperandData<opc, GPR32, asm, node> {
  1762. let Inst{31} = 0;
  1763. }
  1764. class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
  1765. : BaseOneOperandData<opc, GPR64, asm, node> {
  1766. let Inst{31} = 1;
  1767. }
  1768. class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm,
  1769. SDPatternOperator op>
  1770. : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn",
  1771. "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>,
  1772. Sched<[WriteI, ReadI]> {
  1773. bits<5> Rd;
  1774. bits<5> Rn;
  1775. let Inst{31-15} = 0b11011010110000010;
  1776. let Inst{14-12} = opcode_prefix;
  1777. let Inst{11-10} = opcode;
  1778. let Inst{9-5} = Rn;
  1779. let Inst{4-0} = Rd;
  1780. }
  1781. class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm,
  1782. SDPatternOperator op>
  1783. : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd",
  1784. [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>,
  1785. Sched<[]> {
  1786. bits<5> Rd;
  1787. let Inst{31-15} = 0b11011010110000010;
  1788. let Inst{14-12} = opcode_prefix;
  1789. let Inst{11-10} = opcode;
  1790. let Inst{9-5} = 0b11111;
  1791. let Inst{4-0} = Rd;
  1792. }
  1793. class SignAuthTwoOperand<bits<4> opc, string asm,
  1794. SDPatternOperator OpNode>
  1795. : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm),
  1796. asm, "\t$Rd, $Rn, $Rm", "",
  1797. [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>,
  1798. Sched<[WriteI, ReadI, ReadI]> {
  1799. bits<5> Rd;
  1800. bits<5> Rn;
  1801. bits<5> Rm;
  1802. let Inst{31-21} = 0b10011010110;
  1803. let Inst{20-16} = Rm;
  1804. let Inst{15-14} = 0b00;
  1805. let Inst{13-10} = opc;
  1806. let Inst{9-5} = Rn;
  1807. let Inst{4-0} = Rd;
  1808. }
  1809. class ClearAuth<bits<1> data, string asm>
  1810. : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> {
  1811. bits<5> Rd;
  1812. let Inst{31-11} = 0b110110101100000101000;
  1813. let Inst{10} = data;
  1814. let Inst{9-5} = 0b11111;
  1815. let Inst{4-0} = Rd;
  1816. }
  1817. // Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions
  1818. class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops>
  1819. : I<(outs), iops, asm, ops, "", []>,
  1820. Sched<[WriteI, ReadI, ReadI]> {
  1821. let Uses = [NZCV];
  1822. let Defs = [NZCV];
  1823. bits<5> Rn;
  1824. let Inst{31} = sf;
  1825. let Inst{30-15} = 0b0111010000000000;
  1826. let Inst{14} = sz;
  1827. let Inst{13-10} = 0b0010;
  1828. let Inst{9-5} = Rn;
  1829. let Inst{4-0} = 0b01101;
  1830. }
  1831. class FlagRotate<dag iops, string asm, string ops>
  1832. : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> {
  1833. bits<6> imm;
  1834. bits<4> mask;
  1835. let Inst{20-15} = imm;
  1836. let Inst{13-10} = 0b0001;
  1837. let Inst{4} = 0b0;
  1838. let Inst{3-0} = mask;
  1839. }
  1840. //---
  1841. // Basic two-operand data processing instructions.
  1842. //---
  1843. class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
  1844. list<dag> pattern>
  1845. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
  1846. asm, "\t$Rd, $Rn, $Rm", "", pattern>,
  1847. Sched<[WriteI, ReadI, ReadI]> {
  1848. let Uses = [NZCV];
  1849. bits<5> Rd;
  1850. bits<5> Rn;
  1851. bits<5> Rm;
  1852. let Inst{30} = isSub;
  1853. let Inst{28-21} = 0b11010000;
  1854. let Inst{20-16} = Rm;
  1855. let Inst{15-10} = 0;
  1856. let Inst{9-5} = Rn;
  1857. let Inst{4-0} = Rd;
  1858. }
  1859. class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
  1860. SDNode OpNode>
  1861. : BaseBaseAddSubCarry<isSub, regtype, asm,
  1862. [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
  1863. class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
  1864. SDNode OpNode>
  1865. : BaseBaseAddSubCarry<isSub, regtype, asm,
  1866. [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
  1867. (implicit NZCV)]> {
  1868. let Defs = [NZCV];
  1869. }
  1870. multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
  1871. SDNode OpNode, SDNode OpNode_setflags> {
  1872. def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
  1873. let Inst{31} = 0;
  1874. let Inst{29} = 0;
  1875. }
  1876. def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
  1877. let Inst{31} = 1;
  1878. let Inst{29} = 0;
  1879. }
  1880. // Sets flags.
  1881. def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
  1882. OpNode_setflags> {
  1883. let Inst{31} = 0;
  1884. let Inst{29} = 1;
  1885. }
  1886. def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
  1887. OpNode_setflags> {
  1888. let Inst{31} = 1;
  1889. let Inst{29} = 1;
  1890. }
  1891. }
  1892. class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
  1893. SDPatternOperator OpNode,
  1894. RegisterClass in1regtype = regtype,
  1895. RegisterClass in2regtype = regtype>
  1896. : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm),
  1897. asm, "\t$Rd, $Rn, $Rm", "",
  1898. [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> {
  1899. bits<5> Rd;
  1900. bits<5> Rn;
  1901. bits<5> Rm;
  1902. let Inst{30-21} = 0b0011010110;
  1903. let Inst{20-16} = Rm;
  1904. let Inst{15-14} = 0b00;
  1905. let Inst{13-10} = opc;
  1906. let Inst{9-5} = Rn;
  1907. let Inst{4-0} = Rd;
  1908. }
  1909. class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
  1910. SDPatternOperator OpNode>
  1911. : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
  1912. let Inst{10} = isSigned;
  1913. }
  1914. multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
  1915. def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
  1916. Sched<[WriteID32, ReadID, ReadID]> {
  1917. let Inst{31} = 0;
  1918. }
  1919. def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
  1920. Sched<[WriteID64, ReadID, ReadID]> {
  1921. let Inst{31} = 1;
  1922. }
  1923. }
  1924. class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
  1925. SDPatternOperator OpNode = null_frag>
  1926. : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
  1927. Sched<[WriteIS, ReadI]> {
  1928. let Inst{11-10} = shift_type;
  1929. }
  1930. multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
  1931. def Wr : BaseShift<shift_type, GPR32, asm> {
  1932. let Inst{31} = 0;
  1933. }
  1934. def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
  1935. let Inst{31} = 1;
  1936. }
  1937. def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
  1938. (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
  1939. (EXTRACT_SUBREG i64:$Rm, sub_32))>;
  1940. def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
  1941. (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
  1942. def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
  1943. (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
  1944. def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
  1945. (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
  1946. def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))),
  1947. (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
  1948. (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
  1949. def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))),
  1950. (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,
  1951. (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;
  1952. }
  1953. class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
  1954. : InstAlias<asm#"\t$dst, $src1, $src2",
  1955. (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
  1956. class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
  1957. RegisterClass addtype, string asm,
  1958. list<dag> pattern>
  1959. : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
  1960. asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
  1961. bits<5> Rd;
  1962. bits<5> Rn;
  1963. bits<5> Rm;
  1964. bits<5> Ra;
  1965. let Inst{30-24} = 0b0011011;
  1966. let Inst{23-21} = opc;
  1967. let Inst{20-16} = Rm;
  1968. let Inst{15} = isSub;
  1969. let Inst{14-10} = Ra;
  1970. let Inst{9-5} = Rn;
  1971. let Inst{4-0} = Rd;
  1972. }
  1973. multiclass MulAccum<bit isSub, string asm> {
  1974. // MADD/MSUB generation is decided by MachineCombiner.cpp
  1975. def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>,
  1976. Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
  1977. let Inst{31} = 0;
  1978. }
  1979. def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>,
  1980. Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
  1981. let Inst{31} = 1;
  1982. }
  1983. }
  1984. class WideMulAccum<bit isSub, bits<3> opc, string asm,
  1985. SDNode AccNode, SDNode ExtNode>
  1986. : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
  1987. [(set GPR64:$Rd, (AccNode GPR64:$Ra,
  1988. (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
  1989. Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
  1990. let Inst{31} = 1;
  1991. }
  1992. class MulHi<bits<3> opc, string asm, SDNode OpNode>
  1993. : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
  1994. asm, "\t$Rd, $Rn, $Rm", "",
  1995. [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
  1996. Sched<[WriteIM64, ReadIM, ReadIM]> {
  1997. bits<5> Rd;
  1998. bits<5> Rn;
  1999. bits<5> Rm;
  2000. let Inst{31-24} = 0b10011011;
  2001. let Inst{23-21} = opc;
  2002. let Inst{20-16} = Rm;
  2003. let Inst{15} = 0;
  2004. let Inst{9-5} = Rn;
  2005. let Inst{4-0} = Rd;
  2006. // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
  2007. // (i.e. all bits 1) but is ignored by the processor.
  2008. let PostEncoderMethod = "fixMulHigh";
  2009. }
  2010. class MulAccumWAlias<string asm, Instruction inst>
  2011. : InstAlias<asm#"\t$dst, $src1, $src2",
  2012. (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
  2013. class MulAccumXAlias<string asm, Instruction inst>
  2014. : InstAlias<asm#"\t$dst, $src1, $src2",
  2015. (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
  2016. class WideMulAccumAlias<string asm, Instruction inst>
  2017. : InstAlias<asm#"\t$dst, $src1, $src2",
  2018. (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
  2019. class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
  2020. SDPatternOperator OpNode, string asm>
  2021. : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
  2022. asm, "\t$Rd, $Rn, $Rm", "",
  2023. [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
  2024. Sched<[WriteISReg, ReadI, ReadISReg]> {
  2025. bits<5> Rd;
  2026. bits<5> Rn;
  2027. bits<5> Rm;
  2028. let Inst{31} = sf;
  2029. let Inst{30-21} = 0b0011010110;
  2030. let Inst{20-16} = Rm;
  2031. let Inst{15-13} = 0b010;
  2032. let Inst{12} = C;
  2033. let Inst{11-10} = sz;
  2034. let Inst{9-5} = Rn;
  2035. let Inst{4-0} = Rd;
  2036. let Predicates = [HasCRC];
  2037. }
  2038. //---
  2039. // Address generation.
  2040. //---
  2041. class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
  2042. : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
  2043. pattern>,
  2044. Sched<[WriteI]> {
  2045. bits<5> Xd;
  2046. bits<21> label;
  2047. let Inst{31} = page;
  2048. let Inst{30-29} = label{1-0};
  2049. let Inst{28-24} = 0b10000;
  2050. let Inst{23-5} = label{20-2};
  2051. let Inst{4-0} = Xd;
  2052. let DecoderMethod = "DecodeAdrInstruction";
  2053. }
  2054. //---
  2055. // Move immediate.
  2056. //---
  2057. def movimm32_imm : Operand<i32> {
  2058. let ParserMatchClass = AsmImmRange<0, 65535>;
  2059. let EncoderMethod = "getMoveWideImmOpValue";
  2060. let PrintMethod = "printImm";
  2061. }
  2062. def movimm32_shift : Operand<i32> {
  2063. let PrintMethod = "printShifter";
  2064. let ParserMatchClass = MovImm32ShifterOperand;
  2065. }
  2066. def movimm64_shift : Operand<i32> {
  2067. let PrintMethod = "printShifter";
  2068. let ParserMatchClass = MovImm64ShifterOperand;
  2069. }
  2070. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  2071. class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
  2072. string asm>
  2073. : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
  2074. asm, "\t$Rd, $imm$shift", "", []>,
  2075. Sched<[WriteImm]> {
  2076. bits<5> Rd;
  2077. bits<16> imm;
  2078. bits<6> shift;
  2079. let Inst{30-29} = opc;
  2080. let Inst{28-23} = 0b100101;
  2081. let Inst{22-21} = shift{5-4};
  2082. let Inst{20-5} = imm;
  2083. let Inst{4-0} = Rd;
  2084. let DecoderMethod = "DecodeMoveImmInstruction";
  2085. }
  2086. multiclass MoveImmediate<bits<2> opc, string asm> {
  2087. def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
  2088. let Inst{31} = 0;
  2089. }
  2090. def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
  2091. let Inst{31} = 1;
  2092. }
  2093. }
  2094. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  2095. class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
  2096. string asm>
  2097. : I<(outs regtype:$Rd),
  2098. (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
  2099. asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
  2100. Sched<[WriteI, ReadI]> {
  2101. bits<5> Rd;
  2102. bits<16> imm;
  2103. bits<6> shift;
  2104. let Inst{30-29} = opc;
  2105. let Inst{28-23} = 0b100101;
  2106. let Inst{22-21} = shift{5-4};
  2107. let Inst{20-5} = imm;
  2108. let Inst{4-0} = Rd;
  2109. let DecoderMethod = "DecodeMoveImmInstruction";
  2110. }
  2111. multiclass InsertImmediate<bits<2> opc, string asm> {
  2112. def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
  2113. let Inst{31} = 0;
  2114. }
  2115. def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
  2116. let Inst{31} = 1;
  2117. }
  2118. }
  2119. //---
  2120. // Add/Subtract
  2121. //---
  2122. class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
  2123. string asm_inst, string asm_ops,
  2124. dag inputs, dag pattern>
  2125. : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>,
  2126. Sched<[WriteI, ReadI]> {
  2127. bits<5> Rd;
  2128. bits<5> Rn;
  2129. let Inst{30} = isSub;
  2130. let Inst{29} = setFlags;
  2131. let Inst{28-24} = 0b10001;
  2132. let Inst{9-5} = Rn;
  2133. let Inst{4-0} = Rd;
  2134. }
  2135. class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype,
  2136. RegisterClass srcRegtype, addsub_shifted_imm immtype,
  2137. string asm_inst, SDPatternOperator OpNode>
  2138. : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm",
  2139. (ins srcRegtype:$Rn, immtype:$imm),
  2140. (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> {
  2141. bits<14> imm;
  2142. let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
  2143. let Inst{21-10} = imm{11-0};
  2144. let DecoderMethod = "DecodeAddSubImmShift";
  2145. }
  2146. class BaseAddSubRegPseudo<RegisterClass regtype,
  2147. SDPatternOperator OpNode>
  2148. : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
  2149. [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
  2150. Sched<[WriteI, ReadI, ReadI]>;
  2151. class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
  2152. arith_shifted_reg shifted_regtype, string asm,
  2153. SDPatternOperator OpNode>
  2154. : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
  2155. asm, "\t$Rd, $Rn, $Rm", "",
  2156. [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
  2157. Sched<[WriteISReg, ReadI, ReadISReg]> {
  2158. // The operands are in order to match the 'addr' MI operands, so we
  2159. // don't need an encoder method and by-name matching. Just use the default
  2160. // in-order handling. Since we're using by-order, make sure the names
  2161. // do not match.
  2162. bits<5> dst;
  2163. bits<5> src1;
  2164. bits<5> src2;
  2165. bits<8> shift;
  2166. let Inst{30} = isSub;
  2167. let Inst{29} = setFlags;
  2168. let Inst{28-24} = 0b01011;
  2169. let Inst{23-22} = shift{7-6};
  2170. let Inst{21} = 0;
  2171. let Inst{20-16} = src2;
  2172. let Inst{15-10} = shift{5-0};
  2173. let Inst{9-5} = src1;
  2174. let Inst{4-0} = dst;
  2175. let DecoderMethod = "DecodeThreeAddrSRegInstruction";
  2176. }
  2177. class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
  2178. RegisterClass src1Regtype, Operand src2Regtype,
  2179. string asm, SDPatternOperator OpNode>
  2180. : I<(outs dstRegtype:$R1),
  2181. (ins src1Regtype:$R2, src2Regtype:$R3),
  2182. asm, "\t$R1, $R2, $R3", "",
  2183. [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
  2184. Sched<[WriteIEReg, ReadI, ReadIEReg]> {
  2185. bits<5> Rd;
  2186. bits<5> Rn;
  2187. bits<5> Rm;
  2188. bits<6> ext;
  2189. let Inst{30} = isSub;
  2190. let Inst{29} = setFlags;
  2191. let Inst{28-24} = 0b01011;
  2192. let Inst{23-21} = 0b001;
  2193. let Inst{20-16} = Rm;
  2194. let Inst{15-13} = ext{5-3};
  2195. let Inst{12-10} = ext{2-0};
  2196. let Inst{9-5} = Rn;
  2197. let Inst{4-0} = Rd;
  2198. let DecoderMethod = "DecodeAddSubERegInstruction";
  2199. }
  2200. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  2201. class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
  2202. RegisterClass src1Regtype, RegisterClass src2Regtype,
  2203. Operand ext_op, string asm>
  2204. : I<(outs dstRegtype:$Rd),
  2205. (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
  2206. asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
  2207. Sched<[WriteIEReg, ReadI, ReadIEReg]> {
  2208. bits<5> Rd;
  2209. bits<5> Rn;
  2210. bits<5> Rm;
  2211. bits<6> ext;
  2212. let Inst{30} = isSub;
  2213. let Inst{29} = setFlags;
  2214. let Inst{28-24} = 0b01011;
  2215. let Inst{23-21} = 0b001;
  2216. let Inst{20-16} = Rm;
  2217. let Inst{15} = ext{5};
  2218. let Inst{12-10} = ext{2-0};
  2219. let Inst{9-5} = Rn;
  2220. let Inst{4-0} = Rd;
  2221. let DecoderMethod = "DecodeAddSubERegInstruction";
  2222. }
  2223. // Aliases for register+register add/subtract.
  2224. class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
  2225. RegisterClass src1Regtype, RegisterClass src2Regtype,
  2226. int shiftExt>
  2227. : InstAlias<asm#"\t$dst, $src1, $src2",
  2228. (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
  2229. shiftExt)>;
  2230. multiclass AddSub<bit isSub, string mnemonic, string alias,
  2231. SDPatternOperator OpNode = null_frag> {
  2232. let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
  2233. // Add/Subtract immediate
  2234. // Increase the weight of the immediate variant to try to match it before
  2235. // the extended register variant.
  2236. // We used to match the register variant before the immediate when the
  2237. // register argument could be implicitly zero-extended.
  2238. let AddedComplexity = 6 in
  2239. def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
  2240. mnemonic, OpNode> {
  2241. let Inst{31} = 0;
  2242. }
  2243. let AddedComplexity = 6 in
  2244. def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
  2245. mnemonic, OpNode> {
  2246. let Inst{31} = 1;
  2247. }
  2248. // Add/Subtract register - Only used for CodeGen
  2249. def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
  2250. def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
  2251. // Add/Subtract shifted register
  2252. def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
  2253. OpNode> {
  2254. let Inst{31} = 0;
  2255. }
  2256. def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
  2257. OpNode> {
  2258. let Inst{31} = 1;
  2259. }
  2260. }
  2261. // Add/Subtract extended register
  2262. let AddedComplexity = 1, hasSideEffects = 0 in {
  2263. def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
  2264. arith_extended_reg32_i32, mnemonic, OpNode> {
  2265. let Inst{31} = 0;
  2266. }
  2267. def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
  2268. arith_extended_reg32to64_i64, mnemonic, OpNode> {
  2269. let Inst{31} = 1;
  2270. }
  2271. }
  2272. def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
  2273. arith_extendlsl64, mnemonic> {
  2274. // UXTX and SXTX only.
  2275. let Inst{14-13} = 0b11;
  2276. let Inst{31} = 1;
  2277. }
  2278. // add Rd, Rb, -imm -> sub Rd, Rn, imm
  2279. def : InstSubst<alias#"\t$Rd, $Rn, $imm",
  2280. (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
  2281. addsub_shifted_imm32_neg:$imm), 0>;
  2282. def : InstSubst<alias#"\t$Rd, $Rn, $imm",
  2283. (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
  2284. addsub_shifted_imm64_neg:$imm), 0>;
  2285. // Register/register aliases with no shift when SP is not used.
  2286. def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
  2287. GPR32, GPR32, GPR32, 0>;
  2288. def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
  2289. GPR64, GPR64, GPR64, 0>;
  2290. // Register/register aliases with no shift when either the destination or
  2291. // first source register is SP.
  2292. def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
  2293. GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
  2294. def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
  2295. GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
  2296. def : AddSubRegAlias<mnemonic,
  2297. !cast<Instruction>(NAME#"Xrx64"),
  2298. GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
  2299. def : AddSubRegAlias<mnemonic,
  2300. !cast<Instruction>(NAME#"Xrx64"),
  2301. GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
  2302. }
  2303. multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
  2304. string alias, string cmpAlias> {
  2305. let isCompare = 1, Defs = [NZCV] in {
  2306. // Add/Subtract immediate
  2307. def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
  2308. mnemonic, OpNode> {
  2309. let Inst{31} = 0;
  2310. }
  2311. def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
  2312. mnemonic, OpNode> {
  2313. let Inst{31} = 1;
  2314. }
  2315. // Add/Subtract register
  2316. def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
  2317. def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
  2318. // Add/Subtract shifted register
  2319. def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
  2320. OpNode> {
  2321. let Inst{31} = 0;
  2322. }
  2323. def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
  2324. OpNode> {
  2325. let Inst{31} = 1;
  2326. }
  2327. // Add/Subtract extended register
  2328. let AddedComplexity = 1 in {
  2329. def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
  2330. arith_extended_reg32_i32, mnemonic, OpNode> {
  2331. let Inst{31} = 0;
  2332. }
  2333. def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
  2334. arith_extended_reg32_i64, mnemonic, OpNode> {
  2335. let Inst{31} = 1;
  2336. }
  2337. }
  2338. def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
  2339. arith_extendlsl64, mnemonic> {
  2340. // UXTX and SXTX only.
  2341. let Inst{14-13} = 0b11;
  2342. let Inst{31} = 1;
  2343. }
  2344. } // Defs = [NZCV]
  2345. // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
  2346. def : InstSubst<alias#"\t$Rd, $Rn, $imm",
  2347. (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
  2348. addsub_shifted_imm32_neg:$imm), 0>;
  2349. def : InstSubst<alias#"\t$Rd, $Rn, $imm",
  2350. (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
  2351. addsub_shifted_imm64_neg:$imm), 0>;
  2352. // Compare aliases
  2353. def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
  2354. WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
  2355. def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
  2356. XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
  2357. def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
  2358. WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
  2359. def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
  2360. XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
  2361. def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
  2362. XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
  2363. def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
  2364. WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
  2365. def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
  2366. XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
  2367. // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
  2368. def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
  2369. WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
  2370. def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
  2371. XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
  2372. // Compare shorthands
  2373. def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
  2374. WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
  2375. def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
  2376. XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
  2377. def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
  2378. WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
  2379. def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
  2380. XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
  2381. // Register/register aliases with no shift when SP is not used.
  2382. def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
  2383. GPR32, GPR32, GPR32, 0>;
  2384. def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
  2385. GPR64, GPR64, GPR64, 0>;
  2386. // Register/register aliases with no shift when the first source register
  2387. // is SP.
  2388. def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
  2389. GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
  2390. def : AddSubRegAlias<mnemonic,
  2391. !cast<Instruction>(NAME#"Xrx64"),
  2392. GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
  2393. }
  2394. class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode>
  2395. : BaseAddSubImm<
  2396. isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4",
  2397. (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4),
  2398. (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> {
  2399. bits<6> imm6;
  2400. bits<4> imm4;
  2401. let Inst{31} = 1;
  2402. let Inst{23-22} = 0b10;
  2403. let Inst{21-16} = imm6;
  2404. let Inst{15-14} = 0b00;
  2405. let Inst{13-10} = imm4;
  2406. let Unpredictable{15-14} = 0b11;
  2407. }
  2408. class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode>
  2409. : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> {
  2410. let Inst{31} = 1;
  2411. let Inst{29} = setsFlags;
  2412. }
  2413. //---
  2414. // Extract
  2415. //---
  2416. def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
  2417. SDTCisPtrTy<3>]>;
  2418. def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
  2419. class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
  2420. list<dag> patterns>
  2421. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
  2422. asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
  2423. Sched<[WriteExtr, ReadExtrHi]> {
  2424. bits<5> Rd;
  2425. bits<5> Rn;
  2426. bits<5> Rm;
  2427. bits<6> imm;
  2428. let Inst{30-23} = 0b00100111;
  2429. let Inst{21} = 0;
  2430. let Inst{20-16} = Rm;
  2431. let Inst{15-10} = imm;
  2432. let Inst{9-5} = Rn;
  2433. let Inst{4-0} = Rd;
  2434. }
  2435. multiclass ExtractImm<string asm> {
  2436. def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
  2437. [(set GPR32:$Rd,
  2438. (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
  2439. let Inst{31} = 0;
  2440. let Inst{22} = 0;
  2441. // imm<5> must be zero.
  2442. let imm{5} = 0;
  2443. }
  2444. def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
  2445. [(set GPR64:$Rd,
  2446. (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
  2447. let Inst{31} = 1;
  2448. let Inst{22} = 1;
  2449. }
  2450. }
  2451. //---
  2452. // Bitfield
  2453. //---
  2454. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  2455. class BaseBitfieldImm<bits<2> opc,
  2456. RegisterClass regtype, Operand imm_type, string asm>
  2457. : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
  2458. asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
  2459. Sched<[WriteIS, ReadI]> {
  2460. bits<5> Rd;
  2461. bits<5> Rn;
  2462. bits<6> immr;
  2463. bits<6> imms;
  2464. let Inst{30-29} = opc;
  2465. let Inst{28-23} = 0b100110;
  2466. let Inst{21-16} = immr;
  2467. let Inst{15-10} = imms;
  2468. let Inst{9-5} = Rn;
  2469. let Inst{4-0} = Rd;
  2470. }
  2471. multiclass BitfieldImm<bits<2> opc, string asm> {
  2472. def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
  2473. let Inst{31} = 0;
  2474. let Inst{22} = 0;
  2475. // imms<5> and immr<5> must be zero, else ReservedValue().
  2476. let Inst{21} = 0;
  2477. let Inst{15} = 0;
  2478. }
  2479. def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
  2480. let Inst{31} = 1;
  2481. let Inst{22} = 1;
  2482. }
  2483. }
  2484. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  2485. class BaseBitfieldImmWith2RegArgs<bits<2> opc,
  2486. RegisterClass regtype, Operand imm_type, string asm>
  2487. : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
  2488. imm_type:$imms),
  2489. asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
  2490. Sched<[WriteIS, ReadI]> {
  2491. bits<5> Rd;
  2492. bits<5> Rn;
  2493. bits<6> immr;
  2494. bits<6> imms;
  2495. let Inst{30-29} = opc;
  2496. let Inst{28-23} = 0b100110;
  2497. let Inst{21-16} = immr;
  2498. let Inst{15-10} = imms;
  2499. let Inst{9-5} = Rn;
  2500. let Inst{4-0} = Rd;
  2501. }
  2502. multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
  2503. def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
  2504. let Inst{31} = 0;
  2505. let Inst{22} = 0;
  2506. // imms<5> and immr<5> must be zero, else ReservedValue().
  2507. let Inst{21} = 0;
  2508. let Inst{15} = 0;
  2509. }
  2510. def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
  2511. let Inst{31} = 1;
  2512. let Inst{22} = 1;
  2513. }
  2514. }
  2515. //---
  2516. // Logical
  2517. //---
  2518. // Logical (immediate)
  2519. class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
  2520. RegisterClass sregtype, Operand imm_type, string asm,
  2521. list<dag> pattern>
  2522. : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
  2523. asm, "\t$Rd, $Rn, $imm", "", pattern>,
  2524. Sched<[WriteI, ReadI]> {
  2525. bits<5> Rd;
  2526. bits<5> Rn;
  2527. bits<13> imm;
  2528. let Inst{30-29} = opc;
  2529. let Inst{28-23} = 0b100100;
  2530. let Inst{22} = imm{12};
  2531. let Inst{21-16} = imm{11-6};
  2532. let Inst{15-10} = imm{5-0};
  2533. let Inst{9-5} = Rn;
  2534. let Inst{4-0} = Rd;
  2535. let DecoderMethod = "DecodeLogicalImmInstruction";
  2536. }
  2537. // Logical (shifted register)
  2538. class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
  2539. logical_shifted_reg shifted_regtype, string asm,
  2540. list<dag> pattern>
  2541. : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
  2542. asm, "\t$Rd, $Rn, $Rm", "", pattern>,
  2543. Sched<[WriteISReg, ReadI, ReadISReg]> {
  2544. // The operands are in order to match the 'addr' MI operands, so we
  2545. // don't need an encoder method and by-name matching. Just use the default
  2546. // in-order handling. Since we're using by-order, make sure the names
  2547. // do not match.
  2548. bits<5> dst;
  2549. bits<5> src1;
  2550. bits<5> src2;
  2551. bits<8> shift;
  2552. let Inst{30-29} = opc;
  2553. let Inst{28-24} = 0b01010;
  2554. let Inst{23-22} = shift{7-6};
  2555. let Inst{21} = N;
  2556. let Inst{20-16} = src2;
  2557. let Inst{15-10} = shift{5-0};
  2558. let Inst{9-5} = src1;
  2559. let Inst{4-0} = dst;
  2560. let DecoderMethod = "DecodeThreeAddrSRegInstruction";
  2561. }
  2562. // Aliases for register+register logical instructions.
  2563. class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
  2564. : InstAlias<asm#"\t$dst, $src1, $src2",
  2565. (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
  2566. multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
  2567. string Alias> {
  2568. let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
  2569. def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
  2570. [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
  2571. logical_imm32:$imm))]> {
  2572. let Inst{31} = 0;
  2573. let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
  2574. }
  2575. let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
  2576. def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
  2577. [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
  2578. logical_imm64:$imm))]> {
  2579. let Inst{31} = 1;
  2580. }
  2581. def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
  2582. (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
  2583. logical_imm32_not:$imm), 0>;
  2584. def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
  2585. (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
  2586. logical_imm64_not:$imm), 0>;
  2587. }
  2588. multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
  2589. string Alias> {
  2590. let isCompare = 1, Defs = [NZCV] in {
  2591. def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
  2592. [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
  2593. let Inst{31} = 0;
  2594. let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
  2595. }
  2596. def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
  2597. [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
  2598. let Inst{31} = 1;
  2599. }
  2600. } // end Defs = [NZCV]
  2601. def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
  2602. (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
  2603. logical_imm32_not:$imm), 0>;
  2604. def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
  2605. (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
  2606. logical_imm64_not:$imm), 0>;
  2607. }
  2608. class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
  2609. : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
  2610. [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
  2611. Sched<[WriteI, ReadI, ReadI]>;
  2612. // Split from LogicalImm as not all instructions have both.
  2613. multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
  2614. SDPatternOperator OpNode> {
  2615. let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
  2616. def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
  2617. def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
  2618. }
  2619. def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
  2620. [(set GPR32:$Rd, (OpNode GPR32:$Rn,
  2621. logical_shifted_reg32:$Rm))]> {
  2622. let Inst{31} = 0;
  2623. }
  2624. def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
  2625. [(set GPR64:$Rd, (OpNode GPR64:$Rn,
  2626. logical_shifted_reg64:$Rm))]> {
  2627. let Inst{31} = 1;
  2628. }
  2629. def : LogicalRegAlias<mnemonic,
  2630. !cast<Instruction>(NAME#"Wrs"), GPR32>;
  2631. def : LogicalRegAlias<mnemonic,
  2632. !cast<Instruction>(NAME#"Xrs"), GPR64>;
  2633. }
  2634. // Split from LogicalReg to allow setting NZCV Defs
  2635. multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
  2636. SDPatternOperator OpNode = null_frag> {
  2637. let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
  2638. def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
  2639. def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
  2640. def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
  2641. [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
  2642. let Inst{31} = 0;
  2643. }
  2644. def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
  2645. [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
  2646. let Inst{31} = 1;
  2647. }
  2648. } // Defs = [NZCV]
  2649. def : LogicalRegAlias<mnemonic,
  2650. !cast<Instruction>(NAME#"Wrs"), GPR32>;
  2651. def : LogicalRegAlias<mnemonic,
  2652. !cast<Instruction>(NAME#"Xrs"), GPR64>;
  2653. }
  2654. //---
  2655. // Conditionally set flags
  2656. //---
  2657. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  2658. class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
  2659. string mnemonic, SDNode OpNode>
  2660. : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
  2661. mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
  2662. [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
  2663. (i32 imm:$cond), NZCV))]>,
  2664. Sched<[WriteI, ReadI]> {
  2665. let Uses = [NZCV];
  2666. let Defs = [NZCV];
  2667. bits<5> Rn;
  2668. bits<5> imm;
  2669. bits<4> nzcv;
  2670. bits<4> cond;
  2671. let Inst{30} = op;
  2672. let Inst{29-21} = 0b111010010;
  2673. let Inst{20-16} = imm;
  2674. let Inst{15-12} = cond;
  2675. let Inst{11-10} = 0b10;
  2676. let Inst{9-5} = Rn;
  2677. let Inst{4} = 0b0;
  2678. let Inst{3-0} = nzcv;
  2679. }
  2680. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  2681. class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
  2682. SDNode OpNode>
  2683. : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
  2684. mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
  2685. [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
  2686. (i32 imm:$cond), NZCV))]>,
  2687. Sched<[WriteI, ReadI, ReadI]> {
  2688. let Uses = [NZCV];
  2689. let Defs = [NZCV];
  2690. bits<5> Rn;
  2691. bits<5> Rm;
  2692. bits<4> nzcv;
  2693. bits<4> cond;
  2694. let Inst{30} = op;
  2695. let Inst{29-21} = 0b111010010;
  2696. let Inst{20-16} = Rm;
  2697. let Inst{15-12} = cond;
  2698. let Inst{11-10} = 0b00;
  2699. let Inst{9-5} = Rn;
  2700. let Inst{4} = 0b0;
  2701. let Inst{3-0} = nzcv;
  2702. }
  2703. multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
  2704. // immediate operand variants
  2705. def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
  2706. let Inst{31} = 0;
  2707. }
  2708. def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
  2709. let Inst{31} = 1;
  2710. }
  2711. // register operand variants
  2712. def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
  2713. let Inst{31} = 0;
  2714. }
  2715. def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
  2716. let Inst{31} = 1;
  2717. }
  2718. }
  2719. //---
  2720. // Conditional select
  2721. //---
  2722. class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
  2723. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
  2724. asm, "\t$Rd, $Rn, $Rm, $cond", "",
  2725. [(set regtype:$Rd,
  2726. (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
  2727. Sched<[WriteI, ReadI, ReadI]> {
  2728. let Uses = [NZCV];
  2729. bits<5> Rd;
  2730. bits<5> Rn;
  2731. bits<5> Rm;
  2732. bits<4> cond;
  2733. let Inst{30} = op;
  2734. let Inst{29-21} = 0b011010100;
  2735. let Inst{20-16} = Rm;
  2736. let Inst{15-12} = cond;
  2737. let Inst{11-10} = op2;
  2738. let Inst{9-5} = Rn;
  2739. let Inst{4-0} = Rd;
  2740. }
  2741. multiclass CondSelect<bit op, bits<2> op2, string asm> {
  2742. def Wr : BaseCondSelect<op, op2, GPR32, asm> {
  2743. let Inst{31} = 0;
  2744. }
  2745. def Xr : BaseCondSelect<op, op2, GPR64, asm> {
  2746. let Inst{31} = 1;
  2747. }
  2748. }
  2749. class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
  2750. PatFrag frag>
  2751. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
  2752. asm, "\t$Rd, $Rn, $Rm, $cond", "",
  2753. [(set regtype:$Rd,
  2754. (AArch64csel regtype:$Rn, (frag regtype:$Rm),
  2755. (i32 imm:$cond), NZCV))]>,
  2756. Sched<[WriteI, ReadI, ReadI]> {
  2757. let Uses = [NZCV];
  2758. bits<5> Rd;
  2759. bits<5> Rn;
  2760. bits<5> Rm;
  2761. bits<4> cond;
  2762. let Inst{30} = op;
  2763. let Inst{29-21} = 0b011010100;
  2764. let Inst{20-16} = Rm;
  2765. let Inst{15-12} = cond;
  2766. let Inst{11-10} = op2;
  2767. let Inst{9-5} = Rn;
  2768. let Inst{4-0} = Rd;
  2769. }
  2770. def inv_cond_XFORM : SDNodeXForm<imm, [{
  2771. AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
  2772. return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
  2773. MVT::i32);
  2774. }]>;
  2775. multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
  2776. def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
  2777. let Inst{31} = 0;
  2778. }
  2779. def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
  2780. let Inst{31} = 1;
  2781. }
  2782. def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
  2783. (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
  2784. (inv_cond_XFORM imm:$cond))>;
  2785. def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
  2786. (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
  2787. (inv_cond_XFORM imm:$cond))>;
  2788. }
  2789. //---
  2790. // Special Mask Value
  2791. //---
  2792. def maski8_or_more : Operand<i32>,
  2793. ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
  2794. }
  2795. def maski16_or_more : Operand<i32>,
  2796. ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
  2797. }
  2798. //---
  2799. // Load/store
  2800. //---
  2801. // (unsigned immediate)
  2802. // Indexed for 8-bit registers. offset is in range [0,4095].
  2803. def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>;
  2804. def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>;
  2805. def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>;
  2806. def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>;
  2807. def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>;
  2808. // (unsigned immediate)
  2809. // Indexed for 8-bit registers. offset is in range [0,63].
  2810. def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>;
  2811. def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>;
  2812. def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>;
  2813. def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>;
  2814. def gi_am_indexed8 :
  2815. GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">,
  2816. GIComplexPatternEquiv<am_indexed8>;
  2817. def gi_am_indexed16 :
  2818. GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">,
  2819. GIComplexPatternEquiv<am_indexed16>;
  2820. def gi_am_indexed32 :
  2821. GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">,
  2822. GIComplexPatternEquiv<am_indexed32>;
  2823. def gi_am_indexed64 :
  2824. GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">,
  2825. GIComplexPatternEquiv<am_indexed64>;
  2826. def gi_am_indexed128 :
  2827. GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">,
  2828. GIComplexPatternEquiv<am_indexed128>;
  2829. class UImm12OffsetOperand<int Scale> : AsmOperandClass {
  2830. let Name = "UImm12Offset" # Scale;
  2831. let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
  2832. let PredicateMethod = "isUImm12Offset<" # Scale # ">";
  2833. let DiagnosticType = "InvalidMemoryIndexed" # Scale;
  2834. }
  2835. def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
  2836. def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
  2837. def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
  2838. def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
  2839. def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
  2840. class uimm12_scaled<int Scale> : Operand<i64> {
  2841. let ParserMatchClass
  2842. = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
  2843. let EncoderMethod
  2844. = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
  2845. let PrintMethod = "printUImm12Offset<" # Scale # ">";
  2846. }
  2847. def uimm12s1 : uimm12_scaled<1>;
  2848. def uimm12s2 : uimm12_scaled<2>;
  2849. def uimm12s4 : uimm12_scaled<4>;
  2850. def uimm12s8 : uimm12_scaled<8>;
  2851. def uimm12s16 : uimm12_scaled<16>;
  2852. class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
  2853. string asm, list<dag> pattern>
  2854. : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
  2855. bits<5> Rt;
  2856. bits<5> Rn;
  2857. bits<12> offset;
  2858. let Inst{31-30} = sz;
  2859. let Inst{29-27} = 0b111;
  2860. let Inst{26} = V;
  2861. let Inst{25-24} = 0b01;
  2862. let Inst{23-22} = opc;
  2863. let Inst{21-10} = offset;
  2864. let Inst{9-5} = Rn;
  2865. let Inst{4-0} = Rt;
  2866. let DecoderMethod = "DecodeUnsignedLdStInstruction";
  2867. }
  2868. multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  2869. Operand indextype, string asm, list<dag> pattern> {
  2870. let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
  2871. def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
  2872. (ins GPR64sp:$Rn, indextype:$offset),
  2873. asm, pattern>,
  2874. Sched<[WriteLD]>;
  2875. def : InstAlias<asm # "\t$Rt, [$Rn]",
  2876. (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
  2877. }
  2878. multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  2879. Operand indextype, string asm, list<dag> pattern> {
  2880. let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
  2881. def ui : BaseLoadStoreUI<sz, V, opc, (outs),
  2882. (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
  2883. asm, pattern>,
  2884. Sched<[WriteST]>;
  2885. def : InstAlias<asm # "\t$Rt, [$Rn]",
  2886. (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
  2887. }
  2888. // Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to
  2889. // substitute zero-registers automatically.
  2890. //
  2891. // TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back
  2892. // into StoreUI.
  2893. multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
  2894. Operand indextype, string asm, list<dag> pattern> {
  2895. let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
  2896. def ui : BaseLoadStoreUI<sz, V, opc, (outs),
  2897. (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
  2898. asm, pattern>,
  2899. Sched<[WriteST]>;
  2900. def : InstAlias<asm # "\t$Rt, [$Rn]",
  2901. (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
  2902. }
  2903. def PrefetchOperand : AsmOperandClass {
  2904. let Name = "Prefetch";
  2905. let ParserMethod = "tryParsePrefetch";
  2906. }
  2907. def prfop : Operand<i32> {
  2908. let PrintMethod = "printPrefetchOp";
  2909. let ParserMatchClass = PrefetchOperand;
  2910. }
  2911. let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
  2912. class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
  2913. : BaseLoadStoreUI<sz, V, opc,
  2914. (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
  2915. asm, pat>,
  2916. Sched<[WriteLD]>;
  2917. //---
  2918. // Load literal
  2919. //---
  2920. // Load literal address: 19-bit immediate. The low two bits of the target
  2921. // offset are implied zero and so are not part of the immediate.
  2922. def am_ldrlit : Operand<iPTR> {
  2923. let EncoderMethod = "getLoadLiteralOpValue";
  2924. let DecoderMethod = "DecodePCRelLabel19";
  2925. let PrintMethod = "printAlignedLabel";
  2926. let ParserMatchClass = PCRelLabel19Operand;
  2927. let OperandType = "OPERAND_PCREL";
  2928. }
  2929. let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in
  2930. class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat>
  2931. : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
  2932. asm, "\t$Rt, $label", "", pat>,
  2933. Sched<[WriteLD]> {
  2934. bits<5> Rt;
  2935. bits<19> label;
  2936. let Inst{31-30} = opc;
  2937. let Inst{29-27} = 0b011;
  2938. let Inst{26} = V;
  2939. let Inst{25-24} = 0b00;
  2940. let Inst{23-5} = label;
  2941. let Inst{4-0} = Rt;
  2942. }
  2943. let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
  2944. class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
  2945. : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
  2946. asm, "\t$Rt, $label", "", pat>,
  2947. Sched<[WriteLD]> {
  2948. bits<5> Rt;
  2949. bits<19> label;
  2950. let Inst{31-30} = opc;
  2951. let Inst{29-27} = 0b011;
  2952. let Inst{26} = V;
  2953. let Inst{25-24} = 0b00;
  2954. let Inst{23-5} = label;
  2955. let Inst{4-0} = Rt;
  2956. }
  2957. //---
  2958. // Load/store register offset
  2959. //---
  2960. def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>;
  2961. def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>;
  2962. def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>;
  2963. def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>;
  2964. def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>;
  2965. def gi_ro_Xindexed8 :
  2966. GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">,
  2967. GIComplexPatternEquiv<ro_Xindexed8>;
  2968. def gi_ro_Xindexed16 :
  2969. GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">,
  2970. GIComplexPatternEquiv<ro_Xindexed16>;
  2971. def gi_ro_Xindexed32 :
  2972. GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">,
  2973. GIComplexPatternEquiv<ro_Xindexed32>;
  2974. def gi_ro_Xindexed64 :
  2975. GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">,
  2976. GIComplexPatternEquiv<ro_Xindexed64>;
  2977. def gi_ro_Xindexed128 :
  2978. GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">,
  2979. GIComplexPatternEquiv<ro_Xindexed128>;
  2980. def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>;
  2981. def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>;
  2982. def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>;
  2983. def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>;
  2984. def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>;
  2985. def gi_ro_Windexed8 :
  2986. GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">,
  2987. GIComplexPatternEquiv<ro_Windexed8>;
  2988. def gi_ro_Windexed16 :
  2989. GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">,
  2990. GIComplexPatternEquiv<ro_Windexed16>;
  2991. def gi_ro_Windexed32 :
  2992. GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">,
  2993. GIComplexPatternEquiv<ro_Windexed32>;
  2994. def gi_ro_Windexed64 :
  2995. GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">,
  2996. GIComplexPatternEquiv<ro_Windexed64>;
  2997. def gi_ro_Windexed128 :
  2998. GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">,
  2999. GIComplexPatternEquiv<ro_Windexed128>;
  3000. class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
  3001. let Name = "Mem" # Reg # "Extend" # Width;
  3002. let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
  3003. let RenderMethod = "addMemExtendOperands";
  3004. let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
  3005. }
  3006. def MemWExtend8Operand : MemExtendOperand<"W", 8> {
  3007. // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
  3008. // the trivial shift.
  3009. let RenderMethod = "addMemExtend8Operands";
  3010. }
  3011. def MemWExtend16Operand : MemExtendOperand<"W", 16>;
  3012. def MemWExtend32Operand : MemExtendOperand<"W", 32>;
  3013. def MemWExtend64Operand : MemExtendOperand<"W", 64>;
  3014. def MemWExtend128Operand : MemExtendOperand<"W", 128>;
  3015. def MemXExtend8Operand : MemExtendOperand<"X", 8> {
  3016. // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
  3017. // the trivial shift.
  3018. let RenderMethod = "addMemExtend8Operands";
  3019. }
  3020. def MemXExtend16Operand : MemExtendOperand<"X", 16>;
  3021. def MemXExtend32Operand : MemExtendOperand<"X", 32>;
  3022. def MemXExtend64Operand : MemExtendOperand<"X", 64>;
  3023. def MemXExtend128Operand : MemExtendOperand<"X", 128>;
  3024. class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
  3025. : Operand<i32> {
  3026. let ParserMatchClass = ParserClass;
  3027. let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
  3028. let DecoderMethod = "DecodeMemExtend";
  3029. let EncoderMethod = "getMemExtendOpValue";
  3030. let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
  3031. }
  3032. def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;
  3033. def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;
  3034. def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;
  3035. def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;
  3036. def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
  3037. def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;
  3038. def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;
  3039. def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;
  3040. def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;
  3041. def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
  3042. class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
  3043. Operand wextend, Operand xextend> {
  3044. // CodeGen-level pattern covering the entire addressing mode.
  3045. ComplexPattern Wpat = windex;
  3046. ComplexPattern Xpat = xindex;
  3047. // Asm-level Operand covering the valid "uxtw #3" style syntax.
  3048. Operand Wext = wextend;
  3049. Operand Xext = xextend;
  3050. }
  3051. def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
  3052. def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
  3053. def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
  3054. def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
  3055. def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
  3056. ro_Xextend128>;
  3057. class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,
  3058. dag outs, list<dag> pat>
  3059. : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
  3060. bits<5> Rt;
  3061. bits<5> Rn;
  3062. bits<5> Rm;
  3063. bits<2> extend;
  3064. let Inst{31-30} = sz;
  3065. let Inst{29-27} = 0b111;
  3066. let Inst{26} = V;
  3067. let Inst{25-24} = 0b00;
  3068. let Inst{23-22} = opc;
  3069. let Inst{21} = 1;
  3070. let Inst{20-16} = Rm;
  3071. let Inst{15} = extend{1}; // sign extend Rm?
  3072. let Inst{14} = 1;
  3073. let Inst{12} = extend{0}; // do shift?
  3074. let Inst{11-10} = 0b10;
  3075. let Inst{9-5} = Rn;
  3076. let Inst{4-0} = Rt;
  3077. }
  3078. class ROInstAlias<string asm, DAGOperand regtype, Instruction INST>
  3079. : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
  3080. (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
  3081. multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3082. string asm, ValueType Ty, SDPatternOperator loadop> {
  3083. let AddedComplexity = 10 in
  3084. def roW : LoadStore8RO<sz, V, opc, asm,
  3085. (outs regtype:$Rt),
  3086. (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
  3087. [(set (Ty regtype:$Rt),
  3088. (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
  3089. ro_Wextend8:$extend)))]>,
  3090. Sched<[WriteLDIdx, ReadAdrBase]> {
  3091. let Inst{13} = 0b0;
  3092. }
  3093. let AddedComplexity = 10 in
  3094. def roX : LoadStore8RO<sz, V, opc, asm,
  3095. (outs regtype:$Rt),
  3096. (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
  3097. [(set (Ty regtype:$Rt),
  3098. (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
  3099. ro_Xextend8:$extend)))]>,
  3100. Sched<[WriteLDIdx, ReadAdrBase]> {
  3101. let Inst{13} = 0b1;
  3102. }
  3103. def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
  3104. }
  3105. multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3106. string asm, ValueType Ty, SDPatternOperator storeop> {
  3107. let AddedComplexity = 10 in
  3108. def roW : LoadStore8RO<sz, V, opc, asm, (outs),
  3109. (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
  3110. [(storeop (Ty regtype:$Rt),
  3111. (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
  3112. ro_Wextend8:$extend))]>,
  3113. Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
  3114. let Inst{13} = 0b0;
  3115. }
  3116. let AddedComplexity = 10 in
  3117. def roX : LoadStore8RO<sz, V, opc, asm, (outs),
  3118. (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
  3119. [(storeop (Ty regtype:$Rt),
  3120. (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
  3121. ro_Xextend8:$extend))]>,
  3122. Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
  3123. let Inst{13} = 0b1;
  3124. }
  3125. def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
  3126. }
  3127. class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,
  3128. dag outs, list<dag> pat>
  3129. : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
  3130. bits<5> Rt;
  3131. bits<5> Rn;
  3132. bits<5> Rm;
  3133. bits<2> extend;
  3134. let Inst{31-30} = sz;
  3135. let Inst{29-27} = 0b111;
  3136. let Inst{26} = V;
  3137. let Inst{25-24} = 0b00;
  3138. let Inst{23-22} = opc;
  3139. let Inst{21} = 1;
  3140. let Inst{20-16} = Rm;
  3141. let Inst{15} = extend{1}; // sign extend Rm?
  3142. let Inst{14} = 1;
  3143. let Inst{12} = extend{0}; // do shift?
  3144. let Inst{11-10} = 0b10;
  3145. let Inst{9-5} = Rn;
  3146. let Inst{4-0} = Rt;
  3147. }
  3148. multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3149. string asm, ValueType Ty, SDPatternOperator loadop> {
  3150. let AddedComplexity = 10 in
  3151. def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt),
  3152. (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
  3153. [(set (Ty regtype:$Rt),
  3154. (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
  3155. ro_Wextend16:$extend)))]>,
  3156. Sched<[WriteLDIdx, ReadAdrBase]> {
  3157. let Inst{13} = 0b0;
  3158. }
  3159. let AddedComplexity = 10 in
  3160. def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt),
  3161. (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
  3162. [(set (Ty regtype:$Rt),
  3163. (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
  3164. ro_Xextend16:$extend)))]>,
  3165. Sched<[WriteLDIdx, ReadAdrBase]> {
  3166. let Inst{13} = 0b1;
  3167. }
  3168. def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
  3169. }
  3170. multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3171. string asm, ValueType Ty, SDPatternOperator storeop> {
  3172. let AddedComplexity = 10 in
  3173. def roW : LoadStore16RO<sz, V, opc, asm, (outs),
  3174. (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
  3175. [(storeop (Ty regtype:$Rt),
  3176. (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
  3177. ro_Wextend16:$extend))]>,
  3178. Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
  3179. let Inst{13} = 0b0;
  3180. }
  3181. let AddedComplexity = 10 in
  3182. def roX : LoadStore16RO<sz, V, opc, asm, (outs),
  3183. (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
  3184. [(storeop (Ty regtype:$Rt),
  3185. (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
  3186. ro_Xextend16:$extend))]>,
  3187. Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
  3188. let Inst{13} = 0b1;
  3189. }
  3190. def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
  3191. }
  3192. class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,
  3193. dag outs, list<dag> pat>
  3194. : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
  3195. bits<5> Rt;
  3196. bits<5> Rn;
  3197. bits<5> Rm;
  3198. bits<2> extend;
  3199. let Inst{31-30} = sz;
  3200. let Inst{29-27} = 0b111;
  3201. let Inst{26} = V;
  3202. let Inst{25-24} = 0b00;
  3203. let Inst{23-22} = opc;
  3204. let Inst{21} = 1;
  3205. let Inst{20-16} = Rm;
  3206. let Inst{15} = extend{1}; // sign extend Rm?
  3207. let Inst{14} = 1;
  3208. let Inst{12} = extend{0}; // do shift?
  3209. let Inst{11-10} = 0b10;
  3210. let Inst{9-5} = Rn;
  3211. let Inst{4-0} = Rt;
  3212. }
  3213. multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3214. string asm, ValueType Ty, SDPatternOperator loadop> {
  3215. let AddedComplexity = 10 in
  3216. def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt),
  3217. (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
  3218. [(set (Ty regtype:$Rt),
  3219. (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
  3220. ro_Wextend32:$extend)))]>,
  3221. Sched<[WriteLDIdx, ReadAdrBase]> {
  3222. let Inst{13} = 0b0;
  3223. }
  3224. let AddedComplexity = 10 in
  3225. def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt),
  3226. (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
  3227. [(set (Ty regtype:$Rt),
  3228. (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
  3229. ro_Xextend32:$extend)))]>,
  3230. Sched<[WriteLDIdx, ReadAdrBase]> {
  3231. let Inst{13} = 0b1;
  3232. }
  3233. def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
  3234. }
  3235. multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3236. string asm, ValueType Ty, SDPatternOperator storeop> {
  3237. let AddedComplexity = 10 in
  3238. def roW : LoadStore32RO<sz, V, opc, asm, (outs),
  3239. (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
  3240. [(storeop (Ty regtype:$Rt),
  3241. (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
  3242. ro_Wextend32:$extend))]>,
  3243. Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
  3244. let Inst{13} = 0b0;
  3245. }
  3246. let AddedComplexity = 10 in
  3247. def roX : LoadStore32RO<sz, V, opc, asm, (outs),
  3248. (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
  3249. [(storeop (Ty regtype:$Rt),
  3250. (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
  3251. ro_Xextend32:$extend))]>,
  3252. Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
  3253. let Inst{13} = 0b1;
  3254. }
  3255. def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
  3256. }
  3257. class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,
  3258. dag outs, list<dag> pat>
  3259. : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
  3260. bits<5> Rt;
  3261. bits<5> Rn;
  3262. bits<5> Rm;
  3263. bits<2> extend;
  3264. let Inst{31-30} = sz;
  3265. let Inst{29-27} = 0b111;
  3266. let Inst{26} = V;
  3267. let Inst{25-24} = 0b00;
  3268. let Inst{23-22} = opc;
  3269. let Inst{21} = 1;
  3270. let Inst{20-16} = Rm;
  3271. let Inst{15} = extend{1}; // sign extend Rm?
  3272. let Inst{14} = 1;
  3273. let Inst{12} = extend{0}; // do shift?
  3274. let Inst{11-10} = 0b10;
  3275. let Inst{9-5} = Rn;
  3276. let Inst{4-0} = Rt;
  3277. }
  3278. multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3279. string asm, ValueType Ty, SDPatternOperator loadop> {
  3280. let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
  3281. def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt),
  3282. (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
  3283. [(set (Ty regtype:$Rt),
  3284. (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
  3285. ro_Wextend64:$extend)))]>,
  3286. Sched<[WriteLDIdx, ReadAdrBase]> {
  3287. let Inst{13} = 0b0;
  3288. }
  3289. let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
  3290. def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt),
  3291. (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
  3292. [(set (Ty regtype:$Rt),
  3293. (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
  3294. ro_Xextend64:$extend)))]>,
  3295. Sched<[WriteLDIdx, ReadAdrBase]> {
  3296. let Inst{13} = 0b1;
  3297. }
  3298. def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
  3299. }
  3300. multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3301. string asm, ValueType Ty, SDPatternOperator storeop> {
  3302. let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
  3303. def roW : LoadStore64RO<sz, V, opc, asm, (outs),
  3304. (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
  3305. [(storeop (Ty regtype:$Rt),
  3306. (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
  3307. ro_Wextend64:$extend))]>,
  3308. Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
  3309. let Inst{13} = 0b0;
  3310. }
  3311. let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
  3312. def roX : LoadStore64RO<sz, V, opc, asm, (outs),
  3313. (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
  3314. [(storeop (Ty regtype:$Rt),
  3315. (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
  3316. ro_Xextend64:$extend))]>,
  3317. Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
  3318. let Inst{13} = 0b1;
  3319. }
  3320. def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
  3321. }
  3322. class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,
  3323. dag outs, list<dag> pat>
  3324. : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
  3325. bits<5> Rt;
  3326. bits<5> Rn;
  3327. bits<5> Rm;
  3328. bits<2> extend;
  3329. let Inst{31-30} = sz;
  3330. let Inst{29-27} = 0b111;
  3331. let Inst{26} = V;
  3332. let Inst{25-24} = 0b00;
  3333. let Inst{23-22} = opc;
  3334. let Inst{21} = 1;
  3335. let Inst{20-16} = Rm;
  3336. let Inst{15} = extend{1}; // sign extend Rm?
  3337. let Inst{14} = 1;
  3338. let Inst{12} = extend{0}; // do shift?
  3339. let Inst{11-10} = 0b10;
  3340. let Inst{9-5} = Rn;
  3341. let Inst{4-0} = Rt;
  3342. }
  3343. multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3344. string asm, ValueType Ty, SDPatternOperator loadop> {
  3345. let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
  3346. def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt),
  3347. (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
  3348. [(set (Ty regtype:$Rt),
  3349. (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
  3350. ro_Wextend128:$extend)))]>,
  3351. Sched<[WriteLDIdx, ReadAdrBase]> {
  3352. let Inst{13} = 0b0;
  3353. }
  3354. let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
  3355. def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt),
  3356. (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
  3357. [(set (Ty regtype:$Rt),
  3358. (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
  3359. ro_Xextend128:$extend)))]>,
  3360. Sched<[WriteLDIdx, ReadAdrBase]> {
  3361. let Inst{13} = 0b1;
  3362. }
  3363. def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
  3364. }
  3365. multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3366. string asm> {
  3367. let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
  3368. def roW : LoadStore128RO<sz, V, opc, asm, (outs),
  3369. (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
  3370. []>,
  3371. Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
  3372. let Inst{13} = 0b0;
  3373. }
  3374. let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
  3375. def roX : LoadStore128RO<sz, V, opc, asm, (outs),
  3376. (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
  3377. []>,
  3378. Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
  3379. let Inst{13} = 0b1;
  3380. }
  3381. def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
  3382. }
  3383. let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
  3384. class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
  3385. string asm, list<dag> pat>
  3386. : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
  3387. Sched<[WriteLD]> {
  3388. bits<5> Rt;
  3389. bits<5> Rn;
  3390. bits<5> Rm;
  3391. bits<2> extend;
  3392. let Inst{31-30} = sz;
  3393. let Inst{29-27} = 0b111;
  3394. let Inst{26} = V;
  3395. let Inst{25-24} = 0b00;
  3396. let Inst{23-22} = opc;
  3397. let Inst{21} = 1;
  3398. let Inst{20-16} = Rm;
  3399. let Inst{15} = extend{1}; // sign extend Rm?
  3400. let Inst{14} = 1;
  3401. let Inst{12} = extend{0}; // do shift?
  3402. let Inst{11-10} = 0b10;
  3403. let Inst{9-5} = Rn;
  3404. let Inst{4-0} = Rt;
  3405. }
  3406. multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
  3407. def roW : BasePrefetchRO<sz, V, opc, (outs),
  3408. (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
  3409. asm, [(AArch64Prefetch imm:$Rt,
  3410. (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
  3411. ro_Wextend64:$extend))]> {
  3412. let Inst{13} = 0b0;
  3413. }
  3414. def roX : BasePrefetchRO<sz, V, opc, (outs),
  3415. (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
  3416. asm, [(AArch64Prefetch imm:$Rt,
  3417. (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
  3418. ro_Xextend64:$extend))]> {
  3419. let Inst{13} = 0b1;
  3420. }
  3421. def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
  3422. (!cast<Instruction>(NAME # "roX") prfop:$Rt,
  3423. GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
  3424. }
  3425. //---
  3426. // Load/store unscaled immediate
  3427. //---
  3428. def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>;
  3429. def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>;
  3430. def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>;
  3431. def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>;
  3432. def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>;
  3433. def gi_am_unscaled8 :
  3434. GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">,
  3435. GIComplexPatternEquiv<am_unscaled8>;
  3436. def gi_am_unscaled16 :
  3437. GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">,
  3438. GIComplexPatternEquiv<am_unscaled16>;
  3439. def gi_am_unscaled32 :
  3440. GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">,
  3441. GIComplexPatternEquiv<am_unscaled32>;
  3442. def gi_am_unscaled64 :
  3443. GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">,
  3444. GIComplexPatternEquiv<am_unscaled64>;
  3445. def gi_am_unscaled128 :
  3446. GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">,
  3447. GIComplexPatternEquiv<am_unscaled128>;
  3448. class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
  3449. string asm, list<dag> pattern>
  3450. : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
  3451. bits<5> Rt;
  3452. bits<5> Rn;
  3453. bits<9> offset;
  3454. let Inst{31-30} = sz;
  3455. let Inst{29-27} = 0b111;
  3456. let Inst{26} = V;
  3457. let Inst{25-24} = 0b00;
  3458. let Inst{23-22} = opc;
  3459. let Inst{21} = 0;
  3460. let Inst{20-12} = offset;
  3461. let Inst{11-10} = 0b00;
  3462. let Inst{9-5} = Rn;
  3463. let Inst{4-0} = Rt;
  3464. let DecoderMethod = "DecodeSignedLdStInstruction";
  3465. }
  3466. // Armv8.4 LDAPR & STLR with Immediate Offset instruction
  3467. multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc,
  3468. DAGOperand regtype > {
  3469. def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt),
  3470. (ins GPR64sp:$Rn, simm9:$offset), asm, []>,
  3471. Sched<[WriteST]> {
  3472. let Inst{29} = 0;
  3473. let Inst{24} = 1;
  3474. }
  3475. def : InstAlias<asm # "\t$Rt, [$Rn]",
  3476. (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
  3477. }
  3478. multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc,
  3479. DAGOperand regtype > {
  3480. def i : BaseLoadStoreUnscale<sz, 0, opc, (outs),
  3481. (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
  3482. asm, []>,
  3483. Sched<[WriteST]> {
  3484. let Inst{29} = 0;
  3485. let Inst{24} = 1;
  3486. }
  3487. def : InstAlias<asm # "\t$Rt, [$Rn]",
  3488. (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
  3489. }
  3490. multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3491. string asm, list<dag> pattern> {
  3492. let AddedComplexity = 1 in // try this before LoadUI
  3493. def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
  3494. (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
  3495. Sched<[WriteLD]>;
  3496. def : InstAlias<asm # "\t$Rt, [$Rn]",
  3497. (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
  3498. }
  3499. multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
  3500. string asm, list<dag> pattern> {
  3501. let AddedComplexity = 1 in // try this before StoreUI
  3502. def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
  3503. (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
  3504. asm, pattern>,
  3505. Sched<[WriteST]>;
  3506. def : InstAlias<asm # "\t$Rt, [$Rn]",
  3507. (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
  3508. }
  3509. multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
  3510. list<dag> pat> {
  3511. let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
  3512. def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
  3513. (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
  3514. asm, pat>,
  3515. Sched<[WriteLD]>;
  3516. def : InstAlias<asm # "\t$Rt, [$Rn]",
  3517. (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
  3518. }
  3519. //---
  3520. // Load/store unscaled immediate, unprivileged
  3521. //---
  3522. class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
  3523. dag oops, dag iops, string asm>
  3524. : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
  3525. bits<5> Rt;
  3526. bits<5> Rn;
  3527. bits<9> offset;
  3528. let Inst{31-30} = sz;
  3529. let Inst{29-27} = 0b111;
  3530. let Inst{26} = V;
  3531. let Inst{25-24} = 0b00;
  3532. let Inst{23-22} = opc;
  3533. let Inst{21} = 0;
  3534. let Inst{20-12} = offset;
  3535. let Inst{11-10} = 0b10;
  3536. let Inst{9-5} = Rn;
  3537. let Inst{4-0} = Rt;
  3538. let DecoderMethod = "DecodeSignedLdStInstruction";
  3539. }
  3540. multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
  3541. RegisterClass regtype, string asm> {
  3542. let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
  3543. def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
  3544. (ins GPR64sp:$Rn, simm9:$offset), asm>,
  3545. Sched<[WriteLD]>;
  3546. def : InstAlias<asm # "\t$Rt, [$Rn]",
  3547. (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
  3548. }
  3549. multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
  3550. RegisterClass regtype, string asm> {
  3551. let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
  3552. def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
  3553. (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
  3554. asm>,
  3555. Sched<[WriteST]>;
  3556. def : InstAlias<asm # "\t$Rt, [$Rn]",
  3557. (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
  3558. }
  3559. //---
  3560. // Load/store pre-indexed
  3561. //---
  3562. class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
  3563. string asm, string cstr, list<dag> pat>
  3564. : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
  3565. bits<5> Rt;
  3566. bits<5> Rn;
  3567. bits<9> offset;
  3568. let Inst{31-30} = sz;
  3569. let Inst{29-27} = 0b111;
  3570. let Inst{26} = V;
  3571. let Inst{25-24} = 0;
  3572. let Inst{23-22} = opc;
  3573. let Inst{21} = 0;
  3574. let Inst{20-12} = offset;
  3575. let Inst{11-10} = 0b11;
  3576. let Inst{9-5} = Rn;
  3577. let Inst{4-0} = Rt;
  3578. let DecoderMethod = "DecodeSignedLdStInstruction";
  3579. }
  3580. let hasSideEffects = 0 in {
  3581. let mayStore = 0, mayLoad = 1 in
  3582. class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
  3583. string asm>
  3584. : BaseLoadStorePreIdx<sz, V, opc,
  3585. (outs GPR64sp:$wback, regtype:$Rt),
  3586. (ins GPR64sp:$Rn, simm9:$offset), asm,
  3587. "$Rn = $wback,@earlyclobber $wback", []>,
  3588. Sched<[WriteAdr, WriteLD]>;
  3589. let mayStore = 1, mayLoad = 0 in
  3590. class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
  3591. string asm, SDPatternOperator storeop, ValueType Ty>
  3592. : BaseLoadStorePreIdx<sz, V, opc,
  3593. (outs GPR64sp:$wback),
  3594. (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
  3595. asm, "$Rn = $wback,@earlyclobber $wback",
  3596. [(set GPR64sp:$wback,
  3597. (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
  3598. Sched<[WriteAdr, WriteST]>;
  3599. } // hasSideEffects = 0
  3600. //---
  3601. // Load/store post-indexed
  3602. //---
  3603. class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
  3604. string asm, string cstr, list<dag> pat>
  3605. : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
  3606. bits<5> Rt;
  3607. bits<5> Rn;
  3608. bits<9> offset;
  3609. let Inst{31-30} = sz;
  3610. let Inst{29-27} = 0b111;
  3611. let Inst{26} = V;
  3612. let Inst{25-24} = 0b00;
  3613. let Inst{23-22} = opc;
  3614. let Inst{21} = 0b0;
  3615. let Inst{20-12} = offset;
  3616. let Inst{11-10} = 0b01;
  3617. let Inst{9-5} = Rn;
  3618. let Inst{4-0} = Rt;
  3619. let DecoderMethod = "DecodeSignedLdStInstruction";
  3620. }
  3621. let hasSideEffects = 0 in {
  3622. let mayStore = 0, mayLoad = 1 in
  3623. class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
  3624. string asm>
  3625. : BaseLoadStorePostIdx<sz, V, opc,
  3626. (outs GPR64sp:$wback, regtype:$Rt),
  3627. (ins GPR64sp:$Rn, simm9:$offset),
  3628. asm, "$Rn = $wback,@earlyclobber $wback", []>,
  3629. Sched<[WriteAdr, WriteLD]>;
  3630. let mayStore = 1, mayLoad = 0 in
  3631. class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
  3632. string asm, SDPatternOperator storeop, ValueType Ty>
  3633. : BaseLoadStorePostIdx<sz, V, opc,
  3634. (outs GPR64sp:$wback),
  3635. (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
  3636. asm, "$Rn = $wback,@earlyclobber $wback",
  3637. [(set GPR64sp:$wback,
  3638. (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
  3639. Sched<[WriteAdr, WriteST]>;
  3640. } // hasSideEffects = 0
  3641. //---
  3642. // Load/store pair
  3643. //---
  3644. // (indexed, offset)
  3645. class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
  3646. string asm>
  3647. : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
  3648. bits<5> Rt;
  3649. bits<5> Rt2;
  3650. bits<5> Rn;
  3651. bits<7> offset;
  3652. let Inst{31-30} = opc;
  3653. let Inst{29-27} = 0b101;
  3654. let Inst{26} = V;
  3655. let Inst{25-23} = 0b010;
  3656. let Inst{22} = L;
  3657. let Inst{21-15} = offset;
  3658. let Inst{14-10} = Rt2;
  3659. let Inst{9-5} = Rn;
  3660. let Inst{4-0} = Rt;
  3661. let DecoderMethod = "DecodePairLdStInstruction";
  3662. }
  3663. multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype,
  3664. Operand indextype, string asm> {
  3665. let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
  3666. def i : BaseLoadStorePairOffset<opc, V, 1,
  3667. (outs regtype:$Rt, regtype:$Rt2),
  3668. (ins GPR64sp:$Rn, indextype:$offset), asm>,
  3669. Sched<[WriteLD, WriteLDHi]>;
  3670. def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
  3671. (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
  3672. GPR64sp:$Rn, 0)>;
  3673. }
  3674. multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype,
  3675. Operand indextype, string asm> {
  3676. let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
  3677. def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
  3678. (ins regtype:$Rt, regtype:$Rt2,
  3679. GPR64sp:$Rn, indextype:$offset),
  3680. asm>,
  3681. Sched<[WriteSTP]>;
  3682. def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
  3683. (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
  3684. GPR64sp:$Rn, 0)>;
  3685. }
  3686. // (pre-indexed)
  3687. class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
  3688. string asm>
  3689. : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
  3690. bits<5> Rt;
  3691. bits<5> Rt2;
  3692. bits<5> Rn;
  3693. bits<7> offset;
  3694. let Inst{31-30} = opc;
  3695. let Inst{29-27} = 0b101;
  3696. let Inst{26} = V;
  3697. let Inst{25-23} = 0b011;
  3698. let Inst{22} = L;
  3699. let Inst{21-15} = offset;
  3700. let Inst{14-10} = Rt2;
  3701. let Inst{9-5} = Rn;
  3702. let Inst{4-0} = Rt;
  3703. let DecoderMethod = "DecodePairLdStInstruction";
  3704. }
  3705. let hasSideEffects = 0 in {
  3706. let mayStore = 0, mayLoad = 1 in
  3707. class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
  3708. Operand indextype, string asm>
  3709. : BaseLoadStorePairPreIdx<opc, V, 1,
  3710. (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
  3711. (ins GPR64sp:$Rn, indextype:$offset), asm>,
  3712. Sched<[WriteAdr, WriteLD, WriteLDHi]>;
  3713. let mayStore = 1, mayLoad = 0 in
  3714. class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
  3715. Operand indextype, string asm>
  3716. : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
  3717. (ins regtype:$Rt, regtype:$Rt2,
  3718. GPR64sp:$Rn, indextype:$offset),
  3719. asm>,
  3720. Sched<[WriteAdr, WriteSTP]>;
  3721. } // hasSideEffects = 0
  3722. // (post-indexed)
  3723. class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
  3724. string asm>
  3725. : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
  3726. bits<5> Rt;
  3727. bits<5> Rt2;
  3728. bits<5> Rn;
  3729. bits<7> offset;
  3730. let Inst{31-30} = opc;
  3731. let Inst{29-27} = 0b101;
  3732. let Inst{26} = V;
  3733. let Inst{25-23} = 0b001;
  3734. let Inst{22} = L;
  3735. let Inst{21-15} = offset;
  3736. let Inst{14-10} = Rt2;
  3737. let Inst{9-5} = Rn;
  3738. let Inst{4-0} = Rt;
  3739. let DecoderMethod = "DecodePairLdStInstruction";
  3740. }
  3741. let hasSideEffects = 0 in {
  3742. let mayStore = 0, mayLoad = 1 in
  3743. class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
  3744. Operand idxtype, string asm>
  3745. : BaseLoadStorePairPostIdx<opc, V, 1,
  3746. (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
  3747. (ins GPR64sp:$Rn, idxtype:$offset), asm>,
  3748. Sched<[WriteAdr, WriteLD, WriteLDHi]>;
  3749. let mayStore = 1, mayLoad = 0 in
  3750. class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
  3751. Operand idxtype, string asm>
  3752. : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
  3753. (ins regtype:$Rt, regtype:$Rt2,
  3754. GPR64sp:$Rn, idxtype:$offset),
  3755. asm>,
  3756. Sched<[WriteAdr, WriteSTP]>;
  3757. } // hasSideEffects = 0
  3758. // (no-allocate)
  3759. class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
  3760. string asm>
  3761. : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
  3762. bits<5> Rt;
  3763. bits<5> Rt2;
  3764. bits<5> Rn;
  3765. bits<7> offset;
  3766. let Inst{31-30} = opc;
  3767. let Inst{29-27} = 0b101;
  3768. let Inst{26} = V;
  3769. let Inst{25-23} = 0b000;
  3770. let Inst{22} = L;
  3771. let Inst{21-15} = offset;
  3772. let Inst{14-10} = Rt2;
  3773. let Inst{9-5} = Rn;
  3774. let Inst{4-0} = Rt;
  3775. let DecoderMethod = "DecodePairLdStInstruction";
  3776. }
  3777. multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype,
  3778. Operand indextype, string asm> {
  3779. let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
  3780. def i : BaseLoadStorePairNoAlloc<opc, V, 1,
  3781. (outs regtype:$Rt, regtype:$Rt2),
  3782. (ins GPR64sp:$Rn, indextype:$offset), asm>,
  3783. Sched<[WriteLD, WriteLDHi]>;
  3784. def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
  3785. (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
  3786. GPR64sp:$Rn, 0)>;
  3787. }
  3788. multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype,
  3789. Operand indextype, string asm> {
  3790. let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
  3791. def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
  3792. (ins regtype:$Rt, regtype:$Rt2,
  3793. GPR64sp:$Rn, indextype:$offset),
  3794. asm>,
  3795. Sched<[WriteSTP]>;
  3796. def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
  3797. (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
  3798. GPR64sp:$Rn, 0)>;
  3799. }
  3800. //---
  3801. // Load/store exclusive
  3802. //---
  3803. // True exclusive operations write to and/or read from the system's exclusive
  3804. // monitors, which as far as a compiler is concerned can be modelled as a
  3805. // random shared memory address. Hence LoadExclusive mayStore.
  3806. //
  3807. // Since these instructions have the undefined register bits set to 1 in
  3808. // their canonical form, we need a post encoder method to set those bits
  3809. // to 1 when encoding these instructions. We do this using the
  3810. // fixLoadStoreExclusive function. This function has template parameters:
  3811. //
  3812. // fixLoadStoreExclusive<int hasRs, int hasRt2>
  3813. //
  3814. // hasRs indicates that the instruction uses the Rs field, so we won't set
  3815. // it to 1 (and the same for Rt2). We don't need template parameters for
  3816. // the other register fields since Rt and Rn are always used.
  3817. //
  3818. let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
  3819. class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
  3820. dag oops, dag iops, string asm, string operands>
  3821. : I<oops, iops, asm, operands, "", []> {
  3822. let Inst{31-30} = sz;
  3823. let Inst{29-24} = 0b001000;
  3824. let Inst{23} = o2;
  3825. let Inst{22} = L;
  3826. let Inst{21} = o1;
  3827. let Inst{15} = o0;
  3828. let DecoderMethod = "DecodeExclusiveLdStInstruction";
  3829. }
  3830. // Neither Rs nor Rt2 operands.
  3831. class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
  3832. dag oops, dag iops, string asm, string operands>
  3833. : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
  3834. bits<5> Rt;
  3835. bits<5> Rn;
  3836. let Inst{20-16} = 0b11111;
  3837. let Unpredictable{20-16} = 0b11111;
  3838. let Inst{14-10} = 0b11111;
  3839. let Unpredictable{14-10} = 0b11111;
  3840. let Inst{9-5} = Rn;
  3841. let Inst{4-0} = Rt;
  3842. let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
  3843. }
  3844. // Simple load acquires don't set the exclusive monitor
  3845. let mayLoad = 1, mayStore = 0 in
  3846. class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
  3847. RegisterClass regtype, string asm>
  3848. : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
  3849. (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
  3850. Sched<[WriteLD]>;
  3851. class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
  3852. RegisterClass regtype, string asm>
  3853. : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
  3854. (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
  3855. Sched<[WriteLD]>;
  3856. class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
  3857. RegisterClass regtype, string asm>
  3858. : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
  3859. (outs regtype:$Rt, regtype:$Rt2),
  3860. (ins GPR64sp0:$Rn), asm,
  3861. "\t$Rt, $Rt2, [$Rn]">,
  3862. Sched<[WriteLD, WriteLDHi]> {
  3863. bits<5> Rt;
  3864. bits<5> Rt2;
  3865. bits<5> Rn;
  3866. let Inst{14-10} = Rt2;
  3867. let Inst{9-5} = Rn;
  3868. let Inst{4-0} = Rt;
  3869. let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
  3870. }
  3871. // Simple store release operations do not check the exclusive monitor.
  3872. let mayLoad = 0, mayStore = 1 in
  3873. class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
  3874. RegisterClass regtype, string asm>
  3875. : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
  3876. (ins regtype:$Rt, GPR64sp0:$Rn),
  3877. asm, "\t$Rt, [$Rn]">,
  3878. Sched<[WriteST]>;
  3879. let mayLoad = 1, mayStore = 1 in
  3880. class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
  3881. RegisterClass regtype, string asm>
  3882. : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
  3883. (ins regtype:$Rt, GPR64sp0:$Rn),
  3884. asm, "\t$Ws, $Rt, [$Rn]">,
  3885. Sched<[WriteSTX]> {
  3886. bits<5> Ws;
  3887. bits<5> Rt;
  3888. bits<5> Rn;
  3889. let Inst{20-16} = Ws;
  3890. let Inst{9-5} = Rn;
  3891. let Inst{4-0} = Rt;
  3892. let Constraints = "@earlyclobber $Ws";
  3893. let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
  3894. }
  3895. class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
  3896. RegisterClass regtype, string asm>
  3897. : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
  3898. (outs GPR32:$Ws),
  3899. (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
  3900. asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
  3901. Sched<[WriteSTX]> {
  3902. bits<5> Ws;
  3903. bits<5> Rt;
  3904. bits<5> Rt2;
  3905. bits<5> Rn;
  3906. let Inst{20-16} = Ws;
  3907. let Inst{14-10} = Rt2;
  3908. let Inst{9-5} = Rn;
  3909. let Inst{4-0} = Rt;
  3910. let Constraints = "@earlyclobber $Ws";
  3911. }
  3912. // Armv8.5-A Memory Tagging Extension
  3913. class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn,
  3914. string asm_opnds, string cstr, dag oops, dag iops>
  3915. : I<oops, iops, asm_insn, asm_opnds, cstr, []>,
  3916. Sched<[]> {
  3917. bits<5> Rn;
  3918. let Inst{31-24} = 0b11011001;
  3919. let Inst{23-22} = opc1;
  3920. let Inst{21} = 1;
  3921. // Inst{20-12} defined by subclass
  3922. let Inst{11-10} = opc2;
  3923. let Inst{9-5} = Rn;
  3924. // Inst{4-0} defined by subclass
  3925. }
  3926. class MemTagVector<bit Load, string asm_insn, string asm_opnds,
  3927. dag oops, dag iops>
  3928. : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds,
  3929. "", oops, iops> {
  3930. bits<5> Rt;
  3931. let Inst{20-12} = 0b000000000;
  3932. let Inst{4-0} = Rt;
  3933. let mayLoad = Load;
  3934. }
  3935. class MemTagLoad<string asm_insn, string asm_opnds>
  3936. : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback",
  3937. (outs GPR64:$wback),
  3938. (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> {
  3939. bits<5> Rt;
  3940. bits<9> offset;
  3941. let Inst{20-12} = offset;
  3942. let Inst{4-0} = Rt;
  3943. let mayLoad = 1;
  3944. }
  3945. class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn,
  3946. string asm_opnds, string cstr, dag oops, dag iops>
  3947. : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> {
  3948. bits<5> Rt;
  3949. bits<9> offset;
  3950. let Inst{20-12} = offset;
  3951. let Inst{4-0} = Rt;
  3952. let mayStore = 1;
  3953. }
  3954. multiclass MemTagStore<bits<2> opc1, string insn> {
  3955. def Offset :
  3956. BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "",
  3957. (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
  3958. def PreIndex :
  3959. BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!",
  3960. "$Rn = $wback",
  3961. (outs GPR64sp:$wback),
  3962. (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
  3963. def PostIndex :
  3964. BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset",
  3965. "$Rn = $wback",
  3966. (outs GPR64sp:$wback),
  3967. (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;
  3968. def : InstAlias<insn # "\t$Rt, [$Rn]",
  3969. (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>;
  3970. }
  3971. //---
  3972. // Exception generation
  3973. //---
  3974. let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
  3975. class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
  3976. : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", []>,
  3977. Sched<[WriteSys]> {
  3978. bits<16> imm;
  3979. let Inst{31-24} = 0b11010100;
  3980. let Inst{23-21} = op1;
  3981. let Inst{20-5} = imm;
  3982. let Inst{4-2} = 0b000;
  3983. let Inst{1-0} = ll;
  3984. }
  3985. //---
  3986. // UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm.
  3987. //--
  3988. let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in {
  3989. class UDFType<bits<16> opc, string asm>
  3990. : I<(outs), (ins uimm16:$imm),
  3991. asm, "\t$imm", "", []>,
  3992. Sched<[]> {
  3993. bits<16> imm;
  3994. let Inst{31-16} = opc;
  3995. let Inst{15-0} = imm;
  3996. }
  3997. }
  3998. let Predicates = [HasFPARMv8] in {
  3999. //---
  4000. // Floating point to integer conversion
  4001. //---
  4002. class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
  4003. RegisterClass srcType, RegisterClass dstType,
  4004. string asm, list<dag> pattern>
  4005. : I<(outs dstType:$Rd), (ins srcType:$Rn),
  4006. asm, "\t$Rd, $Rn", "", pattern>,
  4007. Sched<[WriteFCvt]> {
  4008. bits<5> Rd;
  4009. bits<5> Rn;
  4010. let Inst{30-29} = 0b00;
  4011. let Inst{28-24} = 0b11110;
  4012. let Inst{23-22} = type;
  4013. let Inst{21} = 1;
  4014. let Inst{20-19} = rmode;
  4015. let Inst{18-16} = opcode;
  4016. let Inst{15-10} = 0;
  4017. let Inst{9-5} = Rn;
  4018. let Inst{4-0} = Rd;
  4019. }
  4020. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4021. class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
  4022. RegisterClass srcType, RegisterClass dstType,
  4023. Operand immType, string asm, list<dag> pattern>
  4024. : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
  4025. asm, "\t$Rd, $Rn, $scale", "", pattern>,
  4026. Sched<[WriteFCvt]> {
  4027. bits<5> Rd;
  4028. bits<5> Rn;
  4029. bits<6> scale;
  4030. let Inst{30-29} = 0b00;
  4031. let Inst{28-24} = 0b11110;
  4032. let Inst{23-22} = type;
  4033. let Inst{21} = 0;
  4034. let Inst{20-19} = rmode;
  4035. let Inst{18-16} = opcode;
  4036. let Inst{15-10} = scale;
  4037. let Inst{9-5} = Rn;
  4038. let Inst{4-0} = Rd;
  4039. }
  4040. multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
  4041. SDPatternOperator OpN> {
  4042. // Unscaled half-precision to 32-bit
  4043. def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
  4044. [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> {
  4045. let Inst{31} = 0; // 32-bit GPR flag
  4046. let Predicates = [HasFullFP16];
  4047. }
  4048. // Unscaled half-precision to 64-bit
  4049. def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
  4050. [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> {
  4051. let Inst{31} = 1; // 64-bit GPR flag
  4052. let Predicates = [HasFullFP16];
  4053. }
  4054. // Unscaled single-precision to 32-bit
  4055. def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
  4056. [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
  4057. let Inst{31} = 0; // 32-bit GPR flag
  4058. }
  4059. // Unscaled single-precision to 64-bit
  4060. def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
  4061. [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
  4062. let Inst{31} = 1; // 64-bit GPR flag
  4063. }
  4064. // Unscaled double-precision to 32-bit
  4065. def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
  4066. [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
  4067. let Inst{31} = 0; // 32-bit GPR flag
  4068. }
  4069. // Unscaled double-precision to 64-bit
  4070. def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
  4071. [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
  4072. let Inst{31} = 1; // 64-bit GPR flag
  4073. }
  4074. }
  4075. multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
  4076. SDPatternOperator OpN> {
  4077. // Scaled half-precision to 32-bit
  4078. def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
  4079. fixedpoint_f16_i32, asm,
  4080. [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn),
  4081. fixedpoint_f16_i32:$scale)))]> {
  4082. let Inst{31} = 0; // 32-bit GPR flag
  4083. let scale{5} = 1;
  4084. let Predicates = [HasFullFP16];
  4085. }
  4086. // Scaled half-precision to 64-bit
  4087. def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
  4088. fixedpoint_f16_i64, asm,
  4089. [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn),
  4090. fixedpoint_f16_i64:$scale)))]> {
  4091. let Inst{31} = 1; // 64-bit GPR flag
  4092. let Predicates = [HasFullFP16];
  4093. }
  4094. // Scaled single-precision to 32-bit
  4095. def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
  4096. fixedpoint_f32_i32, asm,
  4097. [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
  4098. fixedpoint_f32_i32:$scale)))]> {
  4099. let Inst{31} = 0; // 32-bit GPR flag
  4100. let scale{5} = 1;
  4101. }
  4102. // Scaled single-precision to 64-bit
  4103. def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
  4104. fixedpoint_f32_i64, asm,
  4105. [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
  4106. fixedpoint_f32_i64:$scale)))]> {
  4107. let Inst{31} = 1; // 64-bit GPR flag
  4108. }
  4109. // Scaled double-precision to 32-bit
  4110. def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
  4111. fixedpoint_f64_i32, asm,
  4112. [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
  4113. fixedpoint_f64_i32:$scale)))]> {
  4114. let Inst{31} = 0; // 32-bit GPR flag
  4115. let scale{5} = 1;
  4116. }
  4117. // Scaled double-precision to 64-bit
  4118. def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
  4119. fixedpoint_f64_i64, asm,
  4120. [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
  4121. fixedpoint_f64_i64:$scale)))]> {
  4122. let Inst{31} = 1; // 64-bit GPR flag
  4123. }
  4124. }
  4125. //---
  4126. // Integer to floating point conversion
  4127. //---
  4128. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
  4129. class BaseIntegerToFP<bit isUnsigned,
  4130. RegisterClass srcType, RegisterClass dstType,
  4131. Operand immType, string asm, list<dag> pattern>
  4132. : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
  4133. asm, "\t$Rd, $Rn, $scale", "", pattern>,
  4134. Sched<[WriteFCvt]> {
  4135. bits<5> Rd;
  4136. bits<5> Rn;
  4137. bits<6> scale;
  4138. let Inst{30-24} = 0b0011110;
  4139. let Inst{21-17} = 0b00001;
  4140. let Inst{16} = isUnsigned;
  4141. let Inst{15-10} = scale;
  4142. let Inst{9-5} = Rn;
  4143. let Inst{4-0} = Rd;
  4144. }
  4145. class BaseIntegerToFPUnscaled<bit isUnsigned,
  4146. RegisterClass srcType, RegisterClass dstType,
  4147. ValueType dvt, string asm, SDPatternOperator node>
  4148. : I<(outs dstType:$Rd), (ins srcType:$Rn),
  4149. asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
  4150. Sched<[WriteFCvt]> {
  4151. bits<5> Rd;
  4152. bits<5> Rn;
  4153. bits<6> scale;
  4154. let Inst{30-24} = 0b0011110;
  4155. let Inst{21-17} = 0b10001;
  4156. let Inst{16} = isUnsigned;
  4157. let Inst{15-10} = 0b000000;
  4158. let Inst{9-5} = Rn;
  4159. let Inst{4-0} = Rd;
  4160. }
  4161. multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> {
  4162. // Unscaled
  4163. def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
  4164. let Inst{31} = 0; // 32-bit GPR flag
  4165. let Inst{23-22} = 0b11; // 16-bit FPR flag
  4166. let Predicates = [HasFullFP16];
  4167. }
  4168. def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
  4169. let Inst{31} = 0; // 32-bit GPR flag
  4170. let Inst{23-22} = 0b00; // 32-bit FPR flag
  4171. }
  4172. def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
  4173. let Inst{31} = 0; // 32-bit GPR flag
  4174. let Inst{23-22} = 0b01; // 64-bit FPR flag
  4175. }
  4176. def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
  4177. let Inst{31} = 1; // 64-bit GPR flag
  4178. let Inst{23-22} = 0b11; // 16-bit FPR flag
  4179. let Predicates = [HasFullFP16];
  4180. }
  4181. def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
  4182. let Inst{31} = 1; // 64-bit GPR flag
  4183. let Inst{23-22} = 0b00; // 32-bit FPR flag
  4184. }
  4185. def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
  4186. let Inst{31} = 1; // 64-bit GPR flag
  4187. let Inst{23-22} = 0b01; // 64-bit FPR flag
  4188. }
  4189. // Scaled
  4190. def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
  4191. [(set (f16 FPR16:$Rd),
  4192. (fdiv (node GPR32:$Rn),
  4193. fixedpoint_f16_i32:$scale))]> {
  4194. let Inst{31} = 0; // 32-bit GPR flag
  4195. let Inst{23-22} = 0b11; // 16-bit FPR flag
  4196. let scale{5} = 1;
  4197. let Predicates = [HasFullFP16];
  4198. }
  4199. def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
  4200. [(set FPR32:$Rd,
  4201. (fdiv (node GPR32:$Rn),
  4202. fixedpoint_f32_i32:$scale))]> {
  4203. let Inst{31} = 0; // 32-bit GPR flag
  4204. let Inst{23-22} = 0b00; // 32-bit FPR flag
  4205. let scale{5} = 1;
  4206. }
  4207. def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
  4208. [(set FPR64:$Rd,
  4209. (fdiv (node GPR32:$Rn),
  4210. fixedpoint_f64_i32:$scale))]> {
  4211. let Inst{31} = 0; // 32-bit GPR flag
  4212. let Inst{23-22} = 0b01; // 64-bit FPR flag
  4213. let scale{5} = 1;
  4214. }
  4215. def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
  4216. [(set (f16 FPR16:$Rd),
  4217. (fdiv (node GPR64:$Rn),
  4218. fixedpoint_f16_i64:$scale))]> {
  4219. let Inst{31} = 1; // 64-bit GPR flag
  4220. let Inst{23-22} = 0b11; // 16-bit FPR flag
  4221. let Predicates = [HasFullFP16];
  4222. }
  4223. def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
  4224. [(set FPR32:$Rd,
  4225. (fdiv (node GPR64:$Rn),
  4226. fixedpoint_f32_i64:$scale))]> {
  4227. let Inst{31} = 1; // 64-bit GPR flag
  4228. let Inst{23-22} = 0b00; // 32-bit FPR flag
  4229. }
  4230. def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
  4231. [(set FPR64:$Rd,
  4232. (fdiv (node GPR64:$Rn),
  4233. fixedpoint_f64_i64:$scale))]> {
  4234. let Inst{31} = 1; // 64-bit GPR flag
  4235. let Inst{23-22} = 0b01; // 64-bit FPR flag
  4236. }
  4237. }
  4238. //---
  4239. // Unscaled integer <-> floating point conversion (i.e. FMOV)
  4240. //---
  4241. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4242. class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
  4243. RegisterClass srcType, RegisterClass dstType,
  4244. string asm>
  4245. : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
  4246. // We use COPY_TO_REGCLASS for these bitconvert operations.
  4247. // copyPhysReg() expands the resultant COPY instructions after
  4248. // regalloc is done. This gives greater freedom for the allocator
  4249. // and related passes (coalescing, copy propagation, et. al.) to
  4250. // be more effective.
  4251. [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
  4252. Sched<[WriteFCopy]> {
  4253. bits<5> Rd;
  4254. bits<5> Rn;
  4255. let Inst{30-24} = 0b0011110;
  4256. let Inst{21} = 1;
  4257. let Inst{20-19} = rmode;
  4258. let Inst{18-16} = opcode;
  4259. let Inst{15-10} = 0b000000;
  4260. let Inst{9-5} = Rn;
  4261. let Inst{4-0} = Rd;
  4262. }
  4263. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4264. class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
  4265. RegisterClass srcType, RegisterOperand dstType, string asm,
  4266. string kind>
  4267. : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
  4268. "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
  4269. Sched<[WriteFCopy]> {
  4270. bits<5> Rd;
  4271. bits<5> Rn;
  4272. let Inst{30-23} = 0b00111101;
  4273. let Inst{21} = 1;
  4274. let Inst{20-19} = rmode;
  4275. let Inst{18-16} = opcode;
  4276. let Inst{15-10} = 0b000000;
  4277. let Inst{9-5} = Rn;
  4278. let Inst{4-0} = Rd;
  4279. let DecoderMethod = "DecodeFMOVLaneInstruction";
  4280. }
  4281. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4282. class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
  4283. RegisterOperand srcType, RegisterClass dstType, string asm,
  4284. string kind>
  4285. : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
  4286. "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
  4287. Sched<[WriteFCopy]> {
  4288. bits<5> Rd;
  4289. bits<5> Rn;
  4290. let Inst{30-23} = 0b00111101;
  4291. let Inst{21} = 1;
  4292. let Inst{20-19} = rmode;
  4293. let Inst{18-16} = opcode;
  4294. let Inst{15-10} = 0b000000;
  4295. let Inst{9-5} = Rn;
  4296. let Inst{4-0} = Rd;
  4297. let DecoderMethod = "DecodeFMOVLaneInstruction";
  4298. }
  4299. multiclass UnscaledConversion<string asm> {
  4300. def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
  4301. let Inst{31} = 0; // 32-bit GPR flag
  4302. let Inst{23-22} = 0b11; // 16-bit FPR flag
  4303. let Predicates = [HasFullFP16];
  4304. }
  4305. def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
  4306. let Inst{31} = 1; // 64-bit GPR flag
  4307. let Inst{23-22} = 0b11; // 16-bit FPR flag
  4308. let Predicates = [HasFullFP16];
  4309. }
  4310. def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
  4311. let Inst{31} = 0; // 32-bit GPR flag
  4312. let Inst{23-22} = 0b00; // 32-bit FPR flag
  4313. }
  4314. def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
  4315. let Inst{31} = 1; // 64-bit GPR flag
  4316. let Inst{23-22} = 0b01; // 64-bit FPR flag
  4317. }
  4318. def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
  4319. let Inst{31} = 0; // 32-bit GPR flag
  4320. let Inst{23-22} = 0b11; // 16-bit FPR flag
  4321. let Predicates = [HasFullFP16];
  4322. }
  4323. def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
  4324. let Inst{31} = 1; // 64-bit GPR flag
  4325. let Inst{23-22} = 0b11; // 16-bit FPR flag
  4326. let Predicates = [HasFullFP16];
  4327. }
  4328. def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
  4329. let Inst{31} = 0; // 32-bit GPR flag
  4330. let Inst{23-22} = 0b00; // 32-bit FPR flag
  4331. }
  4332. def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
  4333. let Inst{31} = 1; // 64-bit GPR flag
  4334. let Inst{23-22} = 0b01; // 64-bit FPR flag
  4335. }
  4336. def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
  4337. asm, ".d"> {
  4338. let Inst{31} = 1;
  4339. let Inst{22} = 0;
  4340. }
  4341. def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
  4342. asm, ".d"> {
  4343. let Inst{31} = 1;
  4344. let Inst{22} = 0;
  4345. }
  4346. }
  4347. //---
  4348. // Floating point conversion
  4349. //---
  4350. class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
  4351. RegisterClass srcType, string asm, list<dag> pattern>
  4352. : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
  4353. Sched<[WriteFCvt]> {
  4354. bits<5> Rd;
  4355. bits<5> Rn;
  4356. let Inst{31-24} = 0b00011110;
  4357. let Inst{23-22} = type;
  4358. let Inst{21-17} = 0b10001;
  4359. let Inst{16-15} = opcode;
  4360. let Inst{14-10} = 0b10000;
  4361. let Inst{9-5} = Rn;
  4362. let Inst{4-0} = Rd;
  4363. }
  4364. multiclass FPConversion<string asm> {
  4365. // Double-precision to Half-precision
  4366. def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
  4367. [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>;
  4368. // Double-precision to Single-precision
  4369. def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
  4370. [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>;
  4371. // Half-precision to Double-precision
  4372. def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
  4373. [(set FPR64:$Rd, (fpextend (f16 FPR16:$Rn)))]>;
  4374. // Half-precision to Single-precision
  4375. def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
  4376. [(set FPR32:$Rd, (fpextend (f16 FPR16:$Rn)))]>;
  4377. // Single-precision to Double-precision
  4378. def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
  4379. [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>;
  4380. // Single-precision to Half-precision
  4381. def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
  4382. [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>;
  4383. }
  4384. //---
  4385. // Single operand floating point data processing
  4386. //---
  4387. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4388. class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype,
  4389. ValueType vt, string asm, SDPatternOperator node>
  4390. : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
  4391. [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
  4392. Sched<[WriteF]> {
  4393. bits<5> Rd;
  4394. bits<5> Rn;
  4395. let Inst{31-24} = 0b00011110;
  4396. let Inst{21} = 0b1;
  4397. let Inst{20-15} = opcode;
  4398. let Inst{14-10} = 0b10000;
  4399. let Inst{9-5} = Rn;
  4400. let Inst{4-0} = Rd;
  4401. }
  4402. multiclass SingleOperandFPData<bits<4> opcode, string asm,
  4403. SDPatternOperator node = null_frag> {
  4404. def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> {
  4405. let Inst{23-22} = 0b11; // 16-bit size flag
  4406. let Predicates = [HasFullFP16];
  4407. }
  4408. def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> {
  4409. let Inst{23-22} = 0b00; // 32-bit size flag
  4410. }
  4411. def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> {
  4412. let Inst{23-22} = 0b01; // 64-bit size flag
  4413. }
  4414. }
  4415. multiclass SingleOperandFPNo16<bits<6> opcode, string asm,
  4416. SDPatternOperator node = null_frag>{
  4417. def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
  4418. let Inst{23-22} = 0b00; // 32-bit registers
  4419. }
  4420. def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
  4421. let Inst{23-22} = 0b01; // 64-bit registers
  4422. }
  4423. }
  4424. // FRInt[32|64][Z|N] instructions
  4425. multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> :
  4426. SingleOperandFPNo16<{0b0100,opcode}, asm, node>;
  4427. //---
  4428. // Two operand floating point data processing
  4429. //---
  4430. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4431. class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
  4432. string asm, list<dag> pat>
  4433. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
  4434. asm, "\t$Rd, $Rn, $Rm", "", pat>,
  4435. Sched<[WriteF]> {
  4436. bits<5> Rd;
  4437. bits<5> Rn;
  4438. bits<5> Rm;
  4439. let Inst{31-24} = 0b00011110;
  4440. let Inst{21} = 1;
  4441. let Inst{20-16} = Rm;
  4442. let Inst{15-12} = opcode;
  4443. let Inst{11-10} = 0b10;
  4444. let Inst{9-5} = Rn;
  4445. let Inst{4-0} = Rd;
  4446. }
  4447. multiclass TwoOperandFPData<bits<4> opcode, string asm,
  4448. SDPatternOperator node = null_frag> {
  4449. def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
  4450. [(set (f16 FPR16:$Rd),
  4451. (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
  4452. let Inst{23-22} = 0b11; // 16-bit size flag
  4453. let Predicates = [HasFullFP16];
  4454. }
  4455. def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
  4456. [(set (f32 FPR32:$Rd),
  4457. (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
  4458. let Inst{23-22} = 0b00; // 32-bit size flag
  4459. }
  4460. def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
  4461. [(set (f64 FPR64:$Rd),
  4462. (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
  4463. let Inst{23-22} = 0b01; // 64-bit size flag
  4464. }
  4465. }
  4466. multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
  4467. def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
  4468. [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> {
  4469. let Inst{23-22} = 0b11; // 16-bit size flag
  4470. let Predicates = [HasFullFP16];
  4471. }
  4472. def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
  4473. [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
  4474. let Inst{23-22} = 0b00; // 32-bit size flag
  4475. }
  4476. def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
  4477. [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
  4478. let Inst{23-22} = 0b01; // 64-bit size flag
  4479. }
  4480. }
  4481. //---
  4482. // Three operand floating point data processing
  4483. //---
  4484. class BaseThreeOperandFPData<bit isNegated, bit isSub,
  4485. RegisterClass regtype, string asm, list<dag> pat>
  4486. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
  4487. asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
  4488. Sched<[WriteFMul]> {
  4489. bits<5> Rd;
  4490. bits<5> Rn;
  4491. bits<5> Rm;
  4492. bits<5> Ra;
  4493. let Inst{31-24} = 0b00011111;
  4494. let Inst{21} = isNegated;
  4495. let Inst{20-16} = Rm;
  4496. let Inst{15} = isSub;
  4497. let Inst{14-10} = Ra;
  4498. let Inst{9-5} = Rn;
  4499. let Inst{4-0} = Rd;
  4500. }
  4501. multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
  4502. SDPatternOperator node> {
  4503. def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
  4504. [(set (f16 FPR16:$Rd),
  4505. (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
  4506. let Inst{23-22} = 0b11; // 16-bit size flag
  4507. let Predicates = [HasFullFP16];
  4508. }
  4509. def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
  4510. [(set FPR32:$Rd,
  4511. (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
  4512. let Inst{23-22} = 0b00; // 32-bit size flag
  4513. }
  4514. def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
  4515. [(set FPR64:$Rd,
  4516. (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
  4517. let Inst{23-22} = 0b01; // 64-bit size flag
  4518. }
  4519. }
  4520. //---
  4521. // Floating point data comparisons
  4522. //---
  4523. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4524. class BaseOneOperandFPComparison<bit signalAllNans,
  4525. RegisterClass regtype, string asm,
  4526. list<dag> pat>
  4527. : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
  4528. Sched<[WriteFCmp]> {
  4529. bits<5> Rn;
  4530. let Inst{31-24} = 0b00011110;
  4531. let Inst{21} = 1;
  4532. let Inst{15-10} = 0b001000;
  4533. let Inst{9-5} = Rn;
  4534. let Inst{4} = signalAllNans;
  4535. let Inst{3-0} = 0b1000;
  4536. // Rm should be 0b00000 canonically, but we need to accept any value.
  4537. let PostEncoderMethod = "fixOneOperandFPComparison";
  4538. }
  4539. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4540. class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
  4541. string asm, list<dag> pat>
  4542. : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
  4543. Sched<[WriteFCmp]> {
  4544. bits<5> Rm;
  4545. bits<5> Rn;
  4546. let Inst{31-24} = 0b00011110;
  4547. let Inst{21} = 1;
  4548. let Inst{20-16} = Rm;
  4549. let Inst{15-10} = 0b001000;
  4550. let Inst{9-5} = Rn;
  4551. let Inst{4} = signalAllNans;
  4552. let Inst{3-0} = 0b0000;
  4553. }
  4554. multiclass FPComparison<bit signalAllNans, string asm,
  4555. SDPatternOperator OpNode = null_frag> {
  4556. let Defs = [NZCV] in {
  4557. def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
  4558. [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> {
  4559. let Inst{23-22} = 0b11;
  4560. let Predicates = [HasFullFP16];
  4561. }
  4562. def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
  4563. [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
  4564. let Inst{23-22} = 0b11;
  4565. let Predicates = [HasFullFP16];
  4566. }
  4567. def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
  4568. [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
  4569. let Inst{23-22} = 0b00;
  4570. }
  4571. def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
  4572. [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
  4573. let Inst{23-22} = 0b00;
  4574. }
  4575. def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
  4576. [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
  4577. let Inst{23-22} = 0b01;
  4578. }
  4579. def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
  4580. [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
  4581. let Inst{23-22} = 0b01;
  4582. }
  4583. } // Defs = [NZCV]
  4584. }
  4585. //---
  4586. // Floating point conditional comparisons
  4587. //---
  4588. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4589. class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
  4590. string mnemonic, list<dag> pat>
  4591. : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
  4592. mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
  4593. Sched<[WriteFCmp]> {
  4594. let Uses = [NZCV];
  4595. let Defs = [NZCV];
  4596. bits<5> Rn;
  4597. bits<5> Rm;
  4598. bits<4> nzcv;
  4599. bits<4> cond;
  4600. let Inst{31-24} = 0b00011110;
  4601. let Inst{21} = 1;
  4602. let Inst{20-16} = Rm;
  4603. let Inst{15-12} = cond;
  4604. let Inst{11-10} = 0b01;
  4605. let Inst{9-5} = Rn;
  4606. let Inst{4} = signalAllNans;
  4607. let Inst{3-0} = nzcv;
  4608. }
  4609. multiclass FPCondComparison<bit signalAllNans, string mnemonic,
  4610. SDPatternOperator OpNode = null_frag> {
  4611. def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic,
  4612. [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv),
  4613. (i32 imm:$cond), NZCV))]> {
  4614. let Inst{23-22} = 0b11;
  4615. let Predicates = [HasFullFP16];
  4616. }
  4617. def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
  4618. [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
  4619. (i32 imm:$cond), NZCV))]> {
  4620. let Inst{23-22} = 0b00;
  4621. }
  4622. def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
  4623. [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
  4624. (i32 imm:$cond), NZCV))]> {
  4625. let Inst{23-22} = 0b01;
  4626. }
  4627. }
  4628. //---
  4629. // Floating point conditional select
  4630. //---
  4631. class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
  4632. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
  4633. asm, "\t$Rd, $Rn, $Rm, $cond", "",
  4634. [(set regtype:$Rd,
  4635. (AArch64csel (vt regtype:$Rn), regtype:$Rm,
  4636. (i32 imm:$cond), NZCV))]>,
  4637. Sched<[WriteF]> {
  4638. bits<5> Rd;
  4639. bits<5> Rn;
  4640. bits<5> Rm;
  4641. bits<4> cond;
  4642. let Inst{31-24} = 0b00011110;
  4643. let Inst{21} = 1;
  4644. let Inst{20-16} = Rm;
  4645. let Inst{15-12} = cond;
  4646. let Inst{11-10} = 0b11;
  4647. let Inst{9-5} = Rn;
  4648. let Inst{4-0} = Rd;
  4649. }
  4650. multiclass FPCondSelect<string asm> {
  4651. let Uses = [NZCV] in {
  4652. def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
  4653. let Inst{23-22} = 0b11;
  4654. let Predicates = [HasFullFP16];
  4655. }
  4656. def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
  4657. let Inst{23-22} = 0b00;
  4658. }
  4659. def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
  4660. let Inst{23-22} = 0b01;
  4661. }
  4662. } // Uses = [NZCV]
  4663. }
  4664. //---
  4665. // Floating move immediate
  4666. //---
  4667. class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
  4668. : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
  4669. [(set regtype:$Rd, fpimmtype:$imm)]>,
  4670. Sched<[WriteFImm]> {
  4671. bits<5> Rd;
  4672. bits<8> imm;
  4673. let Inst{31-24} = 0b00011110;
  4674. let Inst{21} = 1;
  4675. let Inst{20-13} = imm;
  4676. let Inst{12-5} = 0b10000000;
  4677. let Inst{4-0} = Rd;
  4678. }
  4679. multiclass FPMoveImmediate<string asm> {
  4680. def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
  4681. let Inst{23-22} = 0b11;
  4682. let Predicates = [HasFullFP16];
  4683. }
  4684. def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
  4685. let Inst{23-22} = 0b00;
  4686. }
  4687. def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
  4688. let Inst{23-22} = 0b01;
  4689. }
  4690. }
  4691. } // end of 'let Predicates = [HasFPARMv8]'
  4692. //----------------------------------------------------------------------------
  4693. // AdvSIMD
  4694. //----------------------------------------------------------------------------
  4695. let Predicates = [HasNEON] in {
  4696. //----------------------------------------------------------------------------
  4697. // AdvSIMD three register vector instructions
  4698. //----------------------------------------------------------------------------
  4699. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4700. class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
  4701. RegisterOperand regtype, string asm, string kind,
  4702. list<dag> pattern>
  4703. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
  4704. "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
  4705. "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
  4706. Sched<[!if(Q, WriteVq, WriteVd)]> {
  4707. bits<5> Rd;
  4708. bits<5> Rn;
  4709. bits<5> Rm;
  4710. let Inst{31} = 0;
  4711. let Inst{30} = Q;
  4712. let Inst{29} = U;
  4713. let Inst{28-24} = 0b01110;
  4714. let Inst{23-21} = size;
  4715. let Inst{20-16} = Rm;
  4716. let Inst{15-11} = opcode;
  4717. let Inst{10} = 1;
  4718. let Inst{9-5} = Rn;
  4719. let Inst{4-0} = Rd;
  4720. }
  4721. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4722. class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
  4723. RegisterOperand regtype, string asm, string kind,
  4724. list<dag> pattern>
  4725. : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
  4726. "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
  4727. "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
  4728. Sched<[!if(Q, WriteVq, WriteVd)]> {
  4729. bits<5> Rd;
  4730. bits<5> Rn;
  4731. bits<5> Rm;
  4732. let Inst{31} = 0;
  4733. let Inst{30} = Q;
  4734. let Inst{29} = U;
  4735. let Inst{28-24} = 0b01110;
  4736. let Inst{23-21} = size;
  4737. let Inst{20-16} = Rm;
  4738. let Inst{15-11} = opcode;
  4739. let Inst{10} = 1;
  4740. let Inst{9-5} = Rn;
  4741. let Inst{4-0} = Rd;
  4742. }
  4743. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  4744. class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern>
  4745. : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>,
  4746. Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>;
  4747. multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> {
  4748. def v8i8 : BaseSIMDThreeSameVectorPseudo<V64,
  4749. [(set (v8i8 V64:$dst),
  4750. (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
  4751. def v16i8 : BaseSIMDThreeSameVectorPseudo<V128,
  4752. [(set (v16i8 V128:$dst),
  4753. (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
  4754. (v16i8 V128:$Rm)))]>;
  4755. def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
  4756. (v4i16 V64:$RHS))),
  4757. (!cast<Instruction>(NAME#"v8i8")
  4758. V64:$LHS, V64:$MHS, V64:$RHS)>;
  4759. def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
  4760. (v2i32 V64:$RHS))),
  4761. (!cast<Instruction>(NAME#"v8i8")
  4762. V64:$LHS, V64:$MHS, V64:$RHS)>;
  4763. def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
  4764. (v1i64 V64:$RHS))),
  4765. (!cast<Instruction>(NAME#"v8i8")
  4766. V64:$LHS, V64:$MHS, V64:$RHS)>;
  4767. def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
  4768. (v8i16 V128:$RHS))),
  4769. (!cast<Instruction>(NAME#"v16i8")
  4770. V128:$LHS, V128:$MHS, V128:$RHS)>;
  4771. def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
  4772. (v4i32 V128:$RHS))),
  4773. (!cast<Instruction>(NAME#"v16i8")
  4774. V128:$LHS, V128:$MHS, V128:$RHS)>;
  4775. def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
  4776. (v2i64 V128:$RHS))),
  4777. (!cast<Instruction>(NAME#"v16i8")
  4778. V128:$LHS, V128:$MHS, V128:$RHS)>;
  4779. }
  4780. // All operand sizes distinguished in the encoding.
  4781. multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
  4782. SDPatternOperator OpNode> {
  4783. def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
  4784. asm, ".8b",
  4785. [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
  4786. def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
  4787. asm, ".16b",
  4788. [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
  4789. def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
  4790. asm, ".4h",
  4791. [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
  4792. def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
  4793. asm, ".8h",
  4794. [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
  4795. def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
  4796. asm, ".2s",
  4797. [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
  4798. def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
  4799. asm, ".4s",
  4800. [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
  4801. def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
  4802. asm, ".2d",
  4803. [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
  4804. }
  4805. multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> {
  4806. def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)),
  4807. (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>;
  4808. def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
  4809. (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>;
  4810. def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
  4811. (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>;
  4812. def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)),
  4813. (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>;
  4814. def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
  4815. (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>;
  4816. def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
  4817. (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>;
  4818. def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
  4819. (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>;
  4820. }
  4821. // As above, but D sized elements unsupported.
  4822. multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
  4823. SDPatternOperator OpNode> {
  4824. def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
  4825. asm, ".8b",
  4826. [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
  4827. def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
  4828. asm, ".16b",
  4829. [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
  4830. def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
  4831. asm, ".4h",
  4832. [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
  4833. def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
  4834. asm, ".8h",
  4835. [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
  4836. def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
  4837. asm, ".2s",
  4838. [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
  4839. def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
  4840. asm, ".4s",
  4841. [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
  4842. }
  4843. multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
  4844. SDPatternOperator OpNode> {
  4845. def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
  4846. asm, ".8b",
  4847. [(set (v8i8 V64:$dst),
  4848. (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
  4849. def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
  4850. asm, ".16b",
  4851. [(set (v16i8 V128:$dst),
  4852. (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
  4853. def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
  4854. asm, ".4h",
  4855. [(set (v4i16 V64:$dst),
  4856. (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
  4857. def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
  4858. asm, ".8h",
  4859. [(set (v8i16 V128:$dst),
  4860. (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
  4861. def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
  4862. asm, ".2s",
  4863. [(set (v2i32 V64:$dst),
  4864. (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
  4865. def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
  4866. asm, ".4s",
  4867. [(set (v4i32 V128:$dst),
  4868. (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
  4869. }
  4870. // As above, but only B sized elements supported.
  4871. multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
  4872. SDPatternOperator OpNode> {
  4873. def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
  4874. asm, ".8b",
  4875. [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
  4876. def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
  4877. asm, ".16b",
  4878. [(set (v16i8 V128:$Rd),
  4879. (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
  4880. }
  4881. // As above, but only floating point elements supported.
  4882. multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
  4883. string asm, SDPatternOperator OpNode> {
  4884. let Predicates = [HasNEON, HasFullFP16] in {
  4885. def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
  4886. asm, ".4h",
  4887. [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
  4888. def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
  4889. asm, ".8h",
  4890. [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
  4891. } // Predicates = [HasNEON, HasFullFP16]
  4892. def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
  4893. asm, ".2s",
  4894. [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
  4895. def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
  4896. asm, ".4s",
  4897. [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
  4898. def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
  4899. asm, ".2d",
  4900. [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
  4901. }
  4902. multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
  4903. string asm,
  4904. SDPatternOperator OpNode> {
  4905. let Predicates = [HasNEON, HasFullFP16] in {
  4906. def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
  4907. asm, ".4h",
  4908. [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
  4909. def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
  4910. asm, ".8h",
  4911. [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
  4912. } // Predicates = [HasNEON, HasFullFP16]
  4913. def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
  4914. asm, ".2s",
  4915. [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
  4916. def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
  4917. asm, ".4s",
  4918. [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
  4919. def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
  4920. asm, ".2d",
  4921. [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
  4922. }
  4923. multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
  4924. string asm, SDPatternOperator OpNode> {
  4925. let Predicates = [HasNEON, HasFullFP16] in {
  4926. def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
  4927. asm, ".4h",
  4928. [(set (v4f16 V64:$dst),
  4929. (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
  4930. def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
  4931. asm, ".8h",
  4932. [(set (v8f16 V128:$dst),
  4933. (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
  4934. } // Predicates = [HasNEON, HasFullFP16]
  4935. def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
  4936. asm, ".2s",
  4937. [(set (v2f32 V64:$dst),
  4938. (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
  4939. def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
  4940. asm, ".4s",
  4941. [(set (v4f32 V128:$dst),
  4942. (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
  4943. def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
  4944. asm, ".2d",
  4945. [(set (v2f64 V128:$dst),
  4946. (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
  4947. }
  4948. // As above, but D and B sized elements unsupported.
  4949. multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
  4950. SDPatternOperator OpNode> {
  4951. def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
  4952. asm, ".4h",
  4953. [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
  4954. def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
  4955. asm, ".8h",
  4956. [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
  4957. def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
  4958. asm, ".2s",
  4959. [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
  4960. def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
  4961. asm, ".4s",
  4962. [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
  4963. }
  4964. // Logical three vector ops share opcode bits, and only use B sized elements.
  4965. multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
  4966. SDPatternOperator OpNode = null_frag> {
  4967. def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
  4968. asm, ".8b",
  4969. [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
  4970. def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
  4971. asm, ".16b",
  4972. [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
  4973. def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
  4974. (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
  4975. def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
  4976. (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
  4977. def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
  4978. (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
  4979. def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
  4980. (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
  4981. def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
  4982. (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
  4983. def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
  4984. (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
  4985. }
  4986. multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
  4987. string asm, SDPatternOperator OpNode = null_frag> {
  4988. def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
  4989. asm, ".8b",
  4990. [(set (v8i8 V64:$dst),
  4991. (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
  4992. def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
  4993. asm, ".16b",
  4994. [(set (v16i8 V128:$dst),
  4995. (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
  4996. (v16i8 V128:$Rm)))]>;
  4997. def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
  4998. (v4i16 V64:$RHS))),
  4999. (!cast<Instruction>(NAME#"v8i8")
  5000. V64:$LHS, V64:$MHS, V64:$RHS)>;
  5001. def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
  5002. (v2i32 V64:$RHS))),
  5003. (!cast<Instruction>(NAME#"v8i8")
  5004. V64:$LHS, V64:$MHS, V64:$RHS)>;
  5005. def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
  5006. (v1i64 V64:$RHS))),
  5007. (!cast<Instruction>(NAME#"v8i8")
  5008. V64:$LHS, V64:$MHS, V64:$RHS)>;
  5009. def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
  5010. (v8i16 V128:$RHS))),
  5011. (!cast<Instruction>(NAME#"v16i8")
  5012. V128:$LHS, V128:$MHS, V128:$RHS)>;
  5013. def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
  5014. (v4i32 V128:$RHS))),
  5015. (!cast<Instruction>(NAME#"v16i8")
  5016. V128:$LHS, V128:$MHS, V128:$RHS)>;
  5017. def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
  5018. (v2i64 V128:$RHS))),
  5019. (!cast<Instruction>(NAME#"v16i8")
  5020. V128:$LHS, V128:$MHS, V128:$RHS)>;
  5021. }
  5022. // ARMv8.2-A Dot Product Instructions (Vector): These instructions extract
  5023. // bytes from S-sized elements.
  5024. class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1,
  5025. string kind2, RegisterOperand RegType,
  5026. ValueType AccumType, ValueType InputType,
  5027. SDPatternOperator OpNode> :
  5028. BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1,
  5029. [(set (AccumType RegType:$dst),
  5030. (OpNode (AccumType RegType:$Rd),
  5031. (InputType RegType:$Rn),
  5032. (InputType RegType:$Rm)))]> {
  5033. let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
  5034. }
  5035. multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> {
  5036. def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64,
  5037. v2i32, v8i8, OpNode>;
  5038. def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128,
  5039. v4i32, v16i8, OpNode>;
  5040. }
  5041. // ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions
  5042. // select inputs from 4H vectors and accumulate outputs to a 2S vector (or from
  5043. // 8H to 4S, when Q=1).
  5044. class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1,
  5045. string kind2, RegisterOperand RegType,
  5046. ValueType AccumType, ValueType InputType,
  5047. SDPatternOperator OpNode> :
  5048. BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1,
  5049. [(set (AccumType RegType:$dst),
  5050. (OpNode (AccumType RegType:$Rd),
  5051. (InputType RegType:$Rn),
  5052. (InputType RegType:$Rm)))]> {
  5053. let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
  5054. let Inst{13} = b13;
  5055. }
  5056. multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm,
  5057. SDPatternOperator OpNode> {
  5058. def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64,
  5059. v2f32, v4f16, OpNode>;
  5060. def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128,
  5061. v4f32, v8f16, OpNode>;
  5062. }
  5063. //----------------------------------------------------------------------------
  5064. // AdvSIMD two register vector instructions.
  5065. //----------------------------------------------------------------------------
  5066. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  5067. class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
  5068. bits<2> size2, RegisterOperand regtype, string asm,
  5069. string dstkind, string srckind, list<dag> pattern>
  5070. : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
  5071. "{\t$Rd" # dstkind # ", $Rn" # srckind #
  5072. "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
  5073. Sched<[!if(Q, WriteVq, WriteVd)]> {
  5074. bits<5> Rd;
  5075. bits<5> Rn;
  5076. let Inst{31} = 0;
  5077. let Inst{30} = Q;
  5078. let Inst{29} = U;
  5079. let Inst{28-24} = 0b01110;
  5080. let Inst{23-22} = size;
  5081. let Inst{21} = 0b1;
  5082. let Inst{20-19} = size2;
  5083. let Inst{18-17} = 0b00;
  5084. let Inst{16-12} = opcode;
  5085. let Inst{11-10} = 0b10;
  5086. let Inst{9-5} = Rn;
  5087. let Inst{4-0} = Rd;
  5088. }
  5089. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  5090. class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
  5091. bits<2> size2, RegisterOperand regtype,
  5092. string asm, string dstkind, string srckind,
  5093. list<dag> pattern>
  5094. : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
  5095. "{\t$Rd" # dstkind # ", $Rn" # srckind #
  5096. "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
  5097. Sched<[!if(Q, WriteVq, WriteVd)]> {
  5098. bits<5> Rd;
  5099. bits<5> Rn;
  5100. let Inst{31} = 0;
  5101. let Inst{30} = Q;
  5102. let Inst{29} = U;
  5103. let Inst{28-24} = 0b01110;
  5104. let Inst{23-22} = size;
  5105. let Inst{21} = 0b1;
  5106. let Inst{20-19} = size2;
  5107. let Inst{18-17} = 0b00;
  5108. let Inst{16-12} = opcode;
  5109. let Inst{11-10} = 0b10;
  5110. let Inst{9-5} = Rn;
  5111. let Inst{4-0} = Rd;
  5112. }
  5113. // Supports B, H, and S element sizes.
  5114. multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
  5115. SDPatternOperator OpNode> {
  5116. def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
  5117. asm, ".8b", ".8b",
  5118. [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
  5119. def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
  5120. asm, ".16b", ".16b",
  5121. [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
  5122. def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
  5123. asm, ".4h", ".4h",
  5124. [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
  5125. def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
  5126. asm, ".8h", ".8h",
  5127. [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
  5128. def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
  5129. asm, ".2s", ".2s",
  5130. [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
  5131. def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
  5132. asm, ".4s", ".4s",
  5133. [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
  5134. }
  5135. class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
  5136. RegisterOperand regtype, string asm, string dstkind,
  5137. string srckind, string amount>
  5138. : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
  5139. "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
  5140. "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
  5141. Sched<[WriteVq]> {
  5142. bits<5> Rd;
  5143. bits<5> Rn;
  5144. let Inst{31} = 0;
  5145. let Inst{30} = Q;
  5146. let Inst{29-24} = 0b101110;
  5147. let Inst{23-22} = size;
  5148. let Inst{21-10} = 0b100001001110;
  5149. let Inst{9-5} = Rn;
  5150. let Inst{4-0} = Rd;
  5151. }
  5152. multiclass SIMDVectorLShiftLongBySizeBHS {
  5153. let hasSideEffects = 0 in {
  5154. def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
  5155. "shll", ".8h", ".8b", "8">;
  5156. def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
  5157. "shll2", ".8h", ".16b", "8">;
  5158. def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
  5159. "shll", ".4s", ".4h", "16">;
  5160. def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
  5161. "shll2", ".4s", ".8h", "16">;
  5162. def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
  5163. "shll", ".2d", ".2s", "32">;
  5164. def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
  5165. "shll2", ".2d", ".4s", "32">;
  5166. }
  5167. }
  5168. // Supports all element sizes.
  5169. multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
  5170. SDPatternOperator OpNode> {
  5171. def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
  5172. asm, ".4h", ".8b",
  5173. [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
  5174. def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
  5175. asm, ".8h", ".16b",
  5176. [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
  5177. def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
  5178. asm, ".2s", ".4h",
  5179. [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
  5180. def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
  5181. asm, ".4s", ".8h",
  5182. [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
  5183. def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
  5184. asm, ".1d", ".2s",
  5185. [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
  5186. def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
  5187. asm, ".2d", ".4s",
  5188. [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
  5189. }
  5190. multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
  5191. SDPatternOperator OpNode> {
  5192. def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
  5193. asm, ".4h", ".8b",
  5194. [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
  5195. (v8i8 V64:$Rn)))]>;
  5196. def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
  5197. asm, ".8h", ".16b",
  5198. [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
  5199. (v16i8 V128:$Rn)))]>;
  5200. def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
  5201. asm, ".2s", ".4h",
  5202. [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
  5203. (v4i16 V64:$Rn)))]>;
  5204. def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
  5205. asm, ".4s", ".8h",
  5206. [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
  5207. (v8i16 V128:$Rn)))]>;
  5208. def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
  5209. asm, ".1d", ".2s",
  5210. [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
  5211. (v2i32 V64:$Rn)))]>;
  5212. def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
  5213. asm, ".2d", ".4s",
  5214. [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
  5215. (v4i32 V128:$Rn)))]>;
  5216. }
  5217. // Supports all element sizes, except 1xD.
  5218. multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
  5219. SDPatternOperator OpNode> {
  5220. def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
  5221. asm, ".8b", ".8b",
  5222. [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
  5223. def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
  5224. asm, ".16b", ".16b",
  5225. [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
  5226. def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
  5227. asm, ".4h", ".4h",
  5228. [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
  5229. def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
  5230. asm, ".8h", ".8h",
  5231. [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
  5232. def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
  5233. asm, ".2s", ".2s",
  5234. [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
  5235. def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
  5236. asm, ".4s", ".4s",
  5237. [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
  5238. def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
  5239. asm, ".2d", ".2d",
  5240. [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
  5241. }
  5242. multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
  5243. SDPatternOperator OpNode = null_frag> {
  5244. def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
  5245. asm, ".8b", ".8b",
  5246. [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
  5247. def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
  5248. asm, ".16b", ".16b",
  5249. [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
  5250. def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
  5251. asm, ".4h", ".4h",
  5252. [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
  5253. def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
  5254. asm, ".8h", ".8h",
  5255. [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
  5256. def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
  5257. asm, ".2s", ".2s",
  5258. [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
  5259. def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
  5260. asm, ".4s", ".4s",
  5261. [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
  5262. def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
  5263. asm, ".2d", ".2d",
  5264. [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
  5265. }
  5266. // Supports only B element sizes.
  5267. multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
  5268. SDPatternOperator OpNode> {
  5269. def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
  5270. asm, ".8b", ".8b",
  5271. [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
  5272. def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
  5273. asm, ".16b", ".16b",
  5274. [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
  5275. }
  5276. // Supports only B and H element sizes.
  5277. multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
  5278. SDPatternOperator OpNode> {
  5279. def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
  5280. asm, ".8b", ".8b",
  5281. [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
  5282. def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
  5283. asm, ".16b", ".16b",
  5284. [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
  5285. def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
  5286. asm, ".4h", ".4h",
  5287. [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
  5288. def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
  5289. asm, ".8h", ".8h",
  5290. [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
  5291. }
  5292. // Supports H, S and D element sizes, uses high bit of the size field
  5293. // as an extra opcode bit.
  5294. multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
  5295. SDPatternOperator OpNode> {
  5296. let Predicates = [HasNEON, HasFullFP16] in {
  5297. def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
  5298. asm, ".4h", ".4h",
  5299. [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
  5300. def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
  5301. asm, ".8h", ".8h",
  5302. [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
  5303. } // Predicates = [HasNEON, HasFullFP16]
  5304. def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
  5305. asm, ".2s", ".2s",
  5306. [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
  5307. def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
  5308. asm, ".4s", ".4s",
  5309. [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
  5310. def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
  5311. asm, ".2d", ".2d",
  5312. [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
  5313. }
  5314. // Supports only S and D element sizes
  5315. multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm,
  5316. SDPatternOperator OpNode = null_frag> {
  5317. def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64,
  5318. asm, ".2s", ".2s",
  5319. [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
  5320. def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128,
  5321. asm, ".4s", ".4s",
  5322. [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
  5323. def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128,
  5324. asm, ".2d", ".2d",
  5325. [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
  5326. }
  5327. multiclass FRIntNNTVector<bit U, bit op, string asm,
  5328. SDPatternOperator OpNode = null_frag> :
  5329. SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>;
  5330. // Supports only S element size.
  5331. multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
  5332. SDPatternOperator OpNode> {
  5333. def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
  5334. asm, ".2s", ".2s",
  5335. [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
  5336. def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
  5337. asm, ".4s", ".4s",
  5338. [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
  5339. }
  5340. multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
  5341. SDPatternOperator OpNode> {
  5342. let Predicates = [HasNEON, HasFullFP16] in {
  5343. def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
  5344. asm, ".4h", ".4h",
  5345. [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
  5346. def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
  5347. asm, ".8h", ".8h",
  5348. [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
  5349. } // Predicates = [HasNEON, HasFullFP16]
  5350. def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
  5351. asm, ".2s", ".2s",
  5352. [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
  5353. def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
  5354. asm, ".4s", ".4s",
  5355. [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
  5356. def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
  5357. asm, ".2d", ".2d",
  5358. [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
  5359. }
  5360. multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
  5361. SDPatternOperator OpNode> {
  5362. let Predicates = [HasNEON, HasFullFP16] in {
  5363. def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
  5364. asm, ".4h", ".4h",
  5365. [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
  5366. def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
  5367. asm, ".8h", ".8h",
  5368. [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
  5369. } // Predicates = [HasNEON, HasFullFP16]
  5370. def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
  5371. asm, ".2s", ".2s",
  5372. [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
  5373. def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
  5374. asm, ".4s", ".4s",
  5375. [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
  5376. def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
  5377. asm, ".2d", ".2d",
  5378. [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
  5379. }
  5380. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  5381. class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
  5382. RegisterOperand inreg, RegisterOperand outreg,
  5383. string asm, string outkind, string inkind,
  5384. list<dag> pattern>
  5385. : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
  5386. "{\t$Rd" # outkind # ", $Rn" # inkind #
  5387. "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
  5388. Sched<[WriteVq]> {
  5389. bits<5> Rd;
  5390. bits<5> Rn;
  5391. let Inst{31} = 0;
  5392. let Inst{30} = Q;
  5393. let Inst{29} = U;
  5394. let Inst{28-24} = 0b01110;
  5395. let Inst{23-22} = size;
  5396. let Inst{21-17} = 0b10000;
  5397. let Inst{16-12} = opcode;
  5398. let Inst{11-10} = 0b10;
  5399. let Inst{9-5} = Rn;
  5400. let Inst{4-0} = Rd;
  5401. }
  5402. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  5403. class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
  5404. RegisterOperand inreg, RegisterOperand outreg,
  5405. string asm, string outkind, string inkind,
  5406. list<dag> pattern>
  5407. : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
  5408. "{\t$Rd" # outkind # ", $Rn" # inkind #
  5409. "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
  5410. Sched<[WriteVq]> {
  5411. bits<5> Rd;
  5412. bits<5> Rn;
  5413. let Inst{31} = 0;
  5414. let Inst{30} = Q;
  5415. let Inst{29} = U;
  5416. let Inst{28-24} = 0b01110;
  5417. let Inst{23-22} = size;
  5418. let Inst{21-17} = 0b10000;
  5419. let Inst{16-12} = opcode;
  5420. let Inst{11-10} = 0b10;
  5421. let Inst{9-5} = Rn;
  5422. let Inst{4-0} = Rd;
  5423. }
  5424. multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
  5425. SDPatternOperator OpNode> {
  5426. def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
  5427. asm, ".8b", ".8h",
  5428. [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
  5429. def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
  5430. asm#"2", ".16b", ".8h", []>;
  5431. def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
  5432. asm, ".4h", ".4s",
  5433. [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
  5434. def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
  5435. asm#"2", ".8h", ".4s", []>;
  5436. def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
  5437. asm, ".2s", ".2d",
  5438. [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
  5439. def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
  5440. asm#"2", ".4s", ".2d", []>;
  5441. def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
  5442. (!cast<Instruction>(NAME # "v16i8")
  5443. (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
  5444. def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
  5445. (!cast<Instruction>(NAME # "v8i16")
  5446. (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
  5447. def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
  5448. (!cast<Instruction>(NAME # "v4i32")
  5449. (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
  5450. }
  5451. class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
  5452. bits<5> opcode, RegisterOperand regtype, string asm,
  5453. string kind, string zero, ValueType dty,
  5454. ValueType sty, SDNode OpNode>
  5455. : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
  5456. "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
  5457. "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
  5458. [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
  5459. Sched<[!if(Q, WriteVq, WriteVd)]> {
  5460. bits<5> Rd;
  5461. bits<5> Rn;
  5462. let Inst{31} = 0;
  5463. let Inst{30} = Q;
  5464. let Inst{29} = U;
  5465. let Inst{28-24} = 0b01110;
  5466. let Inst{23-22} = size;
  5467. let Inst{21} = 0b1;
  5468. let Inst{20-19} = size2;
  5469. let Inst{18-17} = 0b00;
  5470. let Inst{16-12} = opcode;
  5471. let Inst{11-10} = 0b10;
  5472. let Inst{9-5} = Rn;
  5473. let Inst{4-0} = Rd;
  5474. }
  5475. // Comparisons support all element sizes, except 1xD.
  5476. multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
  5477. SDNode OpNode> {
  5478. def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
  5479. asm, ".8b", "0",
  5480. v8i8, v8i8, OpNode>;
  5481. def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
  5482. asm, ".16b", "0",
  5483. v16i8, v16i8, OpNode>;
  5484. def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
  5485. asm, ".4h", "0",
  5486. v4i16, v4i16, OpNode>;
  5487. def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
  5488. asm, ".8h", "0",
  5489. v8i16, v8i16, OpNode>;
  5490. def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
  5491. asm, ".2s", "0",
  5492. v2i32, v2i32, OpNode>;
  5493. def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
  5494. asm, ".4s", "0",
  5495. v4i32, v4i32, OpNode>;
  5496. def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
  5497. asm, ".2d", "0",
  5498. v2i64, v2i64, OpNode>;
  5499. }
  5500. // FP Comparisons support only S and D element sizes (and H for v8.2a).
  5501. multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
  5502. string asm, SDNode OpNode> {
  5503. let Predicates = [HasNEON, HasFullFP16] in {
  5504. def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
  5505. asm, ".4h", "0.0",
  5506. v4i16, v4f16, OpNode>;
  5507. def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
  5508. asm, ".8h", "0.0",
  5509. v8i16, v8f16, OpNode>;
  5510. } // Predicates = [HasNEON, HasFullFP16]
  5511. def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
  5512. asm, ".2s", "0.0",
  5513. v2i32, v2f32, OpNode>;
  5514. def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
  5515. asm, ".4s", "0.0",
  5516. v4i32, v4f32, OpNode>;
  5517. def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
  5518. asm, ".2d", "0.0",
  5519. v2i64, v2f64, OpNode>;
  5520. let Predicates = [HasNEON, HasFullFP16] in {
  5521. def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
  5522. (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
  5523. def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
  5524. (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
  5525. }
  5526. def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
  5527. (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
  5528. def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
  5529. (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
  5530. def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
  5531. (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
  5532. let Predicates = [HasNEON, HasFullFP16] in {
  5533. def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
  5534. (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
  5535. def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
  5536. (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
  5537. }
  5538. def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
  5539. (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
  5540. def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
  5541. (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
  5542. def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
  5543. (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
  5544. }
  5545. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  5546. class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
  5547. RegisterOperand outtype, RegisterOperand intype,
  5548. string asm, string VdTy, string VnTy,
  5549. list<dag> pattern>
  5550. : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
  5551. !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
  5552. Sched<[WriteVq]> {
  5553. bits<5> Rd;
  5554. bits<5> Rn;
  5555. let Inst{31} = 0;
  5556. let Inst{30} = Q;
  5557. let Inst{29} = U;
  5558. let Inst{28-24} = 0b01110;
  5559. let Inst{23-22} = size;
  5560. let Inst{21-17} = 0b10000;
  5561. let Inst{16-12} = opcode;
  5562. let Inst{11-10} = 0b10;
  5563. let Inst{9-5} = Rn;
  5564. let Inst{4-0} = Rd;
  5565. }
  5566. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  5567. class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
  5568. RegisterOperand outtype, RegisterOperand intype,
  5569. string asm, string VdTy, string VnTy,
  5570. list<dag> pattern>
  5571. : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
  5572. !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
  5573. Sched<[WriteVq]> {
  5574. bits<5> Rd;
  5575. bits<5> Rn;
  5576. let Inst{31} = 0;
  5577. let Inst{30} = Q;
  5578. let Inst{29} = U;
  5579. let Inst{28-24} = 0b01110;
  5580. let Inst{23-22} = size;
  5581. let Inst{21-17} = 0b10000;
  5582. let Inst{16-12} = opcode;
  5583. let Inst{11-10} = 0b10;
  5584. let Inst{9-5} = Rn;
  5585. let Inst{4-0} = Rd;
  5586. }
  5587. multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
  5588. def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
  5589. asm, ".4s", ".4h", []>;
  5590. def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
  5591. asm#"2", ".4s", ".8h", []>;
  5592. def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
  5593. asm, ".2d", ".2s", []>;
  5594. def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
  5595. asm#"2", ".2d", ".4s", []>;
  5596. }
  5597. multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
  5598. def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
  5599. asm, ".4h", ".4s", []>;
  5600. def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
  5601. asm#"2", ".8h", ".4s", []>;
  5602. def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
  5603. asm, ".2s", ".2d", []>;
  5604. def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
  5605. asm#"2", ".4s", ".2d", []>;
  5606. }
  5607. multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
  5608. Intrinsic OpNode> {
  5609. def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
  5610. asm, ".2s", ".2d",
  5611. [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
  5612. def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
  5613. asm#"2", ".4s", ".2d", []>;
  5614. def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
  5615. (!cast<Instruction>(NAME # "v4f32")
  5616. (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
  5617. }
  5618. //----------------------------------------------------------------------------
  5619. // AdvSIMD three register different-size vector instructions.
  5620. //----------------------------------------------------------------------------
  5621. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  5622. class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
  5623. RegisterOperand outtype, RegisterOperand intype1,
  5624. RegisterOperand intype2, string asm,
  5625. string outkind, string inkind1, string inkind2,
  5626. list<dag> pattern>
  5627. : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
  5628. "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
  5629. "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
  5630. Sched<[WriteVq]> {
  5631. bits<5> Rd;
  5632. bits<5> Rn;
  5633. bits<5> Rm;
  5634. let Inst{31} = 0;
  5635. let Inst{30} = size{0};
  5636. let Inst{29} = U;
  5637. let Inst{28-24} = 0b01110;
  5638. let Inst{23-22} = size{2-1};
  5639. let Inst{21} = 1;
  5640. let Inst{20-16} = Rm;
  5641. let Inst{15-12} = opcode;
  5642. let Inst{11-10} = 0b00;
  5643. let Inst{9-5} = Rn;
  5644. let Inst{4-0} = Rd;
  5645. }
  5646. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  5647. class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
  5648. RegisterOperand outtype, RegisterOperand intype1,
  5649. RegisterOperand intype2, string asm,
  5650. string outkind, string inkind1, string inkind2,
  5651. list<dag> pattern>
  5652. : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
  5653. "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
  5654. "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
  5655. Sched<[WriteVq]> {
  5656. bits<5> Rd;
  5657. bits<5> Rn;
  5658. bits<5> Rm;
  5659. let Inst{31} = 0;
  5660. let Inst{30} = size{0};
  5661. let Inst{29} = U;
  5662. let Inst{28-24} = 0b01110;
  5663. let Inst{23-22} = size{2-1};
  5664. let Inst{21} = 1;
  5665. let Inst{20-16} = Rm;
  5666. let Inst{15-12} = opcode;
  5667. let Inst{11-10} = 0b00;
  5668. let Inst{9-5} = Rn;
  5669. let Inst{4-0} = Rd;
  5670. }
  5671. // FIXME: TableGen doesn't know how to deal with expanded types that also
  5672. // change the element count (in this case, placing the results in
  5673. // the high elements of the result register rather than the low
  5674. // elements). Until that's fixed, we can't code-gen those.
  5675. multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
  5676. Intrinsic IntOp> {
  5677. def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
  5678. V64, V128, V128,
  5679. asm, ".8b", ".8h", ".8h",
  5680. [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
  5681. def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
  5682. V128, V128, V128,
  5683. asm#"2", ".16b", ".8h", ".8h",
  5684. []>;
  5685. def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
  5686. V64, V128, V128,
  5687. asm, ".4h", ".4s", ".4s",
  5688. [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
  5689. def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
  5690. V128, V128, V128,
  5691. asm#"2", ".8h", ".4s", ".4s",
  5692. []>;
  5693. def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
  5694. V64, V128, V128,
  5695. asm, ".2s", ".2d", ".2d",
  5696. [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
  5697. def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
  5698. V128, V128, V128,
  5699. asm#"2", ".4s", ".2d", ".2d",
  5700. []>;
  5701. // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
  5702. // a version attached to an instruction.
  5703. def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
  5704. (v8i16 V128:$Rm))),
  5705. (!cast<Instruction>(NAME # "v8i16_v16i8")
  5706. (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
  5707. V128:$Rn, V128:$Rm)>;
  5708. def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
  5709. (v4i32 V128:$Rm))),
  5710. (!cast<Instruction>(NAME # "v4i32_v8i16")
  5711. (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
  5712. V128:$Rn, V128:$Rm)>;
  5713. def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
  5714. (v2i64 V128:$Rm))),
  5715. (!cast<Instruction>(NAME # "v2i64_v4i32")
  5716. (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
  5717. V128:$Rn, V128:$Rm)>;
  5718. }
  5719. multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
  5720. Intrinsic IntOp> {
  5721. def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
  5722. V128, V64, V64,
  5723. asm, ".8h", ".8b", ".8b",
  5724. [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
  5725. def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
  5726. V128, V128, V128,
  5727. asm#"2", ".8h", ".16b", ".16b", []>;
  5728. let Predicates = [HasAES] in {
  5729. def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
  5730. V128, V64, V64,
  5731. asm, ".1q", ".1d", ".1d", []>;
  5732. def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
  5733. V128, V128, V128,
  5734. asm#"2", ".1q", ".2d", ".2d", []>;
  5735. }
  5736. def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
  5737. (v8i8 (extract_high_v16i8 V128:$Rm)))),
  5738. (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
  5739. }
  5740. multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
  5741. SDPatternOperator OpNode> {
  5742. def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
  5743. V128, V64, V64,
  5744. asm, ".4s", ".4h", ".4h",
  5745. [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
  5746. def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
  5747. V128, V128, V128,
  5748. asm#"2", ".4s", ".8h", ".8h",
  5749. [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
  5750. (extract_high_v8i16 V128:$Rm)))]>;
  5751. def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
  5752. V128, V64, V64,
  5753. asm, ".2d", ".2s", ".2s",
  5754. [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
  5755. def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
  5756. V128, V128, V128,
  5757. asm#"2", ".2d", ".4s", ".4s",
  5758. [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
  5759. (extract_high_v4i32 V128:$Rm)))]>;
  5760. }
  5761. multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
  5762. SDPatternOperator OpNode = null_frag> {
  5763. def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
  5764. V128, V64, V64,
  5765. asm, ".8h", ".8b", ".8b",
  5766. [(set (v8i16 V128:$Rd),
  5767. (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
  5768. def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
  5769. V128, V128, V128,
  5770. asm#"2", ".8h", ".16b", ".16b",
  5771. [(set (v8i16 V128:$Rd),
  5772. (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
  5773. (extract_high_v16i8 V128:$Rm)))))]>;
  5774. def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
  5775. V128, V64, V64,
  5776. asm, ".4s", ".4h", ".4h",
  5777. [(set (v4i32 V128:$Rd),
  5778. (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
  5779. def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
  5780. V128, V128, V128,
  5781. asm#"2", ".4s", ".8h", ".8h",
  5782. [(set (v4i32 V128:$Rd),
  5783. (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
  5784. (extract_high_v8i16 V128:$Rm)))))]>;
  5785. def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
  5786. V128, V64, V64,
  5787. asm, ".2d", ".2s", ".2s",
  5788. [(set (v2i64 V128:$Rd),
  5789. (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
  5790. def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
  5791. V128, V128, V128,
  5792. asm#"2", ".2d", ".4s", ".4s",
  5793. [(set (v2i64 V128:$Rd),
  5794. (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
  5795. (extract_high_v4i32 V128:$Rm)))))]>;
  5796. }
  5797. multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
  5798. string asm,
  5799. SDPatternOperator OpNode> {
  5800. def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
  5801. V128, V64, V64,
  5802. asm, ".8h", ".8b", ".8b",
  5803. [(set (v8i16 V128:$dst),
  5804. (add (v8i16 V128:$Rd),
  5805. (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
  5806. def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
  5807. V128, V128, V128,
  5808. asm#"2", ".8h", ".16b", ".16b",
  5809. [(set (v8i16 V128:$dst),
  5810. (add (v8i16 V128:$Rd),
  5811. (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
  5812. (extract_high_v16i8 V128:$Rm))))))]>;
  5813. def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
  5814. V128, V64, V64,
  5815. asm, ".4s", ".4h", ".4h",
  5816. [(set (v4i32 V128:$dst),
  5817. (add (v4i32 V128:$Rd),
  5818. (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
  5819. def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
  5820. V128, V128, V128,
  5821. asm#"2", ".4s", ".8h", ".8h",
  5822. [(set (v4i32 V128:$dst),
  5823. (add (v4i32 V128:$Rd),
  5824. (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
  5825. (extract_high_v8i16 V128:$Rm))))))]>;
  5826. def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
  5827. V128, V64, V64,
  5828. asm, ".2d", ".2s", ".2s",
  5829. [(set (v2i64 V128:$dst),
  5830. (add (v2i64 V128:$Rd),
  5831. (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
  5832. def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
  5833. V128, V128, V128,
  5834. asm#"2", ".2d", ".4s", ".4s",
  5835. [(set (v2i64 V128:$dst),
  5836. (add (v2i64 V128:$Rd),
  5837. (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
  5838. (extract_high_v4i32 V128:$Rm))))))]>;
  5839. }
  5840. multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
  5841. SDPatternOperator OpNode = null_frag> {
  5842. def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
  5843. V128, V64, V64,
  5844. asm, ".8h", ".8b", ".8b",
  5845. [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
  5846. def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
  5847. V128, V128, V128,
  5848. asm#"2", ".8h", ".16b", ".16b",
  5849. [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
  5850. (extract_high_v16i8 V128:$Rm)))]>;
  5851. def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
  5852. V128, V64, V64,
  5853. asm, ".4s", ".4h", ".4h",
  5854. [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
  5855. def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
  5856. V128, V128, V128,
  5857. asm#"2", ".4s", ".8h", ".8h",
  5858. [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
  5859. (extract_high_v8i16 V128:$Rm)))]>;
  5860. def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
  5861. V128, V64, V64,
  5862. asm, ".2d", ".2s", ".2s",
  5863. [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
  5864. def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
  5865. V128, V128, V128,
  5866. asm#"2", ".2d", ".4s", ".4s",
  5867. [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
  5868. (extract_high_v4i32 V128:$Rm)))]>;
  5869. }
  5870. multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
  5871. string asm,
  5872. SDPatternOperator OpNode> {
  5873. def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
  5874. V128, V64, V64,
  5875. asm, ".8h", ".8b", ".8b",
  5876. [(set (v8i16 V128:$dst),
  5877. (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
  5878. def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
  5879. V128, V128, V128,
  5880. asm#"2", ".8h", ".16b", ".16b",
  5881. [(set (v8i16 V128:$dst),
  5882. (OpNode (v8i16 V128:$Rd),
  5883. (extract_high_v16i8 V128:$Rn),
  5884. (extract_high_v16i8 V128:$Rm)))]>;
  5885. def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
  5886. V128, V64, V64,
  5887. asm, ".4s", ".4h", ".4h",
  5888. [(set (v4i32 V128:$dst),
  5889. (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
  5890. def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
  5891. V128, V128, V128,
  5892. asm#"2", ".4s", ".8h", ".8h",
  5893. [(set (v4i32 V128:$dst),
  5894. (OpNode (v4i32 V128:$Rd),
  5895. (extract_high_v8i16 V128:$Rn),
  5896. (extract_high_v8i16 V128:$Rm)))]>;
  5897. def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
  5898. V128, V64, V64,
  5899. asm, ".2d", ".2s", ".2s",
  5900. [(set (v2i64 V128:$dst),
  5901. (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
  5902. def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
  5903. V128, V128, V128,
  5904. asm#"2", ".2d", ".4s", ".4s",
  5905. [(set (v2i64 V128:$dst),
  5906. (OpNode (v2i64 V128:$Rd),
  5907. (extract_high_v4i32 V128:$Rn),
  5908. (extract_high_v4i32 V128:$Rm)))]>;
  5909. }
  5910. multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
  5911. SDPatternOperator Accum> {
  5912. def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
  5913. V128, V64, V64,
  5914. asm, ".4s", ".4h", ".4h",
  5915. [(set (v4i32 V128:$dst),
  5916. (Accum (v4i32 V128:$Rd),
  5917. (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
  5918. (v4i16 V64:$Rm)))))]>;
  5919. def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
  5920. V128, V128, V128,
  5921. asm#"2", ".4s", ".8h", ".8h",
  5922. [(set (v4i32 V128:$dst),
  5923. (Accum (v4i32 V128:$Rd),
  5924. (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
  5925. (extract_high_v8i16 V128:$Rm)))))]>;
  5926. def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
  5927. V128, V64, V64,
  5928. asm, ".2d", ".2s", ".2s",
  5929. [(set (v2i64 V128:$dst),
  5930. (Accum (v2i64 V128:$Rd),
  5931. (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
  5932. (v2i32 V64:$Rm)))))]>;
  5933. def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
  5934. V128, V128, V128,
  5935. asm#"2", ".2d", ".4s", ".4s",
  5936. [(set (v2i64 V128:$dst),
  5937. (Accum (v2i64 V128:$Rd),
  5938. (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
  5939. (extract_high_v4i32 V128:$Rm)))))]>;
  5940. }
  5941. multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
  5942. SDPatternOperator OpNode> {
  5943. def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
  5944. V128, V128, V64,
  5945. asm, ".8h", ".8h", ".8b",
  5946. [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
  5947. def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
  5948. V128, V128, V128,
  5949. asm#"2", ".8h", ".8h", ".16b",
  5950. [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
  5951. (extract_high_v16i8 V128:$Rm)))]>;
  5952. def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
  5953. V128, V128, V64,
  5954. asm, ".4s", ".4s", ".4h",
  5955. [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
  5956. def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
  5957. V128, V128, V128,
  5958. asm#"2", ".4s", ".4s", ".8h",
  5959. [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
  5960. (extract_high_v8i16 V128:$Rm)))]>;
  5961. def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
  5962. V128, V128, V64,
  5963. asm, ".2d", ".2d", ".2s",
  5964. [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
  5965. def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
  5966. V128, V128, V128,
  5967. asm#"2", ".2d", ".2d", ".4s",
  5968. [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
  5969. (extract_high_v4i32 V128:$Rm)))]>;
  5970. }
  5971. //----------------------------------------------------------------------------
  5972. // AdvSIMD bitwise extract from vector
  5973. //----------------------------------------------------------------------------
  5974. class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
  5975. string asm, string kind>
  5976. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
  5977. "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
  5978. "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
  5979. [(set (vty regtype:$Rd),
  5980. (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
  5981. Sched<[!if(size, WriteVq, WriteVd)]> {
  5982. bits<5> Rd;
  5983. bits<5> Rn;
  5984. bits<5> Rm;
  5985. bits<4> imm;
  5986. let Inst{31} = 0;
  5987. let Inst{30} = size;
  5988. let Inst{29-21} = 0b101110000;
  5989. let Inst{20-16} = Rm;
  5990. let Inst{15} = 0;
  5991. let Inst{14-11} = imm;
  5992. let Inst{10} = 0;
  5993. let Inst{9-5} = Rn;
  5994. let Inst{4-0} = Rd;
  5995. }
  5996. multiclass SIMDBitwiseExtract<string asm> {
  5997. def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
  5998. let imm{3} = 0;
  5999. }
  6000. def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
  6001. }
  6002. //----------------------------------------------------------------------------
  6003. // AdvSIMD zip vector
  6004. //----------------------------------------------------------------------------
  6005. class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
  6006. string asm, string kind, SDNode OpNode, ValueType valty>
  6007. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
  6008. "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
  6009. "|" # kind # "\t$Rd, $Rn, $Rm}", "",
  6010. [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
  6011. Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> {
  6012. bits<5> Rd;
  6013. bits<5> Rn;
  6014. bits<5> Rm;
  6015. let Inst{31} = 0;
  6016. let Inst{30} = size{0};
  6017. let Inst{29-24} = 0b001110;
  6018. let Inst{23-22} = size{2-1};
  6019. let Inst{21} = 0;
  6020. let Inst{20-16} = Rm;
  6021. let Inst{15} = 0;
  6022. let Inst{14-12} = opc;
  6023. let Inst{11-10} = 0b10;
  6024. let Inst{9-5} = Rn;
  6025. let Inst{4-0} = Rd;
  6026. }
  6027. multiclass SIMDZipVector<bits<3>opc, string asm,
  6028. SDNode OpNode> {
  6029. def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
  6030. asm, ".8b", OpNode, v8i8>;
  6031. def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
  6032. asm, ".16b", OpNode, v16i8>;
  6033. def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
  6034. asm, ".4h", OpNode, v4i16>;
  6035. def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
  6036. asm, ".8h", OpNode, v8i16>;
  6037. def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
  6038. asm, ".2s", OpNode, v2i32>;
  6039. def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
  6040. asm, ".4s", OpNode, v4i32>;
  6041. def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
  6042. asm, ".2d", OpNode, v2i64>;
  6043. def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
  6044. (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
  6045. def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
  6046. (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
  6047. def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
  6048. (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
  6049. def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
  6050. (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
  6051. def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
  6052. (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
  6053. }
  6054. //----------------------------------------------------------------------------
  6055. // AdvSIMD three register scalar instructions
  6056. //----------------------------------------------------------------------------
  6057. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
  6058. class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
  6059. RegisterClass regtype, string asm,
  6060. list<dag> pattern>
  6061. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
  6062. "\t$Rd, $Rn, $Rm", "", pattern>,
  6063. Sched<[WriteVd]> {
  6064. bits<5> Rd;
  6065. bits<5> Rn;
  6066. bits<5> Rm;
  6067. let Inst{31-30} = 0b01;
  6068. let Inst{29} = U;
  6069. let Inst{28-24} = 0b11110;
  6070. let Inst{23-21} = size;
  6071. let Inst{20-16} = Rm;
  6072. let Inst{15-11} = opcode;
  6073. let Inst{10} = 1;
  6074. let Inst{9-5} = Rn;
  6075. let Inst{4-0} = Rd;
  6076. }
  6077. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
  6078. class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
  6079. dag oops, dag iops, string asm,
  6080. list<dag> pattern>
  6081. : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
  6082. Sched<[WriteVd]> {
  6083. bits<5> Rd;
  6084. bits<5> Rn;
  6085. bits<5> Rm;
  6086. let Inst{31-30} = 0b01;
  6087. let Inst{29} = U;
  6088. let Inst{28-24} = 0b11110;
  6089. let Inst{23-22} = size;
  6090. let Inst{21} = R;
  6091. let Inst{20-16} = Rm;
  6092. let Inst{15-11} = opcode;
  6093. let Inst{10} = 1;
  6094. let Inst{9-5} = Rn;
  6095. let Inst{4-0} = Rd;
  6096. }
  6097. multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
  6098. SDPatternOperator OpNode> {
  6099. def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
  6100. [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
  6101. }
  6102. multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
  6103. SDPatternOperator OpNode> {
  6104. def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
  6105. [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
  6106. def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
  6107. def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
  6108. def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
  6109. def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
  6110. (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
  6111. def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
  6112. (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
  6113. }
  6114. multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
  6115. SDPatternOperator OpNode> {
  6116. def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
  6117. [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
  6118. def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
  6119. }
  6120. multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> {
  6121. def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
  6122. (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
  6123. asm, []>;
  6124. def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
  6125. (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
  6126. asm, []>;
  6127. }
  6128. multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
  6129. SDPatternOperator OpNode = null_frag,
  6130. Predicate pred = HasNEON> {
  6131. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
  6132. let Predicates = [pred] in {
  6133. def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
  6134. [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
  6135. def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
  6136. [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
  6137. }
  6138. let Predicates = [pred, HasFullFP16] in {
  6139. def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
  6140. [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>;
  6141. }
  6142. }
  6143. def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
  6144. (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
  6145. }
  6146. multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
  6147. SDPatternOperator OpNode = null_frag> {
  6148. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
  6149. def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
  6150. [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
  6151. def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
  6152. [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
  6153. let Predicates = [HasNEON, HasFullFP16] in {
  6154. def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
  6155. []>;
  6156. } // Predicates = [HasNEON, HasFullFP16]
  6157. }
  6158. def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
  6159. (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
  6160. }
  6161. class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
  6162. dag oops, dag iops, string asm, string cstr, list<dag> pat>
  6163. : I<oops, iops, asm,
  6164. "\t$Rd, $Rn, $Rm", cstr, pat>,
  6165. Sched<[WriteVd]> {
  6166. bits<5> Rd;
  6167. bits<5> Rn;
  6168. bits<5> Rm;
  6169. let Inst{31-30} = 0b01;
  6170. let Inst{29} = U;
  6171. let Inst{28-24} = 0b11110;
  6172. let Inst{23-22} = size;
  6173. let Inst{21} = 1;
  6174. let Inst{20-16} = Rm;
  6175. let Inst{15-11} = opcode;
  6176. let Inst{10} = 0;
  6177. let Inst{9-5} = Rn;
  6178. let Inst{4-0} = Rd;
  6179. }
  6180. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  6181. multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
  6182. SDPatternOperator OpNode = null_frag> {
  6183. def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
  6184. (outs FPR32:$Rd),
  6185. (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
  6186. def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
  6187. (outs FPR64:$Rd),
  6188. (ins FPR32:$Rn, FPR32:$Rm), asm, "",
  6189. [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
  6190. }
  6191. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  6192. multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
  6193. SDPatternOperator OpNode = null_frag> {
  6194. def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
  6195. (outs FPR32:$dst),
  6196. (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
  6197. asm, "$Rd = $dst", []>;
  6198. def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
  6199. (outs FPR64:$dst),
  6200. (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
  6201. asm, "$Rd = $dst",
  6202. [(set (i64 FPR64:$dst),
  6203. (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
  6204. }
  6205. //----------------------------------------------------------------------------
  6206. // AdvSIMD two register scalar instructions
  6207. //----------------------------------------------------------------------------
  6208. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  6209. class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
  6210. RegisterClass regtype, RegisterClass regtype2,
  6211. string asm, list<dag> pat>
  6212. : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
  6213. "\t$Rd, $Rn", "", pat>,
  6214. Sched<[WriteVd]> {
  6215. bits<5> Rd;
  6216. bits<5> Rn;
  6217. let Inst{31-30} = 0b01;
  6218. let Inst{29} = U;
  6219. let Inst{28-24} = 0b11110;
  6220. let Inst{23-22} = size;
  6221. let Inst{21} = 0b1;
  6222. let Inst{20-19} = size2;
  6223. let Inst{18-17} = 0b00;
  6224. let Inst{16-12} = opcode;
  6225. let Inst{11-10} = 0b10;
  6226. let Inst{9-5} = Rn;
  6227. let Inst{4-0} = Rd;
  6228. }
  6229. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  6230. class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
  6231. RegisterClass regtype, RegisterClass regtype2,
  6232. string asm, list<dag> pat>
  6233. : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
  6234. "\t$Rd, $Rn", "$Rd = $dst", pat>,
  6235. Sched<[WriteVd]> {
  6236. bits<5> Rd;
  6237. bits<5> Rn;
  6238. let Inst{31-30} = 0b01;
  6239. let Inst{29} = U;
  6240. let Inst{28-24} = 0b11110;
  6241. let Inst{23-22} = size;
  6242. let Inst{21-17} = 0b10000;
  6243. let Inst{16-12} = opcode;
  6244. let Inst{11-10} = 0b10;
  6245. let Inst{9-5} = Rn;
  6246. let Inst{4-0} = Rd;
  6247. }
  6248. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  6249. class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
  6250. RegisterClass regtype, string asm, string zero>
  6251. : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
  6252. "\t$Rd, $Rn, #" # zero, "", []>,
  6253. Sched<[WriteVd]> {
  6254. bits<5> Rd;
  6255. bits<5> Rn;
  6256. let Inst{31-30} = 0b01;
  6257. let Inst{29} = U;
  6258. let Inst{28-24} = 0b11110;
  6259. let Inst{23-22} = size;
  6260. let Inst{21} = 0b1;
  6261. let Inst{20-19} = size2;
  6262. let Inst{18-17} = 0b00;
  6263. let Inst{16-12} = opcode;
  6264. let Inst{11-10} = 0b10;
  6265. let Inst{9-5} = Rn;
  6266. let Inst{4-0} = Rd;
  6267. }
  6268. class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
  6269. : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
  6270. [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
  6271. Sched<[WriteVd]> {
  6272. bits<5> Rd;
  6273. bits<5> Rn;
  6274. let Inst{31-17} = 0b011111100110000;
  6275. let Inst{16-12} = opcode;
  6276. let Inst{11-10} = 0b10;
  6277. let Inst{9-5} = Rn;
  6278. let Inst{4-0} = Rd;
  6279. }
  6280. multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
  6281. SDPatternOperator OpNode> {
  6282. def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
  6283. def : Pat<(v1i64 (OpNode FPR64:$Rn)),
  6284. (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
  6285. }
  6286. multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
  6287. SDPatternOperator OpNode> {
  6288. def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
  6289. def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
  6290. let Predicates = [HasNEON, HasFullFP16] in {
  6291. def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
  6292. }
  6293. def : InstAlias<asm # "\t$Rd, $Rn, #0",
  6294. (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
  6295. def : InstAlias<asm # "\t$Rd, $Rn, #0",
  6296. (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
  6297. let Predicates = [HasNEON, HasFullFP16] in {
  6298. def : InstAlias<asm # "\t$Rd, $Rn, #0",
  6299. (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
  6300. }
  6301. def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
  6302. (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
  6303. }
  6304. multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
  6305. SDPatternOperator OpNode = null_frag> {
  6306. def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
  6307. [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
  6308. def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
  6309. (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
  6310. }
  6311. multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm,
  6312. Predicate pred = HasNEON> {
  6313. let Predicates = [pred] in {
  6314. def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
  6315. def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
  6316. }
  6317. let Predicates = [pred, HasFullFP16] in {
  6318. def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
  6319. }
  6320. }
  6321. multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
  6322. SDPatternOperator OpNode> {
  6323. def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
  6324. [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
  6325. def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
  6326. [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
  6327. let Predicates = [HasNEON, HasFullFP16] in {
  6328. def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
  6329. [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>;
  6330. }
  6331. }
  6332. multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
  6333. SDPatternOperator OpNode = null_frag> {
  6334. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
  6335. def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
  6336. [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
  6337. def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
  6338. [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
  6339. def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
  6340. def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
  6341. }
  6342. def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
  6343. (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
  6344. }
  6345. multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
  6346. Intrinsic OpNode> {
  6347. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
  6348. def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
  6349. [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
  6350. def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
  6351. [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
  6352. def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
  6353. def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
  6354. }
  6355. def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
  6356. (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
  6357. }
  6358. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  6359. multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
  6360. SDPatternOperator OpNode = null_frag> {
  6361. def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
  6362. [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
  6363. def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
  6364. def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
  6365. }
  6366. //----------------------------------------------------------------------------
  6367. // AdvSIMD scalar pairwise instructions
  6368. //----------------------------------------------------------------------------
  6369. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  6370. class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
  6371. RegisterOperand regtype, RegisterOperand vectype,
  6372. string asm, string kind>
  6373. : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
  6374. "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
  6375. Sched<[WriteVd]> {
  6376. bits<5> Rd;
  6377. bits<5> Rn;
  6378. let Inst{31-30} = 0b01;
  6379. let Inst{29} = U;
  6380. let Inst{28-24} = 0b11110;
  6381. let Inst{23-22} = size;
  6382. let Inst{21-17} = 0b11000;
  6383. let Inst{16-12} = opcode;
  6384. let Inst{11-10} = 0b10;
  6385. let Inst{9-5} = Rn;
  6386. let Inst{4-0} = Rd;
  6387. }
  6388. multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
  6389. def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
  6390. asm, ".2d">;
  6391. }
  6392. multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
  6393. let Predicates = [HasNEON, HasFullFP16] in {
  6394. def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
  6395. asm, ".2h">;
  6396. }
  6397. def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
  6398. asm, ".2s">;
  6399. def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
  6400. asm, ".2d">;
  6401. }
  6402. //----------------------------------------------------------------------------
  6403. // AdvSIMD across lanes instructions
  6404. //----------------------------------------------------------------------------
  6405. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  6406. class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
  6407. RegisterClass regtype, RegisterOperand vectype,
  6408. string asm, string kind, list<dag> pattern>
  6409. : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
  6410. "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
  6411. Sched<[!if(Q, WriteVq, WriteVd)]> {
  6412. bits<5> Rd;
  6413. bits<5> Rn;
  6414. let Inst{31} = 0;
  6415. let Inst{30} = Q;
  6416. let Inst{29} = U;
  6417. let Inst{28-24} = 0b01110;
  6418. let Inst{23-22} = size;
  6419. let Inst{21-17} = 0b11000;
  6420. let Inst{16-12} = opcode;
  6421. let Inst{11-10} = 0b10;
  6422. let Inst{9-5} = Rn;
  6423. let Inst{4-0} = Rd;
  6424. }
  6425. multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
  6426. string asm> {
  6427. def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
  6428. asm, ".8b", []>;
  6429. def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
  6430. asm, ".16b", []>;
  6431. def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
  6432. asm, ".4h", []>;
  6433. def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
  6434. asm, ".8h", []>;
  6435. def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
  6436. asm, ".4s", []>;
  6437. }
  6438. multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
  6439. def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
  6440. asm, ".8b", []>;
  6441. def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
  6442. asm, ".16b", []>;
  6443. def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
  6444. asm, ".4h", []>;
  6445. def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
  6446. asm, ".8h", []>;
  6447. def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
  6448. asm, ".4s", []>;
  6449. }
  6450. multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
  6451. Intrinsic intOp> {
  6452. let Predicates = [HasNEON, HasFullFP16] in {
  6453. def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
  6454. asm, ".4h",
  6455. [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>;
  6456. def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
  6457. asm, ".8h",
  6458. [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>;
  6459. } // Predicates = [HasNEON, HasFullFP16]
  6460. def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
  6461. asm, ".4s",
  6462. [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
  6463. }
  6464. //----------------------------------------------------------------------------
  6465. // AdvSIMD INS/DUP instructions
  6466. //----------------------------------------------------------------------------
  6467. // FIXME: There has got to be a better way to factor these. ugh.
  6468. class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
  6469. string operands, string constraints, list<dag> pattern>
  6470. : I<outs, ins, asm, operands, constraints, pattern>,
  6471. Sched<[!if(Q, WriteVq, WriteVd)]> {
  6472. bits<5> Rd;
  6473. bits<5> Rn;
  6474. let Inst{31} = 0;
  6475. let Inst{30} = Q;
  6476. let Inst{29} = op;
  6477. let Inst{28-21} = 0b01110000;
  6478. let Inst{15} = 0;
  6479. let Inst{10} = 1;
  6480. let Inst{9-5} = Rn;
  6481. let Inst{4-0} = Rd;
  6482. }
  6483. class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
  6484. RegisterOperand vecreg, RegisterClass regtype>
  6485. : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
  6486. "{\t$Rd" # size # ", $Rn" #
  6487. "|" # size # "\t$Rd, $Rn}", "",
  6488. [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
  6489. let Inst{20-16} = imm5;
  6490. let Inst{14-11} = 0b0001;
  6491. }
  6492. class SIMDDupFromElement<bit Q, string dstkind, string srckind,
  6493. ValueType vectype, ValueType insreg,
  6494. RegisterOperand vecreg, Operand idxtype,
  6495. SDNode OpNode>
  6496. : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
  6497. "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
  6498. "|" # dstkind # "\t$Rd, $Rn$idx}", "",
  6499. [(set (vectype vecreg:$Rd),
  6500. (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
  6501. let Inst{14-11} = 0b0000;
  6502. }
  6503. class SIMDDup64FromElement
  6504. : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
  6505. VectorIndexD, AArch64duplane64> {
  6506. bits<1> idx;
  6507. let Inst{20} = idx;
  6508. let Inst{19-16} = 0b1000;
  6509. }
  6510. class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
  6511. RegisterOperand vecreg>
  6512. : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
  6513. VectorIndexS, AArch64duplane32> {
  6514. bits<2> idx;
  6515. let Inst{20-19} = idx;
  6516. let Inst{18-16} = 0b100;
  6517. }
  6518. class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
  6519. RegisterOperand vecreg>
  6520. : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
  6521. VectorIndexH, AArch64duplane16> {
  6522. bits<3> idx;
  6523. let Inst{20-18} = idx;
  6524. let Inst{17-16} = 0b10;
  6525. }
  6526. class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
  6527. RegisterOperand vecreg>
  6528. : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
  6529. VectorIndexB, AArch64duplane8> {
  6530. bits<4> idx;
  6531. let Inst{20-17} = idx;
  6532. let Inst{16} = 1;
  6533. }
  6534. class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
  6535. Operand idxtype, string asm, list<dag> pattern>
  6536. : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
  6537. "{\t$Rd, $Rn" # size # "$idx" #
  6538. "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
  6539. let Inst{14-11} = imm4;
  6540. }
  6541. class SIMDSMov<bit Q, string size, RegisterClass regtype,
  6542. Operand idxtype>
  6543. : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
  6544. class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
  6545. Operand idxtype>
  6546. : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
  6547. [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
  6548. class SIMDMovAlias<string asm, string size, Instruction inst,
  6549. RegisterClass regtype, Operand idxtype>
  6550. : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
  6551. "|" # size # "\t$dst, $src$idx}",
  6552. (inst regtype:$dst, V128:$src, idxtype:$idx)>;
  6553. multiclass SMov {
  6554. // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME)
  6555. // streaming mode.
  6556. let Predicates = [HasNEONorStreamingSVE] in {
  6557. def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> {
  6558. let Inst{20-16} = 0b00001;
  6559. }
  6560. def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> {
  6561. let Inst{20-16} = 0b00001;
  6562. }
  6563. def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> {
  6564. let Inst{20-16} = 0b00010;
  6565. }
  6566. def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> {
  6567. let Inst{20-16} = 0b00010;
  6568. }
  6569. def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> {
  6570. let Inst{20-16} = 0b00100;
  6571. }
  6572. }
  6573. def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
  6574. bits<4> idx;
  6575. let Inst{20-17} = idx;
  6576. let Inst{16} = 1;
  6577. }
  6578. def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
  6579. bits<4> idx;
  6580. let Inst{20-17} = idx;
  6581. let Inst{16} = 1;
  6582. }
  6583. def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
  6584. bits<3> idx;
  6585. let Inst{20-18} = idx;
  6586. let Inst{17-16} = 0b10;
  6587. }
  6588. def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
  6589. bits<3> idx;
  6590. let Inst{20-18} = idx;
  6591. let Inst{17-16} = 0b10;
  6592. }
  6593. def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
  6594. bits<2> idx;
  6595. let Inst{20-19} = idx;
  6596. let Inst{18-16} = 0b100;
  6597. }
  6598. }
  6599. multiclass UMov {
  6600. // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME)
  6601. // streaming mode.
  6602. let Predicates = [HasNEONorStreamingSVE] in {
  6603. def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> {
  6604. let Inst{20-16} = 0b00001;
  6605. }
  6606. def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> {
  6607. let Inst{20-16} = 0b00010;
  6608. }
  6609. def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> {
  6610. let Inst{20-16} = 0b00100;
  6611. }
  6612. def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> {
  6613. let Inst{20-16} = 0b01000;
  6614. }
  6615. def : SIMDMovAlias<"mov", ".s",
  6616. !cast<Instruction>(NAME # vi32_idx0),
  6617. GPR32, VectorIndex0>;
  6618. def : SIMDMovAlias<"mov", ".d",
  6619. !cast<Instruction>(NAME # vi64_idx0),
  6620. GPR64, VectorIndex0>;
  6621. }
  6622. def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
  6623. bits<4> idx;
  6624. let Inst{20-17} = idx;
  6625. let Inst{16} = 1;
  6626. }
  6627. def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
  6628. bits<3> idx;
  6629. let Inst{20-18} = idx;
  6630. let Inst{17-16} = 0b10;
  6631. }
  6632. def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
  6633. bits<2> idx;
  6634. let Inst{20-19} = idx;
  6635. let Inst{18-16} = 0b100;
  6636. }
  6637. def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
  6638. bits<1> idx;
  6639. let Inst{20} = idx;
  6640. let Inst{19-16} = 0b1000;
  6641. }
  6642. def : SIMDMovAlias<"mov", ".s",
  6643. !cast<Instruction>(NAME#"vi32"),
  6644. GPR32, VectorIndexS>;
  6645. def : SIMDMovAlias<"mov", ".d",
  6646. !cast<Instruction>(NAME#"vi64"),
  6647. GPR64, VectorIndexD>;
  6648. }
  6649. class SIMDInsFromMain<string size, ValueType vectype,
  6650. RegisterClass regtype, Operand idxtype>
  6651. : BaseSIMDInsDup<1, 0, (outs V128:$dst),
  6652. (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
  6653. "{\t$Rd" # size # "$idx, $Rn" #
  6654. "|" # size # "\t$Rd$idx, $Rn}",
  6655. "$Rd = $dst",
  6656. [(set V128:$dst,
  6657. (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
  6658. let Inst{14-11} = 0b0011;
  6659. }
  6660. class SIMDInsFromElement<string size, ValueType vectype,
  6661. ValueType elttype, Operand idxtype>
  6662. : BaseSIMDInsDup<1, 1, (outs V128:$dst),
  6663. (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
  6664. "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
  6665. "|" # size # "\t$Rd$idx, $Rn$idx2}",
  6666. "$Rd = $dst",
  6667. [(set V128:$dst,
  6668. (vector_insert
  6669. (vectype V128:$Rd),
  6670. (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
  6671. idxtype:$idx))]>;
  6672. class SIMDInsMainMovAlias<string size, Instruction inst,
  6673. RegisterClass regtype, Operand idxtype>
  6674. : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
  6675. "|" # size #"\t$dst$idx, $src}",
  6676. (inst V128:$dst, idxtype:$idx, regtype:$src)>;
  6677. class SIMDInsElementMovAlias<string size, Instruction inst,
  6678. Operand idxtype>
  6679. : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2"
  6680. # "|" # size #"\t$dst$idx, $src$idx2}",
  6681. (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
  6682. multiclass SIMDIns {
  6683. def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
  6684. bits<4> idx;
  6685. let Inst{20-17} = idx;
  6686. let Inst{16} = 1;
  6687. }
  6688. def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
  6689. bits<3> idx;
  6690. let Inst{20-18} = idx;
  6691. let Inst{17-16} = 0b10;
  6692. }
  6693. def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
  6694. bits<2> idx;
  6695. let Inst{20-19} = idx;
  6696. let Inst{18-16} = 0b100;
  6697. }
  6698. def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
  6699. bits<1> idx;
  6700. let Inst{20} = idx;
  6701. let Inst{19-16} = 0b1000;
  6702. }
  6703. def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
  6704. bits<4> idx;
  6705. bits<4> idx2;
  6706. let Inst{20-17} = idx;
  6707. let Inst{16} = 1;
  6708. let Inst{14-11} = idx2;
  6709. }
  6710. def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
  6711. bits<3> idx;
  6712. bits<3> idx2;
  6713. let Inst{20-18} = idx;
  6714. let Inst{17-16} = 0b10;
  6715. let Inst{14-12} = idx2;
  6716. let Inst{11} = {?};
  6717. }
  6718. def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
  6719. bits<2> idx;
  6720. bits<2> idx2;
  6721. let Inst{20-19} = idx;
  6722. let Inst{18-16} = 0b100;
  6723. let Inst{14-13} = idx2;
  6724. let Inst{12-11} = {?,?};
  6725. }
  6726. def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
  6727. bits<1> idx;
  6728. bits<1> idx2;
  6729. let Inst{20} = idx;
  6730. let Inst{19-16} = 0b1000;
  6731. let Inst{14} = idx2;
  6732. let Inst{13-11} = {?,?,?};
  6733. }
  6734. // For all forms of the INS instruction, the "mov" mnemonic is the
  6735. // preferred alias. Why they didn't just call the instruction "mov" in
  6736. // the first place is a very good question indeed...
  6737. def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
  6738. GPR32, VectorIndexB>;
  6739. def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
  6740. GPR32, VectorIndexH>;
  6741. def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
  6742. GPR32, VectorIndexS>;
  6743. def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
  6744. GPR64, VectorIndexD>;
  6745. def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
  6746. VectorIndexB>;
  6747. def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
  6748. VectorIndexH>;
  6749. def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
  6750. VectorIndexS>;
  6751. def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
  6752. VectorIndexD>;
  6753. }
  6754. //----------------------------------------------------------------------------
  6755. // AdvSIMD TBL/TBX
  6756. //----------------------------------------------------------------------------
  6757. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
  6758. class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
  6759. RegisterOperand listtype, string asm, string kind>
  6760. : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
  6761. "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
  6762. Sched<[!if(Q, WriteVq, WriteVd)]> {
  6763. bits<5> Vd;
  6764. bits<5> Vn;
  6765. bits<5> Vm;
  6766. let Inst{31} = 0;
  6767. let Inst{30} = Q;
  6768. let Inst{29-21} = 0b001110000;
  6769. let Inst{20-16} = Vm;
  6770. let Inst{15} = 0;
  6771. let Inst{14-13} = len;
  6772. let Inst{12} = op;
  6773. let Inst{11-10} = 0b00;
  6774. let Inst{9-5} = Vn;
  6775. let Inst{4-0} = Vd;
  6776. }
  6777. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
  6778. class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
  6779. RegisterOperand listtype, string asm, string kind>
  6780. : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
  6781. "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
  6782. Sched<[!if(Q, WriteVq, WriteVd)]> {
  6783. bits<5> Vd;
  6784. bits<5> Vn;
  6785. bits<5> Vm;
  6786. let Inst{31} = 0;
  6787. let Inst{30} = Q;
  6788. let Inst{29-21} = 0b001110000;
  6789. let Inst{20-16} = Vm;
  6790. let Inst{15} = 0;
  6791. let Inst{14-13} = len;
  6792. let Inst{12} = op;
  6793. let Inst{11-10} = 0b00;
  6794. let Inst{9-5} = Vn;
  6795. let Inst{4-0} = Vd;
  6796. }
  6797. class SIMDTableLookupAlias<string asm, Instruction inst,
  6798. RegisterOperand vectype, RegisterOperand listtype>
  6799. : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
  6800. (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
  6801. multiclass SIMDTableLookup<bit op, string asm> {
  6802. def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
  6803. asm, ".8b">;
  6804. def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
  6805. asm, ".8b">;
  6806. def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
  6807. asm, ".8b">;
  6808. def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
  6809. asm, ".8b">;
  6810. def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
  6811. asm, ".16b">;
  6812. def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
  6813. asm, ".16b">;
  6814. def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
  6815. asm, ".16b">;
  6816. def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
  6817. asm, ".16b">;
  6818. def : SIMDTableLookupAlias<asm # ".8b",
  6819. !cast<Instruction>(NAME#"v8i8One"),
  6820. V64, VecListOne128>;
  6821. def : SIMDTableLookupAlias<asm # ".8b",
  6822. !cast<Instruction>(NAME#"v8i8Two"),
  6823. V64, VecListTwo128>;
  6824. def : SIMDTableLookupAlias<asm # ".8b",
  6825. !cast<Instruction>(NAME#"v8i8Three"),
  6826. V64, VecListThree128>;
  6827. def : SIMDTableLookupAlias<asm # ".8b",
  6828. !cast<Instruction>(NAME#"v8i8Four"),
  6829. V64, VecListFour128>;
  6830. def : SIMDTableLookupAlias<asm # ".16b",
  6831. !cast<Instruction>(NAME#"v16i8One"),
  6832. V128, VecListOne128>;
  6833. def : SIMDTableLookupAlias<asm # ".16b",
  6834. !cast<Instruction>(NAME#"v16i8Two"),
  6835. V128, VecListTwo128>;
  6836. def : SIMDTableLookupAlias<asm # ".16b",
  6837. !cast<Instruction>(NAME#"v16i8Three"),
  6838. V128, VecListThree128>;
  6839. def : SIMDTableLookupAlias<asm # ".16b",
  6840. !cast<Instruction>(NAME#"v16i8Four"),
  6841. V128, VecListFour128>;
  6842. }
  6843. multiclass SIMDTableLookupTied<bit op, string asm> {
  6844. def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
  6845. asm, ".8b">;
  6846. def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
  6847. asm, ".8b">;
  6848. def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
  6849. asm, ".8b">;
  6850. def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
  6851. asm, ".8b">;
  6852. def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
  6853. asm, ".16b">;
  6854. def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
  6855. asm, ".16b">;
  6856. def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
  6857. asm, ".16b">;
  6858. def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
  6859. asm, ".16b">;
  6860. def : SIMDTableLookupAlias<asm # ".8b",
  6861. !cast<Instruction>(NAME#"v8i8One"),
  6862. V64, VecListOne128>;
  6863. def : SIMDTableLookupAlias<asm # ".8b",
  6864. !cast<Instruction>(NAME#"v8i8Two"),
  6865. V64, VecListTwo128>;
  6866. def : SIMDTableLookupAlias<asm # ".8b",
  6867. !cast<Instruction>(NAME#"v8i8Three"),
  6868. V64, VecListThree128>;
  6869. def : SIMDTableLookupAlias<asm # ".8b",
  6870. !cast<Instruction>(NAME#"v8i8Four"),
  6871. V64, VecListFour128>;
  6872. def : SIMDTableLookupAlias<asm # ".16b",
  6873. !cast<Instruction>(NAME#"v16i8One"),
  6874. V128, VecListOne128>;
  6875. def : SIMDTableLookupAlias<asm # ".16b",
  6876. !cast<Instruction>(NAME#"v16i8Two"),
  6877. V128, VecListTwo128>;
  6878. def : SIMDTableLookupAlias<asm # ".16b",
  6879. !cast<Instruction>(NAME#"v16i8Three"),
  6880. V128, VecListThree128>;
  6881. def : SIMDTableLookupAlias<asm # ".16b",
  6882. !cast<Instruction>(NAME#"v16i8Four"),
  6883. V128, VecListFour128>;
  6884. }
  6885. //----------------------------------------------------------------------------
  6886. // AdvSIMD scalar DUP
  6887. //----------------------------------------------------------------------------
  6888. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  6889. class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype,
  6890. string asm, string kind, Operand idxtype>
  6891. : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm,
  6892. "{\t$dst, $src" # kind # "$idx" #
  6893. "|\t$dst, $src$idx}", "", []>,
  6894. Sched<[WriteVd]> {
  6895. bits<5> dst;
  6896. bits<5> src;
  6897. let Inst{31-21} = 0b01011110000;
  6898. let Inst{15-10} = 0b000001;
  6899. let Inst{9-5} = src;
  6900. let Inst{4-0} = dst;
  6901. }
  6902. class SIMDScalarDUPAlias<string asm, string size, Instruction inst,
  6903. RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
  6904. : InstAlias<asm # "{\t$dst, $src" # size # "$index"
  6905. # "|\t$dst, $src$index}",
  6906. (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
  6907. multiclass SIMDScalarDUP<string asm> {
  6908. def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> {
  6909. bits<4> idx;
  6910. let Inst{20-17} = idx;
  6911. let Inst{16} = 1;
  6912. }
  6913. def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> {
  6914. bits<3> idx;
  6915. let Inst{20-18} = idx;
  6916. let Inst{17-16} = 0b10;
  6917. }
  6918. def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> {
  6919. bits<2> idx;
  6920. let Inst{20-19} = idx;
  6921. let Inst{18-16} = 0b100;
  6922. }
  6923. def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> {
  6924. bits<1> idx;
  6925. let Inst{20} = idx;
  6926. let Inst{19-16} = 0b1000;
  6927. }
  6928. def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
  6929. VectorIndexD:$idx)))),
  6930. (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
  6931. // 'DUP' mnemonic aliases.
  6932. def : SIMDScalarDUPAlias<"dup", ".b",
  6933. !cast<Instruction>(NAME#"i8"),
  6934. FPR8, V128, VectorIndexB>;
  6935. def : SIMDScalarDUPAlias<"dup", ".h",
  6936. !cast<Instruction>(NAME#"i16"),
  6937. FPR16, V128, VectorIndexH>;
  6938. def : SIMDScalarDUPAlias<"dup", ".s",
  6939. !cast<Instruction>(NAME#"i32"),
  6940. FPR32, V128, VectorIndexS>;
  6941. def : SIMDScalarDUPAlias<"dup", ".d",
  6942. !cast<Instruction>(NAME#"i64"),
  6943. FPR64, V128, VectorIndexD>;
  6944. }
  6945. //----------------------------------------------------------------------------
  6946. // AdvSIMD modified immediate instructions
  6947. //----------------------------------------------------------------------------
  6948. class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
  6949. string asm, string op_string,
  6950. string cstr, list<dag> pattern>
  6951. : I<oops, iops, asm, op_string, cstr, pattern>,
  6952. Sched<[!if(Q, WriteVq, WriteVd)]> {
  6953. bits<5> Rd;
  6954. bits<8> imm8;
  6955. let Inst{31} = 0;
  6956. let Inst{30} = Q;
  6957. let Inst{29} = op;
  6958. let Inst{28-19} = 0b0111100000;
  6959. let Inst{18-16} = imm8{7-5};
  6960. let Inst{11} = op2;
  6961. let Inst{10} = 1;
  6962. let Inst{9-5} = imm8{4-0};
  6963. let Inst{4-0} = Rd;
  6964. }
  6965. class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
  6966. Operand immtype, dag opt_shift_iop,
  6967. string opt_shift, string asm, string kind,
  6968. list<dag> pattern>
  6969. : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
  6970. !con((ins immtype:$imm8), opt_shift_iop), asm,
  6971. "{\t$Rd" # kind # ", $imm8" # opt_shift #
  6972. "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
  6973. "", pattern> {
  6974. let DecoderMethod = "DecodeModImmInstruction";
  6975. }
  6976. class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
  6977. Operand immtype, dag opt_shift_iop,
  6978. string opt_shift, string asm, string kind,
  6979. list<dag> pattern>
  6980. : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
  6981. !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
  6982. asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
  6983. "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
  6984. "$Rd = $dst", pattern> {
  6985. let DecoderMethod = "DecodeModImmTiedInstruction";
  6986. }
  6987. class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
  6988. RegisterOperand vectype, string asm,
  6989. string kind, list<dag> pattern>
  6990. : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
  6991. (ins logical_vec_shift:$shift),
  6992. "$shift", asm, kind, pattern> {
  6993. bits<2> shift;
  6994. let Inst{15} = b15_b12{1};
  6995. let Inst{14-13} = shift;
  6996. let Inst{12} = b15_b12{0};
  6997. }
  6998. class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
  6999. RegisterOperand vectype, string asm,
  7000. string kind, list<dag> pattern>
  7001. : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
  7002. (ins logical_vec_shift:$shift),
  7003. "$shift", asm, kind, pattern> {
  7004. bits<2> shift;
  7005. let Inst{15} = b15_b12{1};
  7006. let Inst{14-13} = shift;
  7007. let Inst{12} = b15_b12{0};
  7008. }
  7009. class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
  7010. RegisterOperand vectype, string asm,
  7011. string kind, list<dag> pattern>
  7012. : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
  7013. (ins logical_vec_hw_shift:$shift),
  7014. "$shift", asm, kind, pattern> {
  7015. bits<2> shift;
  7016. let Inst{15} = b15_b12{1};
  7017. let Inst{14} = 0;
  7018. let Inst{13} = shift{0};
  7019. let Inst{12} = b15_b12{0};
  7020. }
  7021. class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
  7022. RegisterOperand vectype, string asm,
  7023. string kind, list<dag> pattern>
  7024. : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
  7025. (ins logical_vec_hw_shift:$shift),
  7026. "$shift", asm, kind, pattern> {
  7027. bits<2> shift;
  7028. let Inst{15} = b15_b12{1};
  7029. let Inst{14} = 0;
  7030. let Inst{13} = shift{0};
  7031. let Inst{12} = b15_b12{0};
  7032. }
  7033. multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
  7034. string asm> {
  7035. def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
  7036. asm, ".4h", []>;
  7037. def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
  7038. asm, ".8h", []>;
  7039. def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
  7040. asm, ".2s", []>;
  7041. def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
  7042. asm, ".4s", []>;
  7043. }
  7044. multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
  7045. bits<2> w_cmode, string asm,
  7046. SDNode OpNode> {
  7047. def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
  7048. asm, ".4h",
  7049. [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
  7050. imm0_255:$imm8,
  7051. (i32 imm:$shift)))]>;
  7052. def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
  7053. asm, ".8h",
  7054. [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
  7055. imm0_255:$imm8,
  7056. (i32 imm:$shift)))]>;
  7057. def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
  7058. asm, ".2s",
  7059. [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
  7060. imm0_255:$imm8,
  7061. (i32 imm:$shift)))]>;
  7062. def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
  7063. asm, ".4s",
  7064. [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
  7065. imm0_255:$imm8,
  7066. (i32 imm:$shift)))]>;
  7067. }
  7068. class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
  7069. RegisterOperand vectype, string asm,
  7070. string kind, list<dag> pattern>
  7071. : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
  7072. (ins move_vec_shift:$shift),
  7073. "$shift", asm, kind, pattern> {
  7074. bits<1> shift;
  7075. let Inst{15-13} = cmode{3-1};
  7076. let Inst{12} = shift;
  7077. }
  7078. class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
  7079. RegisterOperand vectype,
  7080. Operand imm_type, string asm,
  7081. string kind, list<dag> pattern>
  7082. : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
  7083. asm, kind, pattern> {
  7084. let Inst{15-12} = cmode;
  7085. }
  7086. class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
  7087. list<dag> pattern>
  7088. : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
  7089. "\t$Rd, $imm8", "", pattern> {
  7090. let Inst{15-12} = cmode;
  7091. let DecoderMethod = "DecodeModImmInstruction";
  7092. }
  7093. //----------------------------------------------------------------------------
  7094. // AdvSIMD indexed element
  7095. //----------------------------------------------------------------------------
  7096. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  7097. class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
  7098. RegisterOperand dst_reg, RegisterOperand lhs_reg,
  7099. RegisterOperand rhs_reg, Operand vec_idx, string asm,
  7100. string apple_kind, string dst_kind, string lhs_kind,
  7101. string rhs_kind, list<dag> pattern>
  7102. : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
  7103. asm,
  7104. "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
  7105. "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
  7106. Sched<[WriteVd]> {
  7107. bits<5> Rd;
  7108. bits<5> Rn;
  7109. bits<5> Rm;
  7110. let Inst{31} = 0;
  7111. let Inst{30} = Q;
  7112. let Inst{29} = U;
  7113. let Inst{28} = Scalar;
  7114. let Inst{27-24} = 0b1111;
  7115. let Inst{23-22} = size;
  7116. // Bit 21 must be set by the derived class.
  7117. let Inst{20-16} = Rm;
  7118. let Inst{15-12} = opc;
  7119. // Bit 11 must be set by the derived class.
  7120. let Inst{10} = 0;
  7121. let Inst{9-5} = Rn;
  7122. let Inst{4-0} = Rd;
  7123. }
  7124. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  7125. class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
  7126. RegisterOperand dst_reg, RegisterOperand lhs_reg,
  7127. RegisterOperand rhs_reg, Operand vec_idx, string asm,
  7128. string apple_kind, string dst_kind, string lhs_kind,
  7129. string rhs_kind, list<dag> pattern>
  7130. : I<(outs dst_reg:$dst),
  7131. (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
  7132. "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
  7133. "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
  7134. Sched<[WriteVd]> {
  7135. bits<5> Rd;
  7136. bits<5> Rn;
  7137. bits<5> Rm;
  7138. let Inst{31} = 0;
  7139. let Inst{30} = Q;
  7140. let Inst{29} = U;
  7141. let Inst{28} = Scalar;
  7142. let Inst{27-24} = 0b1111;
  7143. let Inst{23-22} = size;
  7144. // Bit 21 must be set by the derived class.
  7145. let Inst{20-16} = Rm;
  7146. let Inst{15-12} = opc;
  7147. // Bit 11 must be set by the derived class.
  7148. let Inst{10} = 0;
  7149. let Inst{9-5} = Rn;
  7150. let Inst{4-0} = Rd;
  7151. }
  7152. //----------------------------------------------------------------------------
  7153. // Armv8.6 BFloat16 Extension
  7154. //----------------------------------------------------------------------------
  7155. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in {
  7156. class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1,
  7157. string kind2, RegisterOperand RegType,
  7158. ValueType AccumType, ValueType InputType>
  7159. : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst),
  7160. (int_aarch64_neon_bfdot (AccumType RegType:$Rd),
  7161. (InputType RegType:$Rn),
  7162. (InputType RegType:$Rm)))]> {
  7163. let AsmString = !strconcat(asm,
  7164. "{\t$Rd" # kind1 # ", $Rn" # kind2 #
  7165. ", $Rm" # kind2 # "}");
  7166. }
  7167. multiclass SIMDThreeSameVectorBFDot<bit U, string asm> {
  7168. def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64,
  7169. v2f32, v4bf16>;
  7170. def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128,
  7171. v4f32, v8bf16>;
  7172. }
  7173. class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm,
  7174. string dst_kind, string lhs_kind,
  7175. string rhs_kind,
  7176. RegisterOperand RegType,
  7177. ValueType AccumType,
  7178. ValueType InputType>
  7179. : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111,
  7180. RegType, RegType, V128, VectorIndexS,
  7181. asm, "", dst_kind, lhs_kind, rhs_kind,
  7182. [(set (AccumType RegType:$dst),
  7183. (AccumType (int_aarch64_neon_bfdot
  7184. (AccumType RegType:$Rd),
  7185. (InputType RegType:$Rn),
  7186. (InputType (bitconvert (AccumType
  7187. (AArch64duplane32 (v4f32 V128:$Rm),
  7188. VectorIndexS:$idx)))))))]> {
  7189. bits<2> idx;
  7190. let Inst{21} = idx{0}; // L
  7191. let Inst{11} = idx{1}; // H
  7192. }
  7193. multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> {
  7194. def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h",
  7195. ".2h", V64, v2f32, v4bf16>;
  7196. def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h",
  7197. ".2h", V128, v4f32, v8bf16>;
  7198. }
  7199. class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode>
  7200. : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s",
  7201. [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
  7202. (v8bf16 V128:$Rn),
  7203. (v8bf16 V128:$Rm)))]> {
  7204. let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}");
  7205. }
  7206. class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode>
  7207. : I<(outs V128:$dst),
  7208. (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm,
  7209. "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst",
  7210. [(set (v4f32 V128:$dst),
  7211. (v4f32 (OpNode (v4f32 V128:$Rd),
  7212. (v8bf16 V128:$Rn),
  7213. (v8bf16
  7214. (AArch64duplane16 (v8bf16 V128_lo:$Rm),
  7215. VectorIndexH:$idx)))))]>,
  7216. Sched<[WriteVq]> {
  7217. bits<5> Rd;
  7218. bits<5> Rn;
  7219. bits<4> Rm;
  7220. bits<3> idx;
  7221. let Inst{31} = 0;
  7222. let Inst{30} = Q;
  7223. let Inst{29-22} = 0b00111111;
  7224. let Inst{21-20} = idx{1-0};
  7225. let Inst{19-16} = Rm;
  7226. let Inst{15-12} = 0b1111;
  7227. let Inst{11} = idx{2}; // H
  7228. let Inst{10} = 0;
  7229. let Inst{9-5} = Rn;
  7230. let Inst{4-0} = Rd;
  7231. }
  7232. class SIMDThreeSameVectorBF16MatrixMul<string asm>
  7233. : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101,
  7234. V128, asm, ".4s",
  7235. [(set (v4f32 V128:$dst),
  7236. (int_aarch64_neon_bfmmla (v4f32 V128:$Rd),
  7237. (v8bf16 V128:$Rn),
  7238. (v8bf16 V128:$Rm)))]> {
  7239. let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h",
  7240. ", $Rm", ".8h", "}");
  7241. }
  7242. class SIMD_BFCVTN
  7243. : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128,
  7244. "bfcvtn", ".4h", ".4s",
  7245. [(set (v8bf16 V128:$Rd),
  7246. (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>;
  7247. class SIMD_BFCVTN2
  7248. : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128,
  7249. "bfcvtn2", ".8h", ".4s",
  7250. [(set (v8bf16 V128:$dst),
  7251. (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>;
  7252. class BF16ToSinglePrecision<string asm>
  7253. : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "",
  7254. [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>,
  7255. Sched<[WriteFCvt]> {
  7256. bits<5> Rd;
  7257. bits<5> Rn;
  7258. let Inst{31-10} = 0b0001111001100011010000;
  7259. let Inst{9-5} = Rn;
  7260. let Inst{4-0} = Rd;
  7261. }
  7262. } // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0
  7263. //----------------------------------------------------------------------------
  7264. // Armv8.6 Matrix Multiply Extension
  7265. //----------------------------------------------------------------------------
  7266. class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode>
  7267. : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s",
  7268. [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
  7269. (v16i8 V128:$Rn),
  7270. (v16i8 V128:$Rm)))]> {
  7271. let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}";
  7272. }
  7273. //----------------------------------------------------------------------------
  7274. // ARMv8.2-A Dot Product Instructions (Indexed)
  7275. class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm,
  7276. string dst_kind, string lhs_kind, string rhs_kind,
  7277. RegisterOperand RegType,
  7278. ValueType AccumType, ValueType InputType,
  7279. SDPatternOperator OpNode> :
  7280. BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128,
  7281. VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind,
  7282. [(set (AccumType RegType:$dst),
  7283. (AccumType (OpNode (AccumType RegType:$Rd),
  7284. (InputType RegType:$Rn),
  7285. (InputType (bitconvert (AccumType
  7286. (AArch64duplane32 (v4i32 V128:$Rm),
  7287. VectorIndexS:$idx)))))))]> {
  7288. bits<2> idx;
  7289. let Inst{21} = idx{0}; // L
  7290. let Inst{11} = idx{1}; // H
  7291. }
  7292. multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm,
  7293. SDPatternOperator OpNode> {
  7294. def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b",
  7295. V64, v2i32, v8i8, OpNode>;
  7296. def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b",
  7297. V128, v4i32, v16i8, OpNode>;
  7298. }
  7299. // ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed)
  7300. class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm,
  7301. string dst_kind, string lhs_kind,
  7302. string rhs_kind, RegisterOperand RegType,
  7303. ValueType AccumType, ValueType InputType,
  7304. SDPatternOperator OpNode> :
  7305. BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128,
  7306. VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind,
  7307. [(set (AccumType RegType:$dst),
  7308. (AccumType (OpNode (AccumType RegType:$Rd),
  7309. (InputType RegType:$Rn),
  7310. (InputType (AArch64duplane16 (v8f16 V128:$Rm),
  7311. VectorIndexH:$idx)))))]> {
  7312. // idx = H:L:M
  7313. bits<3> idx;
  7314. let Inst{11} = idx{2}; // H
  7315. let Inst{21} = idx{1}; // L
  7316. let Inst{20} = idx{0}; // M
  7317. }
  7318. multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm,
  7319. SDPatternOperator OpNode> {
  7320. def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h",
  7321. V64, v2f32, v4f16, OpNode>;
  7322. def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h",
  7323. V128, v4f32, v8f16, OpNode>;
  7324. }
  7325. multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
  7326. SDPatternOperator OpNode> {
  7327. let Predicates = [HasNEON, HasFullFP16] in {
  7328. def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
  7329. V64, V64,
  7330. V128_lo, VectorIndexH,
  7331. asm, ".4h", ".4h", ".4h", ".h",
  7332. [(set (v4f16 V64:$Rd),
  7333. (OpNode (v4f16 V64:$Rn),
  7334. (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
  7335. bits<3> idx;
  7336. let Inst{11} = idx{2};
  7337. let Inst{21} = idx{1};
  7338. let Inst{20} = idx{0};
  7339. }
  7340. def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
  7341. V128, V128,
  7342. V128_lo, VectorIndexH,
  7343. asm, ".8h", ".8h", ".8h", ".h",
  7344. [(set (v8f16 V128:$Rd),
  7345. (OpNode (v8f16 V128:$Rn),
  7346. (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
  7347. bits<3> idx;
  7348. let Inst{11} = idx{2};
  7349. let Inst{21} = idx{1};
  7350. let Inst{20} = idx{0};
  7351. }
  7352. } // Predicates = [HasNEON, HasFullFP16]
  7353. def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
  7354. V64, V64,
  7355. V128, VectorIndexS,
  7356. asm, ".2s", ".2s", ".2s", ".s",
  7357. [(set (v2f32 V64:$Rd),
  7358. (OpNode (v2f32 V64:$Rn),
  7359. (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
  7360. bits<2> idx;
  7361. let Inst{11} = idx{1};
  7362. let Inst{21} = idx{0};
  7363. }
  7364. def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
  7365. V128, V128,
  7366. V128, VectorIndexS,
  7367. asm, ".4s", ".4s", ".4s", ".s",
  7368. [(set (v4f32 V128:$Rd),
  7369. (OpNode (v4f32 V128:$Rn),
  7370. (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
  7371. bits<2> idx;
  7372. let Inst{11} = idx{1};
  7373. let Inst{21} = idx{0};
  7374. }
  7375. def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
  7376. V128, V128,
  7377. V128, VectorIndexD,
  7378. asm, ".2d", ".2d", ".2d", ".d",
  7379. [(set (v2f64 V128:$Rd),
  7380. (OpNode (v2f64 V128:$Rn),
  7381. (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
  7382. bits<1> idx;
  7383. let Inst{11} = idx{0};
  7384. let Inst{21} = 0;
  7385. }
  7386. let Predicates = [HasNEON, HasFullFP16] in {
  7387. def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
  7388. FPR16Op, FPR16Op, V128_lo, VectorIndexH,
  7389. asm, ".h", "", "", ".h",
  7390. [(set (f16 FPR16Op:$Rd),
  7391. (OpNode (f16 FPR16Op:$Rn),
  7392. (f16 (vector_extract (v8f16 V128_lo:$Rm),
  7393. VectorIndexH:$idx))))]> {
  7394. bits<3> idx;
  7395. let Inst{11} = idx{2};
  7396. let Inst{21} = idx{1};
  7397. let Inst{20} = idx{0};
  7398. }
  7399. } // Predicates = [HasNEON, HasFullFP16]
  7400. def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
  7401. FPR32Op, FPR32Op, V128, VectorIndexS,
  7402. asm, ".s", "", "", ".s",
  7403. [(set (f32 FPR32Op:$Rd),
  7404. (OpNode (f32 FPR32Op:$Rn),
  7405. (f32 (vector_extract (v4f32 V128:$Rm),
  7406. VectorIndexS:$idx))))]> {
  7407. bits<2> idx;
  7408. let Inst{11} = idx{1};
  7409. let Inst{21} = idx{0};
  7410. }
  7411. def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
  7412. FPR64Op, FPR64Op, V128, VectorIndexD,
  7413. asm, ".d", "", "", ".d",
  7414. [(set (f64 FPR64Op:$Rd),
  7415. (OpNode (f64 FPR64Op:$Rn),
  7416. (f64 (vector_extract (v2f64 V128:$Rm),
  7417. VectorIndexD:$idx))))]> {
  7418. bits<1> idx;
  7419. let Inst{11} = idx{0};
  7420. let Inst{21} = 0;
  7421. }
  7422. }
  7423. multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
  7424. let Predicates = [HasNEON, HasFullFP16] in {
  7425. // Patterns for f16: DUPLANE, DUP scalar and vector_extract.
  7426. def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),
  7427. (AArch64duplane16 (v8f16 V128_lo:$Rm),
  7428. VectorIndexH:$idx))),
  7429. (!cast<Instruction>(INST # "v8i16_indexed")
  7430. V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;
  7431. def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),
  7432. (AArch64dup (f16 FPR16Op_lo:$Rm)))),
  7433. (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn,
  7434. (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;
  7435. def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),
  7436. (AArch64duplane16 (v8f16 V128_lo:$Rm),
  7437. VectorIndexH:$idx))),
  7438. (!cast<Instruction>(INST # "v4i16_indexed")
  7439. V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;
  7440. def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),
  7441. (AArch64dup (f16 FPR16Op_lo:$Rm)))),
  7442. (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn,
  7443. (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;
  7444. def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn),
  7445. (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))),
  7446. (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn,
  7447. V128_lo:$Rm, VectorIndexH:$idx)>;
  7448. } // Predicates = [HasNEON, HasFullFP16]
  7449. // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
  7450. def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
  7451. (AArch64duplane32 (v4f32 V128:$Rm),
  7452. VectorIndexS:$idx))),
  7453. (!cast<Instruction>(INST # v2i32_indexed)
  7454. V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
  7455. def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
  7456. (AArch64dup (f32 FPR32Op:$Rm)))),
  7457. (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
  7458. (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
  7459. // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
  7460. def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
  7461. (AArch64duplane32 (v4f32 V128:$Rm),
  7462. VectorIndexS:$idx))),
  7463. (!cast<Instruction>(INST # "v4i32_indexed")
  7464. V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
  7465. def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
  7466. (AArch64dup (f32 FPR32Op:$Rm)))),
  7467. (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
  7468. (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
  7469. // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
  7470. def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
  7471. (AArch64duplane64 (v2f64 V128:$Rm),
  7472. VectorIndexD:$idx))),
  7473. (!cast<Instruction>(INST # "v2i64_indexed")
  7474. V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
  7475. def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
  7476. (AArch64dup (f64 FPR64Op:$Rm)))),
  7477. (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
  7478. (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
  7479. // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s
  7480. def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
  7481. (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
  7482. (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
  7483. V128:$Rm, VectorIndexS:$idx)>;
  7484. // 1 variant for 64-bit scalar version: extract from .1d or from .2d
  7485. def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
  7486. (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
  7487. (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
  7488. V128:$Rm, VectorIndexD:$idx)>;
  7489. }
  7490. multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
  7491. let Predicates = [HasNEON, HasFullFP16] in {
  7492. def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
  7493. V128_lo, VectorIndexH,
  7494. asm, ".4h", ".4h", ".4h", ".h", []> {
  7495. bits<3> idx;
  7496. let Inst{11} = idx{2};
  7497. let Inst{21} = idx{1};
  7498. let Inst{20} = idx{0};
  7499. }
  7500. def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
  7501. V128, V128,
  7502. V128_lo, VectorIndexH,
  7503. asm, ".8h", ".8h", ".8h", ".h", []> {
  7504. bits<3> idx;
  7505. let Inst{11} = idx{2};
  7506. let Inst{21} = idx{1};
  7507. let Inst{20} = idx{0};
  7508. }
  7509. } // Predicates = [HasNEON, HasFullFP16]
  7510. def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
  7511. V128, VectorIndexS,
  7512. asm, ".2s", ".2s", ".2s", ".s", []> {
  7513. bits<2> idx;
  7514. let Inst{11} = idx{1};
  7515. let Inst{21} = idx{0};
  7516. }
  7517. def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
  7518. V128, V128,
  7519. V128, VectorIndexS,
  7520. asm, ".4s", ".4s", ".4s", ".s", []> {
  7521. bits<2> idx;
  7522. let Inst{11} = idx{1};
  7523. let Inst{21} = idx{0};
  7524. }
  7525. def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
  7526. V128, V128,
  7527. V128, VectorIndexD,
  7528. asm, ".2d", ".2d", ".2d", ".d", []> {
  7529. bits<1> idx;
  7530. let Inst{11} = idx{0};
  7531. let Inst{21} = 0;
  7532. }
  7533. let Predicates = [HasNEON, HasFullFP16] in {
  7534. def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
  7535. FPR16Op, FPR16Op, V128_lo, VectorIndexH,
  7536. asm, ".h", "", "", ".h", []> {
  7537. bits<3> idx;
  7538. let Inst{11} = idx{2};
  7539. let Inst{21} = idx{1};
  7540. let Inst{20} = idx{0};
  7541. }
  7542. } // Predicates = [HasNEON, HasFullFP16]
  7543. def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
  7544. FPR32Op, FPR32Op, V128, VectorIndexS,
  7545. asm, ".s", "", "", ".s", []> {
  7546. bits<2> idx;
  7547. let Inst{11} = idx{1};
  7548. let Inst{21} = idx{0};
  7549. }
  7550. def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
  7551. FPR64Op, FPR64Op, V128, VectorIndexD,
  7552. asm, ".d", "", "", ".d", []> {
  7553. bits<1> idx;
  7554. let Inst{11} = idx{0};
  7555. let Inst{21} = 0;
  7556. }
  7557. }
  7558. multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane,
  7559. SDPatternOperator OpNodeLaneQ> {
  7560. def : Pat<(v4i16 (OpNodeLane
  7561. (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm),
  7562. VectorIndexS32b:$idx)),
  7563. (!cast<Instruction>(NAME # v4i16_indexed) $Rn,
  7564. (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub),
  7565. (UImmS1XForm $idx))>;
  7566. def : Pat<(v4i16 (OpNodeLaneQ
  7567. (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm),
  7568. VectorIndexH32b:$idx)),
  7569. (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm,
  7570. (UImmS1XForm $idx))>;
  7571. def : Pat<(v8i16 (OpNodeLane
  7572. (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm),
  7573. VectorIndexS32b:$idx)),
  7574. (!cast<Instruction>(NAME # v8i16_indexed) $Rn,
  7575. (SUBREG_TO_REG (i32 0), $Rm, dsub),
  7576. (UImmS1XForm $idx))>;
  7577. def : Pat<(v8i16 (OpNodeLaneQ
  7578. (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm),
  7579. VectorIndexH32b:$idx)),
  7580. (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm,
  7581. (UImmS1XForm $idx))>;
  7582. def : Pat<(v2i32 (OpNodeLane
  7583. (v2i32 V64:$Rn), (v2i32 V64:$Rm),
  7584. VectorIndexD32b:$idx)),
  7585. (!cast<Instruction>(NAME # v2i32_indexed) $Rn,
  7586. (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub),
  7587. (UImmS1XForm $idx))>;
  7588. def : Pat<(v2i32 (OpNodeLaneQ
  7589. (v2i32 V64:$Rn), (v4i32 V128:$Rm),
  7590. VectorIndexS32b:$idx)),
  7591. (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm,
  7592. (UImmS1XForm $idx))>;
  7593. def : Pat<(v4i32 (OpNodeLane
  7594. (v4i32 V128:$Rn), (v2i32 V64:$Rm),
  7595. VectorIndexD32b:$idx)),
  7596. (!cast<Instruction>(NAME # v4i32_indexed) $Rn,
  7597. (SUBREG_TO_REG (i32 0), $Rm, dsub),
  7598. (UImmS1XForm $idx))>;
  7599. def : Pat<(v4i32 (OpNodeLaneQ
  7600. (v4i32 V128:$Rn),
  7601. (v4i32 V128:$Rm),
  7602. VectorIndexS32b:$idx)),
  7603. (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm,
  7604. (UImmS1XForm $idx))>;
  7605. }
  7606. multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
  7607. SDPatternOperator OpNode> {
  7608. def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
  7609. V128_lo, VectorIndexH,
  7610. asm, ".4h", ".4h", ".4h", ".h",
  7611. [(set (v4i16 V64:$Rd),
  7612. (OpNode (v4i16 V64:$Rn),
  7613. (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
  7614. bits<3> idx;
  7615. let Inst{11} = idx{2};
  7616. let Inst{21} = idx{1};
  7617. let Inst{20} = idx{0};
  7618. }
  7619. def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
  7620. V128, V128,
  7621. V128_lo, VectorIndexH,
  7622. asm, ".8h", ".8h", ".8h", ".h",
  7623. [(set (v8i16 V128:$Rd),
  7624. (OpNode (v8i16 V128:$Rn),
  7625. (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
  7626. bits<3> idx;
  7627. let Inst{11} = idx{2};
  7628. let Inst{21} = idx{1};
  7629. let Inst{20} = idx{0};
  7630. }
  7631. def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
  7632. V64, V64,
  7633. V128, VectorIndexS,
  7634. asm, ".2s", ".2s", ".2s", ".s",
  7635. [(set (v2i32 V64:$Rd),
  7636. (OpNode (v2i32 V64:$Rn),
  7637. (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
  7638. bits<2> idx;
  7639. let Inst{11} = idx{1};
  7640. let Inst{21} = idx{0};
  7641. }
  7642. def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
  7643. V128, V128,
  7644. V128, VectorIndexS,
  7645. asm, ".4s", ".4s", ".4s", ".s",
  7646. [(set (v4i32 V128:$Rd),
  7647. (OpNode (v4i32 V128:$Rn),
  7648. (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
  7649. bits<2> idx;
  7650. let Inst{11} = idx{1};
  7651. let Inst{21} = idx{0};
  7652. }
  7653. def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
  7654. FPR16Op, FPR16Op, V128_lo, VectorIndexH,
  7655. asm, ".h", "", "", ".h", []> {
  7656. bits<3> idx;
  7657. let Inst{11} = idx{2};
  7658. let Inst{21} = idx{1};
  7659. let Inst{20} = idx{0};
  7660. }
  7661. def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
  7662. FPR32Op, FPR32Op, V128, VectorIndexS,
  7663. asm, ".s", "", "", ".s",
  7664. [(set (i32 FPR32Op:$Rd),
  7665. (OpNode FPR32Op:$Rn,
  7666. (i32 (vector_extract (v4i32 V128:$Rm),
  7667. VectorIndexS:$idx))))]> {
  7668. bits<2> idx;
  7669. let Inst{11} = idx{1};
  7670. let Inst{21} = idx{0};
  7671. }
  7672. }
  7673. multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
  7674. SDPatternOperator OpNode> {
  7675. def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
  7676. V64, V64,
  7677. V128_lo, VectorIndexH,
  7678. asm, ".4h", ".4h", ".4h", ".h",
  7679. [(set (v4i16 V64:$Rd),
  7680. (OpNode (v4i16 V64:$Rn),
  7681. (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
  7682. bits<3> idx;
  7683. let Inst{11} = idx{2};
  7684. let Inst{21} = idx{1};
  7685. let Inst{20} = idx{0};
  7686. }
  7687. def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
  7688. V128, V128,
  7689. V128_lo, VectorIndexH,
  7690. asm, ".8h", ".8h", ".8h", ".h",
  7691. [(set (v8i16 V128:$Rd),
  7692. (OpNode (v8i16 V128:$Rn),
  7693. (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
  7694. bits<3> idx;
  7695. let Inst{11} = idx{2};
  7696. let Inst{21} = idx{1};
  7697. let Inst{20} = idx{0};
  7698. }
  7699. def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
  7700. V64, V64,
  7701. V128, VectorIndexS,
  7702. asm, ".2s", ".2s", ".2s", ".s",
  7703. [(set (v2i32 V64:$Rd),
  7704. (OpNode (v2i32 V64:$Rn),
  7705. (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
  7706. bits<2> idx;
  7707. let Inst{11} = idx{1};
  7708. let Inst{21} = idx{0};
  7709. }
  7710. def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
  7711. V128, V128,
  7712. V128, VectorIndexS,
  7713. asm, ".4s", ".4s", ".4s", ".s",
  7714. [(set (v4i32 V128:$Rd),
  7715. (OpNode (v4i32 V128:$Rn),
  7716. (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
  7717. bits<2> idx;
  7718. let Inst{11} = idx{1};
  7719. let Inst{21} = idx{0};
  7720. }
  7721. }
  7722. multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
  7723. SDPatternOperator OpNode> {
  7724. def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
  7725. V128_lo, VectorIndexH,
  7726. asm, ".4h", ".4h", ".4h", ".h",
  7727. [(set (v4i16 V64:$dst),
  7728. (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
  7729. (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
  7730. bits<3> idx;
  7731. let Inst{11} = idx{2};
  7732. let Inst{21} = idx{1};
  7733. let Inst{20} = idx{0};
  7734. }
  7735. def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
  7736. V128, V128,
  7737. V128_lo, VectorIndexH,
  7738. asm, ".8h", ".8h", ".8h", ".h",
  7739. [(set (v8i16 V128:$dst),
  7740. (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
  7741. (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
  7742. bits<3> idx;
  7743. let Inst{11} = idx{2};
  7744. let Inst{21} = idx{1};
  7745. let Inst{20} = idx{0};
  7746. }
  7747. def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
  7748. V64, V64,
  7749. V128, VectorIndexS,
  7750. asm, ".2s", ".2s", ".2s", ".s",
  7751. [(set (v2i32 V64:$dst),
  7752. (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
  7753. (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
  7754. bits<2> idx;
  7755. let Inst{11} = idx{1};
  7756. let Inst{21} = idx{0};
  7757. }
  7758. def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
  7759. V128, V128,
  7760. V128, VectorIndexS,
  7761. asm, ".4s", ".4s", ".4s", ".s",
  7762. [(set (v4i32 V128:$dst),
  7763. (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
  7764. (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
  7765. bits<2> idx;
  7766. let Inst{11} = idx{1};
  7767. let Inst{21} = idx{0};
  7768. }
  7769. }
  7770. multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
  7771. SDPatternOperator OpNode> {
  7772. def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
  7773. V128, V64,
  7774. V128_lo, VectorIndexH,
  7775. asm, ".4s", ".4s", ".4h", ".h",
  7776. [(set (v4i32 V128:$Rd),
  7777. (OpNode (v4i16 V64:$Rn),
  7778. (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
  7779. bits<3> idx;
  7780. let Inst{11} = idx{2};
  7781. let Inst{21} = idx{1};
  7782. let Inst{20} = idx{0};
  7783. }
  7784. def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
  7785. V128, V128,
  7786. V128_lo, VectorIndexH,
  7787. asm#"2", ".4s", ".4s", ".8h", ".h",
  7788. [(set (v4i32 V128:$Rd),
  7789. (OpNode (extract_high_v8i16 V128:$Rn),
  7790. (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
  7791. VectorIndexH:$idx))))]> {
  7792. bits<3> idx;
  7793. let Inst{11} = idx{2};
  7794. let Inst{21} = idx{1};
  7795. let Inst{20} = idx{0};
  7796. }
  7797. def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
  7798. V128, V64,
  7799. V128, VectorIndexS,
  7800. asm, ".2d", ".2d", ".2s", ".s",
  7801. [(set (v2i64 V128:$Rd),
  7802. (OpNode (v2i32 V64:$Rn),
  7803. (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
  7804. bits<2> idx;
  7805. let Inst{11} = idx{1};
  7806. let Inst{21} = idx{0};
  7807. }
  7808. def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
  7809. V128, V128,
  7810. V128, VectorIndexS,
  7811. asm#"2", ".2d", ".2d", ".4s", ".s",
  7812. [(set (v2i64 V128:$Rd),
  7813. (OpNode (extract_high_v4i32 V128:$Rn),
  7814. (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
  7815. VectorIndexS:$idx))))]> {
  7816. bits<2> idx;
  7817. let Inst{11} = idx{1};
  7818. let Inst{21} = idx{0};
  7819. }
  7820. def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
  7821. FPR32Op, FPR16Op, V128_lo, VectorIndexH,
  7822. asm, ".h", "", "", ".h", []> {
  7823. bits<3> idx;
  7824. let Inst{11} = idx{2};
  7825. let Inst{21} = idx{1};
  7826. let Inst{20} = idx{0};
  7827. }
  7828. def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
  7829. FPR64Op, FPR32Op, V128, VectorIndexS,
  7830. asm, ".s", "", "", ".s", []> {
  7831. bits<2> idx;
  7832. let Inst{11} = idx{1};
  7833. let Inst{21} = idx{0};
  7834. }
  7835. }
  7836. multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
  7837. SDPatternOperator Accum> {
  7838. def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
  7839. V128, V64,
  7840. V128_lo, VectorIndexH,
  7841. asm, ".4s", ".4s", ".4h", ".h",
  7842. [(set (v4i32 V128:$dst),
  7843. (Accum (v4i32 V128:$Rd),
  7844. (v4i32 (int_aarch64_neon_sqdmull
  7845. (v4i16 V64:$Rn),
  7846. (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
  7847. VectorIndexH:$idx))))))]> {
  7848. bits<3> idx;
  7849. let Inst{11} = idx{2};
  7850. let Inst{21} = idx{1};
  7851. let Inst{20} = idx{0};
  7852. }
  7853. // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
  7854. // intermediate EXTRACT_SUBREG would be untyped.
  7855. def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
  7856. (i32 (vector_extract (v4i32
  7857. (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
  7858. (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
  7859. VectorIndexH:$idx)))),
  7860. (i64 0))))),
  7861. (EXTRACT_SUBREG
  7862. (!cast<Instruction>(NAME # v4i16_indexed)
  7863. (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
  7864. V128_lo:$Rm, VectorIndexH:$idx),
  7865. ssub)>;
  7866. def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
  7867. V128, V128,
  7868. V128_lo, VectorIndexH,
  7869. asm#"2", ".4s", ".4s", ".8h", ".h",
  7870. [(set (v4i32 V128:$dst),
  7871. (Accum (v4i32 V128:$Rd),
  7872. (v4i32 (int_aarch64_neon_sqdmull
  7873. (extract_high_v8i16 V128:$Rn),
  7874. (extract_high_v8i16
  7875. (AArch64duplane16 (v8i16 V128_lo:$Rm),
  7876. VectorIndexH:$idx))))))]> {
  7877. bits<3> idx;
  7878. let Inst{11} = idx{2};
  7879. let Inst{21} = idx{1};
  7880. let Inst{20} = idx{0};
  7881. }
  7882. def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
  7883. V128, V64,
  7884. V128, VectorIndexS,
  7885. asm, ".2d", ".2d", ".2s", ".s",
  7886. [(set (v2i64 V128:$dst),
  7887. (Accum (v2i64 V128:$Rd),
  7888. (v2i64 (int_aarch64_neon_sqdmull
  7889. (v2i32 V64:$Rn),
  7890. (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
  7891. VectorIndexS:$idx))))))]> {
  7892. bits<2> idx;
  7893. let Inst{11} = idx{1};
  7894. let Inst{21} = idx{0};
  7895. }
  7896. def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
  7897. V128, V128,
  7898. V128, VectorIndexS,
  7899. asm#"2", ".2d", ".2d", ".4s", ".s",
  7900. [(set (v2i64 V128:$dst),
  7901. (Accum (v2i64 V128:$Rd),
  7902. (v2i64 (int_aarch64_neon_sqdmull
  7903. (extract_high_v4i32 V128:$Rn),
  7904. (extract_high_v4i32
  7905. (AArch64duplane32 (v4i32 V128:$Rm),
  7906. VectorIndexS:$idx))))))]> {
  7907. bits<2> idx;
  7908. let Inst{11} = idx{1};
  7909. let Inst{21} = idx{0};
  7910. }
  7911. def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
  7912. FPR32Op, FPR16Op, V128_lo, VectorIndexH,
  7913. asm, ".h", "", "", ".h", []> {
  7914. bits<3> idx;
  7915. let Inst{11} = idx{2};
  7916. let Inst{21} = idx{1};
  7917. let Inst{20} = idx{0};
  7918. }
  7919. def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
  7920. FPR64Op, FPR32Op, V128, VectorIndexS,
  7921. asm, ".s", "", "", ".s",
  7922. [(set (i64 FPR64Op:$dst),
  7923. (Accum (i64 FPR64Op:$Rd),
  7924. (i64 (int_aarch64_neon_sqdmulls_scalar
  7925. (i32 FPR32Op:$Rn),
  7926. (i32 (vector_extract (v4i32 V128:$Rm),
  7927. VectorIndexS:$idx))))))]> {
  7928. bits<2> idx;
  7929. let Inst{11} = idx{1};
  7930. let Inst{21} = idx{0};
  7931. }
  7932. }
  7933. multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
  7934. SDPatternOperator OpNode> {
  7935. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
  7936. def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
  7937. V128, V64,
  7938. V128_lo, VectorIndexH,
  7939. asm, ".4s", ".4s", ".4h", ".h",
  7940. [(set (v4i32 V128:$Rd),
  7941. (OpNode (v4i16 V64:$Rn),
  7942. (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
  7943. bits<3> idx;
  7944. let Inst{11} = idx{2};
  7945. let Inst{21} = idx{1};
  7946. let Inst{20} = idx{0};
  7947. }
  7948. def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
  7949. V128, V128,
  7950. V128_lo, VectorIndexH,
  7951. asm#"2", ".4s", ".4s", ".8h", ".h",
  7952. [(set (v4i32 V128:$Rd),
  7953. (OpNode (extract_high_v8i16 V128:$Rn),
  7954. (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
  7955. VectorIndexH:$idx))))]> {
  7956. bits<3> idx;
  7957. let Inst{11} = idx{2};
  7958. let Inst{21} = idx{1};
  7959. let Inst{20} = idx{0};
  7960. }
  7961. def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
  7962. V128, V64,
  7963. V128, VectorIndexS,
  7964. asm, ".2d", ".2d", ".2s", ".s",
  7965. [(set (v2i64 V128:$Rd),
  7966. (OpNode (v2i32 V64:$Rn),
  7967. (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
  7968. bits<2> idx;
  7969. let Inst{11} = idx{1};
  7970. let Inst{21} = idx{0};
  7971. }
  7972. def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
  7973. V128, V128,
  7974. V128, VectorIndexS,
  7975. asm#"2", ".2d", ".2d", ".4s", ".s",
  7976. [(set (v2i64 V128:$Rd),
  7977. (OpNode (extract_high_v4i32 V128:$Rn),
  7978. (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
  7979. VectorIndexS:$idx))))]> {
  7980. bits<2> idx;
  7981. let Inst{11} = idx{1};
  7982. let Inst{21} = idx{0};
  7983. }
  7984. }
  7985. }
  7986. multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
  7987. SDPatternOperator OpNode> {
  7988. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
  7989. def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
  7990. V128, V64,
  7991. V128_lo, VectorIndexH,
  7992. asm, ".4s", ".4s", ".4h", ".h",
  7993. [(set (v4i32 V128:$dst),
  7994. (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
  7995. (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
  7996. bits<3> idx;
  7997. let Inst{11} = idx{2};
  7998. let Inst{21} = idx{1};
  7999. let Inst{20} = idx{0};
  8000. }
  8001. def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
  8002. V128, V128,
  8003. V128_lo, VectorIndexH,
  8004. asm#"2", ".4s", ".4s", ".8h", ".h",
  8005. [(set (v4i32 V128:$dst),
  8006. (OpNode (v4i32 V128:$Rd),
  8007. (extract_high_v8i16 V128:$Rn),
  8008. (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
  8009. VectorIndexH:$idx))))]> {
  8010. bits<3> idx;
  8011. let Inst{11} = idx{2};
  8012. let Inst{21} = idx{1};
  8013. let Inst{20} = idx{0};
  8014. }
  8015. def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
  8016. V128, V64,
  8017. V128, VectorIndexS,
  8018. asm, ".2d", ".2d", ".2s", ".s",
  8019. [(set (v2i64 V128:$dst),
  8020. (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
  8021. (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
  8022. bits<2> idx;
  8023. let Inst{11} = idx{1};
  8024. let Inst{21} = idx{0};
  8025. }
  8026. def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
  8027. V128, V128,
  8028. V128, VectorIndexS,
  8029. asm#"2", ".2d", ".2d", ".4s", ".s",
  8030. [(set (v2i64 V128:$dst),
  8031. (OpNode (v2i64 V128:$Rd),
  8032. (extract_high_v4i32 V128:$Rn),
  8033. (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
  8034. VectorIndexS:$idx))))]> {
  8035. bits<2> idx;
  8036. let Inst{11} = idx{1};
  8037. let Inst{21} = idx{0};
  8038. }
  8039. }
  8040. }
  8041. //----------------------------------------------------------------------------
  8042. // AdvSIMD scalar shift by immediate
  8043. //----------------------------------------------------------------------------
  8044. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
  8045. class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
  8046. RegisterClass regtype1, RegisterClass regtype2,
  8047. Operand immtype, string asm, list<dag> pattern>
  8048. : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
  8049. asm, "\t$Rd, $Rn, $imm", "", pattern>,
  8050. Sched<[WriteVd]> {
  8051. bits<5> Rd;
  8052. bits<5> Rn;
  8053. bits<7> imm;
  8054. let Inst{31-30} = 0b01;
  8055. let Inst{29} = U;
  8056. let Inst{28-23} = 0b111110;
  8057. let Inst{22-16} = fixed_imm;
  8058. let Inst{15-11} = opc;
  8059. let Inst{10} = 1;
  8060. let Inst{9-5} = Rn;
  8061. let Inst{4-0} = Rd;
  8062. }
  8063. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
  8064. class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
  8065. RegisterClass regtype1, RegisterClass regtype2,
  8066. Operand immtype, string asm, list<dag> pattern>
  8067. : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
  8068. asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
  8069. Sched<[WriteVd]> {
  8070. bits<5> Rd;
  8071. bits<5> Rn;
  8072. bits<7> imm;
  8073. let Inst{31-30} = 0b01;
  8074. let Inst{29} = U;
  8075. let Inst{28-23} = 0b111110;
  8076. let Inst{22-16} = fixed_imm;
  8077. let Inst{15-11} = opc;
  8078. let Inst{10} = 1;
  8079. let Inst{9-5} = Rn;
  8080. let Inst{4-0} = Rd;
  8081. }
  8082. multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
  8083. let Predicates = [HasNEON, HasFullFP16] in {
  8084. def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
  8085. FPR16, FPR16, vecshiftR16, asm, []> {
  8086. let Inst{19-16} = imm{3-0};
  8087. }
  8088. } // Predicates = [HasNEON, HasFullFP16]
  8089. def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
  8090. FPR32, FPR32, vecshiftR32, asm, []> {
  8091. let Inst{20-16} = imm{4-0};
  8092. }
  8093. def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
  8094. FPR64, FPR64, vecshiftR64, asm, []> {
  8095. let Inst{21-16} = imm{5-0};
  8096. }
  8097. }
  8098. multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
  8099. SDPatternOperator OpNode> {
  8100. def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
  8101. FPR64, FPR64, vecshiftR64, asm,
  8102. [(set (i64 FPR64:$Rd),
  8103. (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
  8104. let Inst{21-16} = imm{5-0};
  8105. }
  8106. def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
  8107. (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
  8108. }
  8109. multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
  8110. SDPatternOperator OpNode = null_frag> {
  8111. def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
  8112. FPR64, FPR64, vecshiftR64, asm,
  8113. [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
  8114. (i32 vecshiftR64:$imm)))]> {
  8115. let Inst{21-16} = imm{5-0};
  8116. }
  8117. def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
  8118. (i32 vecshiftR64:$imm))),
  8119. (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
  8120. vecshiftR64:$imm)>;
  8121. }
  8122. multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
  8123. SDPatternOperator OpNode> {
  8124. def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
  8125. FPR64, FPR64, vecshiftL64, asm,
  8126. [(set (i64 FPR64:$Rd),
  8127. (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
  8128. let Inst{21-16} = imm{5-0};
  8129. }
  8130. def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
  8131. (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
  8132. }
  8133. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
  8134. multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
  8135. def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
  8136. FPR64, FPR64, vecshiftL64, asm, []> {
  8137. let Inst{21-16} = imm{5-0};
  8138. }
  8139. }
  8140. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
  8141. multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
  8142. SDPatternOperator OpNode = null_frag> {
  8143. def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
  8144. FPR8, FPR16, vecshiftR8, asm, []> {
  8145. let Inst{18-16} = imm{2-0};
  8146. }
  8147. def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
  8148. FPR16, FPR32, vecshiftR16, asm, []> {
  8149. let Inst{19-16} = imm{3-0};
  8150. }
  8151. def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
  8152. FPR32, FPR64, vecshiftR32, asm,
  8153. [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
  8154. let Inst{20-16} = imm{4-0};
  8155. }
  8156. }
  8157. multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
  8158. SDPatternOperator OpNode> {
  8159. def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
  8160. FPR8, FPR8, vecshiftL8, asm, []> {
  8161. let Inst{18-16} = imm{2-0};
  8162. }
  8163. def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
  8164. FPR16, FPR16, vecshiftL16, asm, []> {
  8165. let Inst{19-16} = imm{3-0};
  8166. }
  8167. def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
  8168. FPR32, FPR32, vecshiftL32, asm,
  8169. [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
  8170. let Inst{20-16} = imm{4-0};
  8171. }
  8172. def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
  8173. FPR64, FPR64, vecshiftL64, asm,
  8174. [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
  8175. let Inst{21-16} = imm{5-0};
  8176. }
  8177. def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
  8178. (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
  8179. }
  8180. multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
  8181. def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
  8182. FPR8, FPR8, vecshiftR8, asm, []> {
  8183. let Inst{18-16} = imm{2-0};
  8184. }
  8185. def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
  8186. FPR16, FPR16, vecshiftR16, asm, []> {
  8187. let Inst{19-16} = imm{3-0};
  8188. }
  8189. def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
  8190. FPR32, FPR32, vecshiftR32, asm, []> {
  8191. let Inst{20-16} = imm{4-0};
  8192. }
  8193. def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
  8194. FPR64, FPR64, vecshiftR64, asm, []> {
  8195. let Inst{21-16} = imm{5-0};
  8196. }
  8197. }
  8198. //----------------------------------------------------------------------------
  8199. // AdvSIMD vector x indexed element
  8200. //----------------------------------------------------------------------------
  8201. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
  8202. class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
  8203. RegisterOperand dst_reg, RegisterOperand src_reg,
  8204. Operand immtype,
  8205. string asm, string dst_kind, string src_kind,
  8206. list<dag> pattern>
  8207. : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
  8208. asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
  8209. "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
  8210. Sched<[!if(Q, WriteVq, WriteVd)]> {
  8211. bits<5> Rd;
  8212. bits<5> Rn;
  8213. let Inst{31} = 0;
  8214. let Inst{30} = Q;
  8215. let Inst{29} = U;
  8216. let Inst{28-23} = 0b011110;
  8217. let Inst{22-16} = fixed_imm;
  8218. let Inst{15-11} = opc;
  8219. let Inst{10} = 1;
  8220. let Inst{9-5} = Rn;
  8221. let Inst{4-0} = Rd;
  8222. }
  8223. let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
  8224. class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
  8225. RegisterOperand vectype1, RegisterOperand vectype2,
  8226. Operand immtype,
  8227. string asm, string dst_kind, string src_kind,
  8228. list<dag> pattern>
  8229. : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
  8230. asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
  8231. "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
  8232. Sched<[!if(Q, WriteVq, WriteVd)]> {
  8233. bits<5> Rd;
  8234. bits<5> Rn;
  8235. let Inst{31} = 0;
  8236. let Inst{30} = Q;
  8237. let Inst{29} = U;
  8238. let Inst{28-23} = 0b011110;
  8239. let Inst{22-16} = fixed_imm;
  8240. let Inst{15-11} = opc;
  8241. let Inst{10} = 1;
  8242. let Inst{9-5} = Rn;
  8243. let Inst{4-0} = Rd;
  8244. }
  8245. multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
  8246. Intrinsic OpNode> {
  8247. let Predicates = [HasNEON, HasFullFP16] in {
  8248. def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
  8249. V64, V64, vecshiftR16,
  8250. asm, ".4h", ".4h",
  8251. [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
  8252. bits<4> imm;
  8253. let Inst{19-16} = imm;
  8254. }
  8255. def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
  8256. V128, V128, vecshiftR16,
  8257. asm, ".8h", ".8h",
  8258. [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
  8259. bits<4> imm;
  8260. let Inst{19-16} = imm;
  8261. }
  8262. } // Predicates = [HasNEON, HasFullFP16]
  8263. def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
  8264. V64, V64, vecshiftR32,
  8265. asm, ".2s", ".2s",
  8266. [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
  8267. bits<5> imm;
  8268. let Inst{20-16} = imm;
  8269. }
  8270. def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
  8271. V128, V128, vecshiftR32,
  8272. asm, ".4s", ".4s",
  8273. [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
  8274. bits<5> imm;
  8275. let Inst{20-16} = imm;
  8276. }
  8277. def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
  8278. V128, V128, vecshiftR64,
  8279. asm, ".2d", ".2d",
  8280. [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
  8281. bits<6> imm;
  8282. let Inst{21-16} = imm;
  8283. }
  8284. }
  8285. multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
  8286. Intrinsic OpNode> {
  8287. let Predicates = [HasNEON, HasFullFP16] in {
  8288. def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
  8289. V64, V64, vecshiftR16,
  8290. asm, ".4h", ".4h",
  8291. [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
  8292. bits<4> imm;
  8293. let Inst{19-16} = imm;
  8294. }
  8295. def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
  8296. V128, V128, vecshiftR16,
  8297. asm, ".8h", ".8h",
  8298. [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
  8299. bits<4> imm;
  8300. let Inst{19-16} = imm;
  8301. }
  8302. } // Predicates = [HasNEON, HasFullFP16]
  8303. def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
  8304. V64, V64, vecshiftR32,
  8305. asm, ".2s", ".2s",
  8306. [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
  8307. bits<5> imm;
  8308. let Inst{20-16} = imm;
  8309. }
  8310. def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
  8311. V128, V128, vecshiftR32,
  8312. asm, ".4s", ".4s",
  8313. [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
  8314. bits<5> imm;
  8315. let Inst{20-16} = imm;
  8316. }
  8317. def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
  8318. V128, V128, vecshiftR64,
  8319. asm, ".2d", ".2d",
  8320. [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
  8321. bits<6> imm;
  8322. let Inst{21-16} = imm;
  8323. }
  8324. }
  8325. multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
  8326. SDPatternOperator OpNode> {
  8327. def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
  8328. V64, V128, vecshiftR16Narrow,
  8329. asm, ".8b", ".8h",
  8330. [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
  8331. bits<3> imm;
  8332. let Inst{18-16} = imm;
  8333. }
  8334. def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
  8335. V128, V128, vecshiftR16Narrow,
  8336. asm#"2", ".16b", ".8h", []> {
  8337. bits<3> imm;
  8338. let Inst{18-16} = imm;
  8339. let hasSideEffects = 0;
  8340. }
  8341. def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
  8342. V64, V128, vecshiftR32Narrow,
  8343. asm, ".4h", ".4s",
  8344. [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
  8345. bits<4> imm;
  8346. let Inst{19-16} = imm;
  8347. }
  8348. def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
  8349. V128, V128, vecshiftR32Narrow,
  8350. asm#"2", ".8h", ".4s", []> {
  8351. bits<4> imm;
  8352. let Inst{19-16} = imm;
  8353. let hasSideEffects = 0;
  8354. }
  8355. def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
  8356. V64, V128, vecshiftR64Narrow,
  8357. asm, ".2s", ".2d",
  8358. [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
  8359. bits<5> imm;
  8360. let Inst{20-16} = imm;
  8361. }
  8362. def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
  8363. V128, V128, vecshiftR64Narrow,
  8364. asm#"2", ".4s", ".2d", []> {
  8365. bits<5> imm;
  8366. let Inst{20-16} = imm;
  8367. let hasSideEffects = 0;
  8368. }
  8369. // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
  8370. // themselves, so put them here instead.
  8371. // Patterns involving what's effectively an insert high and a normal
  8372. // intrinsic, represented by CONCAT_VECTORS.
  8373. def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
  8374. vecshiftR16Narrow:$imm)),
  8375. (!cast<Instruction>(NAME # "v16i8_shift")
  8376. (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
  8377. V128:$Rn, vecshiftR16Narrow:$imm)>;
  8378. def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
  8379. vecshiftR32Narrow:$imm)),
  8380. (!cast<Instruction>(NAME # "v8i16_shift")
  8381. (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
  8382. V128:$Rn, vecshiftR32Narrow:$imm)>;
  8383. def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
  8384. vecshiftR64Narrow:$imm)),
  8385. (!cast<Instruction>(NAME # "v4i32_shift")
  8386. (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
  8387. V128:$Rn, vecshiftR64Narrow:$imm)>;
  8388. }
  8389. multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
  8390. SDPatternOperator OpNode> {
  8391. def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
  8392. V64, V64, vecshiftL8,
  8393. asm, ".8b", ".8b",
  8394. [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
  8395. (i32 vecshiftL8:$imm)))]> {
  8396. bits<3> imm;
  8397. let Inst{18-16} = imm;
  8398. }
  8399. def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
  8400. V128, V128, vecshiftL8,
  8401. asm, ".16b", ".16b",
  8402. [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
  8403. (i32 vecshiftL8:$imm)))]> {
  8404. bits<3> imm;
  8405. let Inst{18-16} = imm;
  8406. }
  8407. def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
  8408. V64, V64, vecshiftL16,
  8409. asm, ".4h", ".4h",
  8410. [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
  8411. (i32 vecshiftL16:$imm)))]> {
  8412. bits<4> imm;
  8413. let Inst{19-16} = imm;
  8414. }
  8415. def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
  8416. V128, V128, vecshiftL16,
  8417. asm, ".8h", ".8h",
  8418. [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
  8419. (i32 vecshiftL16:$imm)))]> {
  8420. bits<4> imm;
  8421. let Inst{19-16} = imm;
  8422. }
  8423. def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
  8424. V64, V64, vecshiftL32,
  8425. asm, ".2s", ".2s",
  8426. [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
  8427. (i32 vecshiftL32:$imm)))]> {
  8428. bits<5> imm;
  8429. let Inst{20-16} = imm;
  8430. }
  8431. def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
  8432. V128, V128, vecshiftL32,
  8433. asm, ".4s", ".4s",
  8434. [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
  8435. (i32 vecshiftL32:$imm)))]> {
  8436. bits<5> imm;
  8437. let Inst{20-16} = imm;
  8438. }
  8439. def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
  8440. V128, V128, vecshiftL64,
  8441. asm, ".2d", ".2d",
  8442. [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
  8443. (i32 vecshiftL64:$imm)))]> {
  8444. bits<6> imm;
  8445. let Inst{21-16} = imm;
  8446. }
  8447. }
  8448. multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
  8449. SDPatternOperator OpNode> {
  8450. def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
  8451. V64, V64, vecshiftR8,
  8452. asm, ".8b", ".8b",
  8453. [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
  8454. (i32 vecshiftR8:$imm)))]> {
  8455. bits<3> imm;
  8456. let Inst{18-16} = imm;
  8457. }
  8458. def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
  8459. V128, V128, vecshiftR8,
  8460. asm, ".16b", ".16b",
  8461. [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
  8462. (i32 vecshiftR8:$imm)))]> {
  8463. bits<3> imm;
  8464. let Inst{18-16} = imm;
  8465. }
  8466. def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
  8467. V64, V64, vecshiftR16,
  8468. asm, ".4h", ".4h",
  8469. [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
  8470. (i32 vecshiftR16:$imm)))]> {
  8471. bits<4> imm;
  8472. let Inst{19-16} = imm;
  8473. }
  8474. def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
  8475. V128, V128, vecshiftR16,
  8476. asm, ".8h", ".8h",
  8477. [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
  8478. (i32 vecshiftR16:$imm)))]> {
  8479. bits<4> imm;
  8480. let Inst{19-16} = imm;
  8481. }
  8482. def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
  8483. V64, V64, vecshiftR32,
  8484. asm, ".2s", ".2s",
  8485. [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
  8486. (i32 vecshiftR32:$imm)))]> {
  8487. bits<5> imm;
  8488. let Inst{20-16} = imm;
  8489. }
  8490. def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
  8491. V128, V128, vecshiftR32,
  8492. asm, ".4s", ".4s",
  8493. [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
  8494. (i32 vecshiftR32:$imm)))]> {
  8495. bits<5> imm;
  8496. let Inst{20-16} = imm;
  8497. }
  8498. def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
  8499. V128, V128, vecshiftR64,
  8500. asm, ".2d", ".2d",
  8501. [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
  8502. (i32 vecshiftR64:$imm)))]> {
  8503. bits<6> imm;
  8504. let Inst{21-16} = imm;
  8505. }
  8506. }
  8507. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  8508. multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
  8509. SDPatternOperator OpNode = null_frag> {
  8510. def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
  8511. V64, V64, vecshiftR8, asm, ".8b", ".8b",
  8512. [(set (v8i8 V64:$dst),
  8513. (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
  8514. (i32 vecshiftR8:$imm)))]> {
  8515. bits<3> imm;
  8516. let Inst{18-16} = imm;
  8517. }
  8518. def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
  8519. V128, V128, vecshiftR8, asm, ".16b", ".16b",
  8520. [(set (v16i8 V128:$dst),
  8521. (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
  8522. (i32 vecshiftR8:$imm)))]> {
  8523. bits<3> imm;
  8524. let Inst{18-16} = imm;
  8525. }
  8526. def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
  8527. V64, V64, vecshiftR16, asm, ".4h", ".4h",
  8528. [(set (v4i16 V64:$dst),
  8529. (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
  8530. (i32 vecshiftR16:$imm)))]> {
  8531. bits<4> imm;
  8532. let Inst{19-16} = imm;
  8533. }
  8534. def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
  8535. V128, V128, vecshiftR16, asm, ".8h", ".8h",
  8536. [(set (v8i16 V128:$dst),
  8537. (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
  8538. (i32 vecshiftR16:$imm)))]> {
  8539. bits<4> imm;
  8540. let Inst{19-16} = imm;
  8541. }
  8542. def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
  8543. V64, V64, vecshiftR32, asm, ".2s", ".2s",
  8544. [(set (v2i32 V64:$dst),
  8545. (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
  8546. (i32 vecshiftR32:$imm)))]> {
  8547. bits<5> imm;
  8548. let Inst{20-16} = imm;
  8549. }
  8550. def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
  8551. V128, V128, vecshiftR32, asm, ".4s", ".4s",
  8552. [(set (v4i32 V128:$dst),
  8553. (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
  8554. (i32 vecshiftR32:$imm)))]> {
  8555. bits<5> imm;
  8556. let Inst{20-16} = imm;
  8557. }
  8558. def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
  8559. V128, V128, vecshiftR64,
  8560. asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
  8561. (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
  8562. (i32 vecshiftR64:$imm)))]> {
  8563. bits<6> imm;
  8564. let Inst{21-16} = imm;
  8565. }
  8566. }
  8567. multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
  8568. SDPatternOperator OpNode = null_frag> {
  8569. def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
  8570. V64, V64, vecshiftL8,
  8571. asm, ".8b", ".8b",
  8572. [(set (v8i8 V64:$dst),
  8573. (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
  8574. (i32 vecshiftL8:$imm)))]> {
  8575. bits<3> imm;
  8576. let Inst{18-16} = imm;
  8577. }
  8578. def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
  8579. V128, V128, vecshiftL8,
  8580. asm, ".16b", ".16b",
  8581. [(set (v16i8 V128:$dst),
  8582. (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
  8583. (i32 vecshiftL8:$imm)))]> {
  8584. bits<3> imm;
  8585. let Inst{18-16} = imm;
  8586. }
  8587. def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
  8588. V64, V64, vecshiftL16,
  8589. asm, ".4h", ".4h",
  8590. [(set (v4i16 V64:$dst),
  8591. (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
  8592. (i32 vecshiftL16:$imm)))]> {
  8593. bits<4> imm;
  8594. let Inst{19-16} = imm;
  8595. }
  8596. def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
  8597. V128, V128, vecshiftL16,
  8598. asm, ".8h", ".8h",
  8599. [(set (v8i16 V128:$dst),
  8600. (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
  8601. (i32 vecshiftL16:$imm)))]> {
  8602. bits<4> imm;
  8603. let Inst{19-16} = imm;
  8604. }
  8605. def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
  8606. V64, V64, vecshiftL32,
  8607. asm, ".2s", ".2s",
  8608. [(set (v2i32 V64:$dst),
  8609. (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
  8610. (i32 vecshiftL32:$imm)))]> {
  8611. bits<5> imm;
  8612. let Inst{20-16} = imm;
  8613. }
  8614. def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
  8615. V128, V128, vecshiftL32,
  8616. asm, ".4s", ".4s",
  8617. [(set (v4i32 V128:$dst),
  8618. (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
  8619. (i32 vecshiftL32:$imm)))]> {
  8620. bits<5> imm;
  8621. let Inst{20-16} = imm;
  8622. }
  8623. def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
  8624. V128, V128, vecshiftL64,
  8625. asm, ".2d", ".2d",
  8626. [(set (v2i64 V128:$dst),
  8627. (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
  8628. (i32 vecshiftL64:$imm)))]> {
  8629. bits<6> imm;
  8630. let Inst{21-16} = imm;
  8631. }
  8632. }
  8633. multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
  8634. SDPatternOperator OpNode> {
  8635. def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
  8636. V128, V64, vecshiftL8, asm, ".8h", ".8b",
  8637. [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
  8638. bits<3> imm;
  8639. let Inst{18-16} = imm;
  8640. }
  8641. def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
  8642. V128, V128, vecshiftL8,
  8643. asm#"2", ".8h", ".16b",
  8644. [(set (v8i16 V128:$Rd),
  8645. (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
  8646. bits<3> imm;
  8647. let Inst{18-16} = imm;
  8648. }
  8649. def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
  8650. V128, V64, vecshiftL16, asm, ".4s", ".4h",
  8651. [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
  8652. bits<4> imm;
  8653. let Inst{19-16} = imm;
  8654. }
  8655. def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
  8656. V128, V128, vecshiftL16,
  8657. asm#"2", ".4s", ".8h",
  8658. [(set (v4i32 V128:$Rd),
  8659. (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
  8660. bits<4> imm;
  8661. let Inst{19-16} = imm;
  8662. }
  8663. def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
  8664. V128, V64, vecshiftL32, asm, ".2d", ".2s",
  8665. [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
  8666. bits<5> imm;
  8667. let Inst{20-16} = imm;
  8668. }
  8669. def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
  8670. V128, V128, vecshiftL32,
  8671. asm#"2", ".2d", ".4s",
  8672. [(set (v2i64 V128:$Rd),
  8673. (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
  8674. bits<5> imm;
  8675. let Inst{20-16} = imm;
  8676. }
  8677. }
  8678. //---
  8679. // Vector load/store
  8680. //---
  8681. // SIMD ldX/stX no-index memory references don't allow the optional
  8682. // ", #0" constant and handle post-indexing explicitly, so we use
  8683. // a more specialized parse method for them. Otherwise, it's the same as
  8684. // the general GPR64sp handling.
  8685. class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
  8686. string asm, dag oops, dag iops, list<dag> pattern>
  8687. : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
  8688. bits<5> Vt;
  8689. bits<5> Rn;
  8690. let Inst{31} = 0;
  8691. let Inst{30} = Q;
  8692. let Inst{29-23} = 0b0011000;
  8693. let Inst{22} = L;
  8694. let Inst{21-16} = 0b000000;
  8695. let Inst{15-12} = opcode;
  8696. let Inst{11-10} = size;
  8697. let Inst{9-5} = Rn;
  8698. let Inst{4-0} = Vt;
  8699. }
  8700. class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
  8701. string asm, dag oops, dag iops>
  8702. : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
  8703. bits<5> Vt;
  8704. bits<5> Rn;
  8705. bits<5> Xm;
  8706. let Inst{31} = 0;
  8707. let Inst{30} = Q;
  8708. let Inst{29-23} = 0b0011001;
  8709. let Inst{22} = L;
  8710. let Inst{21} = 0;
  8711. let Inst{20-16} = Xm;
  8712. let Inst{15-12} = opcode;
  8713. let Inst{11-10} = size;
  8714. let Inst{9-5} = Rn;
  8715. let Inst{4-0} = Vt;
  8716. }
  8717. // The immediate form of AdvSIMD post-indexed addressing is encoded with
  8718. // register post-index addressing from the zero register.
  8719. multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count,
  8720. int Offset, int Size> {
  8721. // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
  8722. // "ld1\t$Vt, [$Rn], #16"
  8723. // may get mapped to
  8724. // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
  8725. def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
  8726. (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
  8727. GPR64sp:$Rn,
  8728. !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
  8729. XZR), 1>;
  8730. // E.g. "ld1.8b { v0, v1 }, [x1], #16"
  8731. // "ld1.8b\t$Vt, [$Rn], #16"
  8732. // may get mapped to
  8733. // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
  8734. def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
  8735. (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
  8736. GPR64sp:$Rn,
  8737. !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
  8738. XZR), 0>;
  8739. // E.g. "ld1.8b { v0, v1 }, [x1]"
  8740. // "ld1\t$Vt, [$Rn]"
  8741. // may get mapped to
  8742. // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
  8743. def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
  8744. (!cast<Instruction>(BaseName # Count # "v" # layout)
  8745. !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
  8746. GPR64sp:$Rn), 0>;
  8747. // E.g. "ld1.8b { v0, v1 }, [x1], x2"
  8748. // "ld1\t$Vt, [$Rn], $Xm"
  8749. // may get mapped to
  8750. // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
  8751. def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
  8752. (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
  8753. GPR64sp:$Rn,
  8754. !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
  8755. !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
  8756. }
  8757. multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist,
  8758. int Offset128, int Offset64, bits<4> opcode> {
  8759. let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
  8760. def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
  8761. (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
  8762. (ins GPR64sp:$Rn), []>;
  8763. def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
  8764. (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
  8765. (ins GPR64sp:$Rn), []>;
  8766. def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
  8767. (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
  8768. (ins GPR64sp:$Rn), []>;
  8769. def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
  8770. (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
  8771. (ins GPR64sp:$Rn), []>;
  8772. def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
  8773. (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
  8774. (ins GPR64sp:$Rn), []>;
  8775. def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
  8776. (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
  8777. (ins GPR64sp:$Rn), []>;
  8778. def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
  8779. (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
  8780. (ins GPR64sp:$Rn), []>;
  8781. def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
  8782. (outs GPR64sp:$wback,
  8783. !cast<RegisterOperand>(veclist # "16b"):$Vt),
  8784. (ins GPR64sp:$Rn,
  8785. !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
  8786. def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
  8787. (outs GPR64sp:$wback,
  8788. !cast<RegisterOperand>(veclist # "8h"):$Vt),
  8789. (ins GPR64sp:$Rn,
  8790. !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
  8791. def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
  8792. (outs GPR64sp:$wback,
  8793. !cast<RegisterOperand>(veclist # "4s"):$Vt),
  8794. (ins GPR64sp:$Rn,
  8795. !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
  8796. def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
  8797. (outs GPR64sp:$wback,
  8798. !cast<RegisterOperand>(veclist # "2d"):$Vt),
  8799. (ins GPR64sp:$Rn,
  8800. !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
  8801. def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
  8802. (outs GPR64sp:$wback,
  8803. !cast<RegisterOperand>(veclist # "8b"):$Vt),
  8804. (ins GPR64sp:$Rn,
  8805. !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
  8806. def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
  8807. (outs GPR64sp:$wback,
  8808. !cast<RegisterOperand>(veclist # "4h"):$Vt),
  8809. (ins GPR64sp:$Rn,
  8810. !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
  8811. def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
  8812. (outs GPR64sp:$wback,
  8813. !cast<RegisterOperand>(veclist # "2s"):$Vt),
  8814. (ins GPR64sp:$Rn,
  8815. !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
  8816. }
  8817. defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
  8818. defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
  8819. defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
  8820. defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
  8821. defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
  8822. defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
  8823. defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
  8824. }
  8825. // Only ld1/st1 has a v1d version.
  8826. multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist,
  8827. int Offset128, int Offset64, bits<4> opcode> {
  8828. let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
  8829. def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
  8830. (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
  8831. GPR64sp:$Rn), []>;
  8832. def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
  8833. (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
  8834. GPR64sp:$Rn), []>;
  8835. def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
  8836. (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
  8837. GPR64sp:$Rn), []>;
  8838. def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
  8839. (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
  8840. GPR64sp:$Rn), []>;
  8841. def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
  8842. (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
  8843. GPR64sp:$Rn), []>;
  8844. def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
  8845. (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
  8846. GPR64sp:$Rn), []>;
  8847. def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
  8848. (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
  8849. GPR64sp:$Rn), []>;
  8850. def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
  8851. (outs GPR64sp:$wback),
  8852. (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
  8853. GPR64sp:$Rn,
  8854. !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
  8855. def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
  8856. (outs GPR64sp:$wback),
  8857. (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
  8858. GPR64sp:$Rn,
  8859. !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
  8860. def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
  8861. (outs GPR64sp:$wback),
  8862. (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
  8863. GPR64sp:$Rn,
  8864. !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
  8865. def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
  8866. (outs GPR64sp:$wback),
  8867. (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
  8868. GPR64sp:$Rn,
  8869. !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
  8870. def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
  8871. (outs GPR64sp:$wback),
  8872. (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
  8873. GPR64sp:$Rn,
  8874. !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
  8875. def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
  8876. (outs GPR64sp:$wback),
  8877. (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
  8878. GPR64sp:$Rn,
  8879. !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
  8880. def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
  8881. (outs GPR64sp:$wback),
  8882. (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
  8883. GPR64sp:$Rn,
  8884. !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
  8885. }
  8886. defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
  8887. defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
  8888. defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
  8889. defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
  8890. defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
  8891. defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
  8892. defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
  8893. }
  8894. multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist,
  8895. int Offset128, int Offset64, bits<4> opcode>
  8896. : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
  8897. // LD1 instructions have extra "1d" variants.
  8898. let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
  8899. def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
  8900. (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
  8901. (ins GPR64sp:$Rn), []>;
  8902. def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
  8903. (outs GPR64sp:$wback,
  8904. !cast<RegisterOperand>(veclist # "1d"):$Vt),
  8905. (ins GPR64sp:$Rn,
  8906. !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
  8907. }
  8908. defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
  8909. }
  8910. multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist,
  8911. int Offset128, int Offset64, bits<4> opcode>
  8912. : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
  8913. // ST1 instructions have extra "1d" variants.
  8914. let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
  8915. def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
  8916. (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
  8917. GPR64sp:$Rn), []>;
  8918. def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
  8919. (outs GPR64sp:$wback),
  8920. (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
  8921. GPR64sp:$Rn,
  8922. !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
  8923. }
  8924. defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
  8925. }
  8926. multiclass SIMDLd1Multiple<string asm> {
  8927. defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;
  8928. defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
  8929. defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
  8930. defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
  8931. }
  8932. multiclass SIMDSt1Multiple<string asm> {
  8933. defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;
  8934. defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
  8935. defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
  8936. defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
  8937. }
  8938. multiclass SIMDLd2Multiple<string asm> {
  8939. defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
  8940. }
  8941. multiclass SIMDSt2Multiple<string asm> {
  8942. defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
  8943. }
  8944. multiclass SIMDLd3Multiple<string asm> {
  8945. defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
  8946. }
  8947. multiclass SIMDSt3Multiple<string asm> {
  8948. defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
  8949. }
  8950. multiclass SIMDLd4Multiple<string asm> {
  8951. defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
  8952. }
  8953. multiclass SIMDSt4Multiple<string asm> {
  8954. defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
  8955. }
  8956. //---
  8957. // AdvSIMD Load/store single-element
  8958. //---
  8959. class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
  8960. string asm, string operands, string cst,
  8961. dag oops, dag iops, list<dag> pattern>
  8962. : I<oops, iops, asm, operands, cst, pattern> {
  8963. bits<5> Vt;
  8964. bits<5> Rn;
  8965. let Inst{31} = 0;
  8966. let Inst{29-24} = 0b001101;
  8967. let Inst{22} = L;
  8968. let Inst{21} = R;
  8969. let Inst{15-13} = opcode;
  8970. let Inst{9-5} = Rn;
  8971. let Inst{4-0} = Vt;
  8972. }
  8973. class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
  8974. string asm, string operands, string cst,
  8975. dag oops, dag iops, list<dag> pattern>
  8976. : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
  8977. bits<5> Vt;
  8978. bits<5> Rn;
  8979. let Inst{31} = 0;
  8980. let Inst{29-24} = 0b001101;
  8981. let Inst{22} = L;
  8982. let Inst{21} = R;
  8983. let Inst{15-13} = opcode;
  8984. let Inst{9-5} = Rn;
  8985. let Inst{4-0} = Vt;
  8986. }
  8987. let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
  8988. class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
  8989. DAGOperand listtype>
  8990. : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
  8991. (outs listtype:$Vt), (ins GPR64sp:$Rn),
  8992. []> {
  8993. let Inst{30} = Q;
  8994. let Inst{23} = 0;
  8995. let Inst{20-16} = 0b00000;
  8996. let Inst{12} = S;
  8997. let Inst{11-10} = size;
  8998. }
  8999. let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
  9000. class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
  9001. string asm, DAGOperand listtype, DAGOperand GPR64pi>
  9002. : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
  9003. "$Rn = $wback",
  9004. (outs GPR64sp:$wback, listtype:$Vt),
  9005. (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
  9006. bits<5> Xm;
  9007. let Inst{30} = Q;
  9008. let Inst{23} = 1;
  9009. let Inst{20-16} = Xm;
  9010. let Inst{12} = S;
  9011. let Inst{11-10} = size;
  9012. }
  9013. multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count,
  9014. int Offset, int Size> {
  9015. // E.g. "ld1r { v0.8b }, [x1], #1"
  9016. // "ld1r.8b\t$Vt, [$Rn], #1"
  9017. // may get mapped to
  9018. // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
  9019. def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
  9020. (!cast<Instruction>(BaseName # "v" # layout # "_POST")
  9021. GPR64sp:$Rn,
  9022. !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
  9023. XZR), 1>;
  9024. // E.g. "ld1r.8b { v0 }, [x1], #1"
  9025. // "ld1r.8b\t$Vt, [$Rn], #1"
  9026. // may get mapped to
  9027. // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
  9028. def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
  9029. (!cast<Instruction>(BaseName # "v" # layout # "_POST")
  9030. GPR64sp:$Rn,
  9031. !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
  9032. XZR), 0>;
  9033. // E.g. "ld1r.8b { v0 }, [x1]"
  9034. // "ld1r.8b\t$Vt, [$Rn]"
  9035. // may get mapped to
  9036. // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
  9037. def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
  9038. (!cast<Instruction>(BaseName # "v" # layout)
  9039. !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
  9040. GPR64sp:$Rn), 0>;
  9041. // E.g. "ld1r.8b { v0 }, [x1], x2"
  9042. // "ld1r.8b\t$Vt, [$Rn], $Xm"
  9043. // may get mapped to
  9044. // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
  9045. def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
  9046. (!cast<Instruction>(BaseName # "v" # layout # "_POST")
  9047. GPR64sp:$Rn,
  9048. !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
  9049. !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
  9050. }
  9051. multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
  9052. int Offset1, int Offset2, int Offset4, int Offset8> {
  9053. def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
  9054. !cast<DAGOperand>("VecList" # Count # "8b")>;
  9055. def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
  9056. !cast<DAGOperand>("VecList" # Count #"16b")>;
  9057. def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
  9058. !cast<DAGOperand>("VecList" # Count #"4h")>;
  9059. def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
  9060. !cast<DAGOperand>("VecList" # Count #"8h")>;
  9061. def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
  9062. !cast<DAGOperand>("VecList" # Count #"2s")>;
  9063. def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
  9064. !cast<DAGOperand>("VecList" # Count #"4s")>;
  9065. def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
  9066. !cast<DAGOperand>("VecList" # Count #"1d")>;
  9067. def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
  9068. !cast<DAGOperand>("VecList" # Count #"2d")>;
  9069. def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
  9070. !cast<DAGOperand>("VecList" # Count # "8b"),
  9071. !cast<DAGOperand>("GPR64pi" # Offset1)>;
  9072. def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
  9073. !cast<DAGOperand>("VecList" # Count # "16b"),
  9074. !cast<DAGOperand>("GPR64pi" # Offset1)>;
  9075. def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
  9076. !cast<DAGOperand>("VecList" # Count # "4h"),
  9077. !cast<DAGOperand>("GPR64pi" # Offset2)>;
  9078. def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
  9079. !cast<DAGOperand>("VecList" # Count # "8h"),
  9080. !cast<DAGOperand>("GPR64pi" # Offset2)>;
  9081. def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
  9082. !cast<DAGOperand>("VecList" # Count # "2s"),
  9083. !cast<DAGOperand>("GPR64pi" # Offset4)>;
  9084. def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
  9085. !cast<DAGOperand>("VecList" # Count # "4s"),
  9086. !cast<DAGOperand>("GPR64pi" # Offset4)>;
  9087. def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
  9088. !cast<DAGOperand>("VecList" # Count # "1d"),
  9089. !cast<DAGOperand>("GPR64pi" # Offset8)>;
  9090. def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
  9091. !cast<DAGOperand>("VecList" # Count # "2d"),
  9092. !cast<DAGOperand>("GPR64pi" # Offset8)>;
  9093. defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>;
  9094. defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>;
  9095. defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>;
  9096. defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>;
  9097. defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>;
  9098. defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>;
  9099. defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>;
  9100. defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>;
  9101. }
  9102. class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
  9103. dag oops, dag iops, list<dag> pattern>
  9104. : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
  9105. pattern> {
  9106. // idx encoded in Q:S:size fields.
  9107. bits<4> idx;
  9108. let Inst{30} = idx{3};
  9109. let Inst{23} = 0;
  9110. let Inst{20-16} = 0b00000;
  9111. let Inst{12} = idx{2};
  9112. let Inst{11-10} = idx{1-0};
  9113. }
  9114. class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
  9115. dag oops, dag iops, list<dag> pattern>
  9116. : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
  9117. oops, iops, pattern> {
  9118. // idx encoded in Q:S:size fields.
  9119. bits<4> idx;
  9120. let Inst{30} = idx{3};
  9121. let Inst{23} = 0;
  9122. let Inst{20-16} = 0b00000;
  9123. let Inst{12} = idx{2};
  9124. let Inst{11-10} = idx{1-0};
  9125. }
  9126. class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
  9127. dag oops, dag iops>
  9128. : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
  9129. "$Rn = $wback", oops, iops, []> {
  9130. // idx encoded in Q:S:size fields.
  9131. bits<4> idx;
  9132. bits<5> Xm;
  9133. let Inst{30} = idx{3};
  9134. let Inst{23} = 1;
  9135. let Inst{20-16} = Xm;
  9136. let Inst{12} = idx{2};
  9137. let Inst{11-10} = idx{1-0};
  9138. }
  9139. class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
  9140. dag oops, dag iops>
  9141. : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
  9142. "$Rn = $wback", oops, iops, []> {
  9143. // idx encoded in Q:S:size fields.
  9144. bits<4> idx;
  9145. bits<5> Xm;
  9146. let Inst{30} = idx{3};
  9147. let Inst{23} = 1;
  9148. let Inst{20-16} = Xm;
  9149. let Inst{12} = idx{2};
  9150. let Inst{11-10} = idx{1-0};
  9151. }
  9152. class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
  9153. dag oops, dag iops, list<dag> pattern>
  9154. : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
  9155. pattern> {
  9156. // idx encoded in Q:S:size<1> fields.
  9157. bits<3> idx;
  9158. let Inst{30} = idx{2};
  9159. let Inst{23} = 0;
  9160. let Inst{20-16} = 0b00000;
  9161. let Inst{12} = idx{1};
  9162. let Inst{11} = idx{0};
  9163. let Inst{10} = size;
  9164. }
  9165. class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
  9166. dag oops, dag iops, list<dag> pattern>
  9167. : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
  9168. oops, iops, pattern> {
  9169. // idx encoded in Q:S:size<1> fields.
  9170. bits<3> idx;
  9171. let Inst{30} = idx{2};
  9172. let Inst{23} = 0;
  9173. let Inst{20-16} = 0b00000;
  9174. let Inst{12} = idx{1};
  9175. let Inst{11} = idx{0};
  9176. let Inst{10} = size;
  9177. }
  9178. class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
  9179. dag oops, dag iops>
  9180. : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
  9181. "$Rn = $wback", oops, iops, []> {
  9182. // idx encoded in Q:S:size<1> fields.
  9183. bits<3> idx;
  9184. bits<5> Xm;
  9185. let Inst{30} = idx{2};
  9186. let Inst{23} = 1;
  9187. let Inst{20-16} = Xm;
  9188. let Inst{12} = idx{1};
  9189. let Inst{11} = idx{0};
  9190. let Inst{10} = size;
  9191. }
  9192. class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
  9193. dag oops, dag iops>
  9194. : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
  9195. "$Rn = $wback", oops, iops, []> {
  9196. // idx encoded in Q:S:size<1> fields.
  9197. bits<3> idx;
  9198. bits<5> Xm;
  9199. let Inst{30} = idx{2};
  9200. let Inst{23} = 1;
  9201. let Inst{20-16} = Xm;
  9202. let Inst{12} = idx{1};
  9203. let Inst{11} = idx{0};
  9204. let Inst{10} = size;
  9205. }
  9206. class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
  9207. dag oops, dag iops, list<dag> pattern>
  9208. : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
  9209. pattern> {
  9210. // idx encoded in Q:S fields.
  9211. bits<2> idx;
  9212. let Inst{30} = idx{1};
  9213. let Inst{23} = 0;
  9214. let Inst{20-16} = 0b00000;
  9215. let Inst{12} = idx{0};
  9216. let Inst{11-10} = size;
  9217. }
  9218. class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
  9219. dag oops, dag iops, list<dag> pattern>
  9220. : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
  9221. oops, iops, pattern> {
  9222. // idx encoded in Q:S fields.
  9223. bits<2> idx;
  9224. let Inst{30} = idx{1};
  9225. let Inst{23} = 0;
  9226. let Inst{20-16} = 0b00000;
  9227. let Inst{12} = idx{0};
  9228. let Inst{11-10} = size;
  9229. }
  9230. class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
  9231. string asm, dag oops, dag iops>
  9232. : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
  9233. "$Rn = $wback", oops, iops, []> {
  9234. // idx encoded in Q:S fields.
  9235. bits<2> idx;
  9236. bits<5> Xm;
  9237. let Inst{30} = idx{1};
  9238. let Inst{23} = 1;
  9239. let Inst{20-16} = Xm;
  9240. let Inst{12} = idx{0};
  9241. let Inst{11-10} = size;
  9242. }
  9243. class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
  9244. string asm, dag oops, dag iops>
  9245. : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
  9246. "$Rn = $wback", oops, iops, []> {
  9247. // idx encoded in Q:S fields.
  9248. bits<2> idx;
  9249. bits<5> Xm;
  9250. let Inst{30} = idx{1};
  9251. let Inst{23} = 1;
  9252. let Inst{20-16} = Xm;
  9253. let Inst{12} = idx{0};
  9254. let Inst{11-10} = size;
  9255. }
  9256. class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
  9257. dag oops, dag iops, list<dag> pattern>
  9258. : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
  9259. pattern> {
  9260. // idx encoded in Q field.
  9261. bits<1> idx;
  9262. let Inst{30} = idx;
  9263. let Inst{23} = 0;
  9264. let Inst{20-16} = 0b00000;
  9265. let Inst{12} = 0;
  9266. let Inst{11-10} = size;
  9267. }
  9268. class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
  9269. dag oops, dag iops, list<dag> pattern>
  9270. : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
  9271. oops, iops, pattern> {
  9272. // idx encoded in Q field.
  9273. bits<1> idx;
  9274. let Inst{30} = idx;
  9275. let Inst{23} = 0;
  9276. let Inst{20-16} = 0b00000;
  9277. let Inst{12} = 0;
  9278. let Inst{11-10} = size;
  9279. }
  9280. class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
  9281. string asm, dag oops, dag iops>
  9282. : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
  9283. "$Rn = $wback", oops, iops, []> {
  9284. // idx encoded in Q field.
  9285. bits<1> idx;
  9286. bits<5> Xm;
  9287. let Inst{30} = idx;
  9288. let Inst{23} = 1;
  9289. let Inst{20-16} = Xm;
  9290. let Inst{12} = 0;
  9291. let Inst{11-10} = size;
  9292. }
  9293. class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
  9294. string asm, dag oops, dag iops>
  9295. : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
  9296. "$Rn = $wback", oops, iops, []> {
  9297. // idx encoded in Q field.
  9298. bits<1> idx;
  9299. bits<5> Xm;
  9300. let Inst{30} = idx;
  9301. let Inst{23} = 1;
  9302. let Inst{20-16} = Xm;
  9303. let Inst{12} = 0;
  9304. let Inst{11-10} = size;
  9305. }
  9306. let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
  9307. multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
  9308. RegisterOperand listtype,
  9309. RegisterOperand GPR64pi> {
  9310. def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
  9311. (outs listtype:$dst),
  9312. (ins listtype:$Vt, VectorIndexB:$idx,
  9313. GPR64sp:$Rn), []>;
  9314. def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
  9315. (outs GPR64sp:$wback, listtype:$dst),
  9316. (ins listtype:$Vt, VectorIndexB:$idx,
  9317. GPR64sp:$Rn, GPR64pi:$Xm)>;
  9318. }
  9319. let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
  9320. multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
  9321. RegisterOperand listtype,
  9322. RegisterOperand GPR64pi> {
  9323. def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
  9324. (outs listtype:$dst),
  9325. (ins listtype:$Vt, VectorIndexH:$idx,
  9326. GPR64sp:$Rn), []>;
  9327. def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
  9328. (outs GPR64sp:$wback, listtype:$dst),
  9329. (ins listtype:$Vt, VectorIndexH:$idx,
  9330. GPR64sp:$Rn, GPR64pi:$Xm)>;
  9331. }
  9332. let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
  9333. multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
  9334. RegisterOperand listtype,
  9335. RegisterOperand GPR64pi> {
  9336. def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
  9337. (outs listtype:$dst),
  9338. (ins listtype:$Vt, VectorIndexS:$idx,
  9339. GPR64sp:$Rn), []>;
  9340. def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
  9341. (outs GPR64sp:$wback, listtype:$dst),
  9342. (ins listtype:$Vt, VectorIndexS:$idx,
  9343. GPR64sp:$Rn, GPR64pi:$Xm)>;
  9344. }
  9345. let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
  9346. multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
  9347. RegisterOperand listtype, RegisterOperand GPR64pi> {
  9348. def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
  9349. (outs listtype:$dst),
  9350. (ins listtype:$Vt, VectorIndexD:$idx,
  9351. GPR64sp:$Rn), []>;
  9352. def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
  9353. (outs GPR64sp:$wback, listtype:$dst),
  9354. (ins listtype:$Vt, VectorIndexD:$idx,
  9355. GPR64sp:$Rn, GPR64pi:$Xm)>;
  9356. }
  9357. let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
  9358. multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
  9359. RegisterOperand listtype, RegisterOperand GPR64pi> {
  9360. def i8 : SIMDLdStSingleB<0, R, opcode, asm,
  9361. (outs), (ins listtype:$Vt, VectorIndexB:$idx,
  9362. GPR64sp:$Rn), []>;
  9363. def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
  9364. (outs GPR64sp:$wback),
  9365. (ins listtype:$Vt, VectorIndexB:$idx,
  9366. GPR64sp:$Rn, GPR64pi:$Xm)>;
  9367. }
  9368. let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
  9369. multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
  9370. RegisterOperand listtype, RegisterOperand GPR64pi> {
  9371. def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
  9372. (outs), (ins listtype:$Vt, VectorIndexH:$idx,
  9373. GPR64sp:$Rn), []>;
  9374. def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
  9375. (outs GPR64sp:$wback),
  9376. (ins listtype:$Vt, VectorIndexH:$idx,
  9377. GPR64sp:$Rn, GPR64pi:$Xm)>;
  9378. }
  9379. let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
  9380. multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
  9381. RegisterOperand listtype, RegisterOperand GPR64pi> {
  9382. def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
  9383. (outs), (ins listtype:$Vt, VectorIndexS:$idx,
  9384. GPR64sp:$Rn), []>;
  9385. def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
  9386. (outs GPR64sp:$wback),
  9387. (ins listtype:$Vt, VectorIndexS:$idx,
  9388. GPR64sp:$Rn, GPR64pi:$Xm)>;
  9389. }
  9390. let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
  9391. multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
  9392. RegisterOperand listtype, RegisterOperand GPR64pi> {
  9393. def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
  9394. (outs), (ins listtype:$Vt, VectorIndexD:$idx,
  9395. GPR64sp:$Rn), []>;
  9396. def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
  9397. (outs GPR64sp:$wback),
  9398. (ins listtype:$Vt, VectorIndexD:$idx,
  9399. GPR64sp:$Rn, GPR64pi:$Xm)>;
  9400. }
  9401. multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
  9402. string Count, int Offset, Operand idxtype> {
  9403. // E.g. "ld1 { v0.8b }[0], [x1], #1"
  9404. // "ld1\t$Vt, [$Rn], #1"
  9405. // may get mapped to
  9406. // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
  9407. def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
  9408. (!cast<Instruction>(NAME # Type # "_POST")
  9409. GPR64sp:$Rn,
  9410. !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
  9411. idxtype:$idx, XZR), 1>;
  9412. // E.g. "ld1.8b { v0 }[0], [x1], #1"
  9413. // "ld1.8b\t$Vt, [$Rn], #1"
  9414. // may get mapped to
  9415. // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
  9416. def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
  9417. (!cast<Instruction>(NAME # Type # "_POST")
  9418. GPR64sp:$Rn,
  9419. !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
  9420. idxtype:$idx, XZR), 0>;
  9421. // E.g. "ld1.8b { v0 }[0], [x1]"
  9422. // "ld1.8b\t$Vt, [$Rn]"
  9423. // may get mapped to
  9424. // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
  9425. def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
  9426. (!cast<Instruction>(NAME # Type)
  9427. !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
  9428. idxtype:$idx, GPR64sp:$Rn), 0>;
  9429. // E.g. "ld1.8b { v0 }[0], [x1], x2"
  9430. // "ld1.8b\t$Vt, [$Rn], $Xm"
  9431. // may get mapped to
  9432. // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
  9433. def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
  9434. (!cast<Instruction>(NAME # Type # "_POST")
  9435. GPR64sp:$Rn,
  9436. !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
  9437. idxtype:$idx,
  9438. !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
  9439. }
  9440. multiclass SIMDLdSt1SingleAliases<string asm> {
  9441. defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
  9442. defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
  9443. defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
  9444. defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
  9445. }
  9446. multiclass SIMDLdSt2SingleAliases<string asm> {
  9447. defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
  9448. defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
  9449. defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
  9450. defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
  9451. }
  9452. multiclass SIMDLdSt3SingleAliases<string asm> {
  9453. defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
  9454. defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
  9455. defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
  9456. defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
  9457. }
  9458. multiclass SIMDLdSt4SingleAliases<string asm> {
  9459. defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
  9460. defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
  9461. defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
  9462. defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
  9463. }
  9464. } // end of 'let Predicates = [HasNEON]'
  9465. //----------------------------------------------------------------------------
  9466. // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
  9467. //----------------------------------------------------------------------------
  9468. let Predicates = [HasNEON, HasRDM] in {
  9469. class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
  9470. RegisterOperand regtype, string asm,
  9471. string kind, list<dag> pattern>
  9472. : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
  9473. pattern> {
  9474. }
  9475. multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
  9476. SDPatternOperator op> {
  9477. def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
  9478. [(set (v4i16 V64:$dst),
  9479. (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
  9480. def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
  9481. [(set (v8i16 V128:$dst),
  9482. (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
  9483. def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
  9484. [(set (v2i32 V64:$dst),
  9485. (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
  9486. def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
  9487. [(set (v4i32 V128:$dst),
  9488. (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
  9489. }
  9490. multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
  9491. SDPatternOperator op> {
  9492. def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
  9493. V64, V64, V128_lo, VectorIndexH,
  9494. asm, ".4h", ".4h", ".4h", ".h",
  9495. [(set (v4i16 V64:$dst),
  9496. (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn),
  9497. (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
  9498. VectorIndexH:$idx)))))]> {
  9499. bits<3> idx;
  9500. let Inst{11} = idx{2};
  9501. let Inst{21} = idx{1};
  9502. let Inst{20} = idx{0};
  9503. }
  9504. def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
  9505. V128, V128, V128_lo, VectorIndexH,
  9506. asm, ".8h", ".8h", ".8h", ".h",
  9507. [(set (v8i16 V128:$dst),
  9508. (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn),
  9509. (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
  9510. VectorIndexH:$idx)))))]> {
  9511. bits<3> idx;
  9512. let Inst{11} = idx{2};
  9513. let Inst{21} = idx{1};
  9514. let Inst{20} = idx{0};
  9515. }
  9516. def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
  9517. V64, V64, V128, VectorIndexS,
  9518. asm, ".2s", ".2s", ".2s", ".s",
  9519. [(set (v2i32 V64:$dst),
  9520. (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn),
  9521. (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
  9522. VectorIndexS:$idx)))))]> {
  9523. bits<2> idx;
  9524. let Inst{11} = idx{1};
  9525. let Inst{21} = idx{0};
  9526. }
  9527. def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
  9528. V128, V128, V128, VectorIndexS,
  9529. asm, ".4s", ".4s", ".4s", ".s",
  9530. [(set (v4i32 V128:$dst),
  9531. (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn),
  9532. (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
  9533. VectorIndexS:$idx)))))]> {
  9534. bits<2> idx;
  9535. let Inst{11} = idx{1};
  9536. let Inst{21} = idx{0};
  9537. }
  9538. def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
  9539. FPR16Op, FPR16Op, V128_lo,
  9540. VectorIndexH, asm, ".h", "", "", ".h",
  9541. []> {
  9542. bits<3> idx;
  9543. let Inst{11} = idx{2};
  9544. let Inst{21} = idx{1};
  9545. let Inst{20} = idx{0};
  9546. }
  9547. def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
  9548. FPR32Op, FPR32Op, V128, VectorIndexS,
  9549. asm, ".s", "", "", ".s",
  9550. [(set (i32 FPR32Op:$dst),
  9551. (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn),
  9552. (i32 (vector_extract (v4i32 V128:$Rm),
  9553. VectorIndexS:$idx)))))]> {
  9554. bits<2> idx;
  9555. let Inst{11} = idx{1};
  9556. let Inst{21} = idx{0};
  9557. }
  9558. }
  9559. } // let Predicates = [HasNeon, HasRDM]
  9560. //----------------------------------------------------------------------------
  9561. // ARMv8.3 Complex ADD/MLA instructions
  9562. //----------------------------------------------------------------------------
  9563. class ComplexRotationOperand<int Angle, int Remainder, string Type>
  9564. : AsmOperandClass {
  9565. let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
  9566. let DiagnosticType = "InvalidComplexRotation" # Type;
  9567. let Name = "ComplexRotation" # Type;
  9568. }
  9569. def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }],
  9570. SDNodeXForm<imm, [{
  9571. return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32);
  9572. }]>> {
  9573. let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
  9574. let PrintMethod = "printComplexRotationOp<90, 0>";
  9575. }
  9576. def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }],
  9577. SDNodeXForm<imm, [{
  9578. return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32);
  9579. }]>> {
  9580. let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
  9581. let PrintMethod = "printComplexRotationOp<180, 90>";
  9582. }
  9583. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  9584. class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,
  9585. RegisterOperand regtype, Operand rottype,
  9586. string asm, string kind, list<dag> pattern>
  9587. : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
  9588. "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
  9589. "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>,
  9590. Sched<[!if(Q, WriteVq, WriteVd)]> {
  9591. bits<5> Rd;
  9592. bits<5> Rn;
  9593. bits<5> Rm;
  9594. bits<1> rot;
  9595. let Inst{31} = 0;
  9596. let Inst{30} = Q;
  9597. let Inst{29} = U;
  9598. let Inst{28-24} = 0b01110;
  9599. let Inst{23-22} = size;
  9600. let Inst{21} = 0;
  9601. let Inst{20-16} = Rm;
  9602. let Inst{15-13} = opcode;
  9603. // Non-tied version (FCADD) only has one rotation bit
  9604. let Inst{12} = rot;
  9605. let Inst{11} = 0;
  9606. let Inst{10} = 1;
  9607. let Inst{9-5} = Rn;
  9608. let Inst{4-0} = Rd;
  9609. }
  9610. //8.3 CompNum - Floating-point complex number support
  9611. multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
  9612. string asm, SDPatternOperator OpNode>{
  9613. let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
  9614. def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype,
  9615. asm, ".4h",
  9616. [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
  9617. (v4f16 V64:$Rn),
  9618. (v4f16 V64:$Rm),
  9619. (i32 rottype:$rot)))]>;
  9620. def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
  9621. asm, ".8h",
  9622. [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
  9623. (v8f16 V128:$Rn),
  9624. (v8f16 V128:$Rm),
  9625. (i32 rottype:$rot)))]>;
  9626. }
  9627. let Predicates = [HasComplxNum, HasNEON] in {
  9628. def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,
  9629. asm, ".2s",
  9630. [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
  9631. (v2f32 V64:$Rn),
  9632. (v2f32 V64:$Rm),
  9633. (i32 rottype:$rot)))]>;
  9634. def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
  9635. asm, ".4s",
  9636. [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
  9637. (v4f32 V128:$Rn),
  9638. (v4f32 V128:$Rm),
  9639. (i32 rottype:$rot)))]>;
  9640. def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
  9641. asm, ".2d",
  9642. [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
  9643. (v2f64 V128:$Rn),
  9644. (v2f64 V128:$Rm),
  9645. (i32 rottype:$rot)))]>;
  9646. }
  9647. }
  9648. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  9649. class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,
  9650. bits<3> opcode,
  9651. RegisterOperand regtype,
  9652. Operand rottype, string asm,
  9653. string kind, list<dag> pattern>
  9654. : I<(outs regtype:$dst),
  9655. (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
  9656. "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
  9657. "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>,
  9658. Sched<[!if(Q, WriteVq, WriteVd)]> {
  9659. bits<5> Rd;
  9660. bits<5> Rn;
  9661. bits<5> Rm;
  9662. bits<2> rot;
  9663. let Inst{31} = 0;
  9664. let Inst{30} = Q;
  9665. let Inst{29} = U;
  9666. let Inst{28-24} = 0b01110;
  9667. let Inst{23-22} = size;
  9668. let Inst{21} = 0;
  9669. let Inst{20-16} = Rm;
  9670. let Inst{15-13} = opcode;
  9671. let Inst{12-11} = rot;
  9672. let Inst{10} = 1;
  9673. let Inst{9-5} = Rn;
  9674. let Inst{4-0} = Rd;
  9675. }
  9676. multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
  9677. Operand rottype, string asm,
  9678. SDPatternOperator OpNode> {
  9679. let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
  9680. def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64,
  9681. rottype, asm, ".4h",
  9682. [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
  9683. (v4f16 V64:$Rn),
  9684. (v4f16 V64:$Rm),
  9685. (i32 rottype:$rot)))]>;
  9686. def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,
  9687. rottype, asm, ".8h",
  9688. [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
  9689. (v8f16 V128:$Rn),
  9690. (v8f16 V128:$Rm),
  9691. (i32 rottype:$rot)))]>;
  9692. }
  9693. let Predicates = [HasComplxNum, HasNEON] in {
  9694. def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64,
  9695. rottype, asm, ".2s",
  9696. [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
  9697. (v2f32 V64:$Rn),
  9698. (v2f32 V64:$Rm),
  9699. (i32 rottype:$rot)))]>;
  9700. def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,
  9701. rottype, asm, ".4s",
  9702. [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
  9703. (v4f32 V128:$Rn),
  9704. (v4f32 V128:$Rm),
  9705. (i32 rottype:$rot)))]>;
  9706. def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,
  9707. rottype, asm, ".2d",
  9708. [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
  9709. (v2f64 V128:$Rn),
  9710. (v2f64 V128:$Rm),
  9711. (i32 rottype:$rot)))]>;
  9712. }
  9713. }
  9714. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  9715. class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size,
  9716. bit opc1, bit opc2, RegisterOperand dst_reg,
  9717. RegisterOperand lhs_reg,
  9718. RegisterOperand rhs_reg, Operand vec_idx,
  9719. Operand rottype, string asm, string apple_kind,
  9720. string dst_kind, string lhs_kind,
  9721. string rhs_kind, list<dag> pattern>
  9722. : I<(outs dst_reg:$dst),
  9723. (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot),
  9724. asm,
  9725. "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind #
  9726. "$idx, $rot" # "|" # apple_kind #
  9727. "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>,
  9728. Sched<[!if(Q, WriteVq, WriteVd)]> {
  9729. bits<5> Rd;
  9730. bits<5> Rn;
  9731. bits<5> Rm;
  9732. bits<2> rot;
  9733. let Inst{31} = 0;
  9734. let Inst{30} = Q;
  9735. let Inst{29} = U;
  9736. let Inst{28} = Scalar;
  9737. let Inst{27-24} = 0b1111;
  9738. let Inst{23-22} = size;
  9739. // Bit 21 must be set by the derived class.
  9740. let Inst{20-16} = Rm;
  9741. let Inst{15} = opc1;
  9742. let Inst{14-13} = rot;
  9743. let Inst{12} = opc2;
  9744. // Bit 11 must be set by the derived class.
  9745. let Inst{10} = 0;
  9746. let Inst{9-5} = Rn;
  9747. let Inst{4-0} = Rd;
  9748. }
  9749. // The complex instructions index by pairs of elements, so the VectorIndexes
  9750. // don't match the lane types, and the index bits are different to the other
  9751. // classes.
  9752. multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype,
  9753. string asm> {
  9754. let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
  9755. def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64,
  9756. V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h",
  9757. ".4h", ".h", []> {
  9758. bits<1> idx;
  9759. let Inst{11} = 0;
  9760. let Inst{21} = idx{0};
  9761. }
  9762. def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,
  9763. V128, V128, V128, VectorIndexS, rottype, asm, ".8h",
  9764. ".8h", ".8h", ".h", []> {
  9765. bits<2> idx;
  9766. let Inst{11} = idx{1};
  9767. let Inst{21} = idx{0};
  9768. }
  9769. } // Predicates = HasComplxNum, HasNEON, HasFullFP16]
  9770. let Predicates = [HasComplxNum, HasNEON] in {
  9771. def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2,
  9772. V128, V128, V128, VectorIndexD, rottype, asm, ".4s",
  9773. ".4s", ".4s", ".s", []> {
  9774. bits<1> idx;
  9775. let Inst{11} = idx{0};
  9776. let Inst{21} = 0;
  9777. }
  9778. } // Predicates = [HasComplxNum, HasNEON]
  9779. }
  9780. //----------------------------------------------------------------------------
  9781. // Crypto extensions
  9782. //----------------------------------------------------------------------------
  9783. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  9784. class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
  9785. list<dag> pat>
  9786. : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
  9787. Sched<[WriteVq]>{
  9788. bits<5> Rd;
  9789. bits<5> Rn;
  9790. let Inst{31-16} = 0b0100111000101000;
  9791. let Inst{15-12} = opc;
  9792. let Inst{11-10} = 0b10;
  9793. let Inst{9-5} = Rn;
  9794. let Inst{4-0} = Rd;
  9795. }
  9796. class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
  9797. : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
  9798. [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
  9799. class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
  9800. : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
  9801. "$Rd = $dst",
  9802. [(set (v16i8 V128:$dst),
  9803. (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
  9804. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  9805. class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
  9806. dag oops, dag iops, list<dag> pat>
  9807. : I<oops, iops, asm,
  9808. "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
  9809. "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
  9810. Sched<[WriteVq]>{
  9811. bits<5> Rd;
  9812. bits<5> Rn;
  9813. bits<5> Rm;
  9814. let Inst{31-21} = 0b01011110000;
  9815. let Inst{20-16} = Rm;
  9816. let Inst{15} = 0;
  9817. let Inst{14-12} = opc;
  9818. let Inst{11-10} = 0b00;
  9819. let Inst{9-5} = Rn;
  9820. let Inst{4-0} = Rd;
  9821. }
  9822. class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
  9823. : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
  9824. (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
  9825. [(set (v4i32 FPR128:$dst),
  9826. (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
  9827. (v4i32 V128:$Rm)))]>;
  9828. class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
  9829. : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
  9830. (ins V128:$Rd, V128:$Rn, V128:$Rm),
  9831. [(set (v4i32 V128:$dst),
  9832. (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
  9833. (v4i32 V128:$Rm)))]>;
  9834. class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
  9835. : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
  9836. (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
  9837. [(set (v4i32 FPR128:$dst),
  9838. (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
  9839. (v4i32 V128:$Rm)))]>;
  9840. let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
  9841. class SHA2OpInst<bits<4> opc, string asm, string kind,
  9842. string cstr, dag oops, dag iops,
  9843. list<dag> pat>
  9844. : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
  9845. "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
  9846. Sched<[WriteVq]>{
  9847. bits<5> Rd;
  9848. bits<5> Rn;
  9849. let Inst{31-16} = 0b0101111000101000;
  9850. let Inst{15-12} = opc;
  9851. let Inst{11-10} = 0b10;
  9852. let Inst{9-5} = Rn;
  9853. let Inst{4-0} = Rd;
  9854. }
  9855. class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
  9856. : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
  9857. (ins V128:$Rd, V128:$Rn),
  9858. [(set (v4i32 V128:$dst),
  9859. (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
  9860. class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
  9861. : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
  9862. [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
  9863. // Armv8.2-A Crypto extensions
  9864. class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst,
  9865. list<dag> pattern>
  9866. : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> {
  9867. bits<5> Vd;
  9868. bits<5> Vn;
  9869. let Inst{31-25} = 0b1100111;
  9870. let Inst{9-5} = Vn;
  9871. let Inst{4-0} = Vd;
  9872. }
  9873. class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops>
  9874. : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops,
  9875. "$Vd = $Vdst", []> {
  9876. let Inst{31-25} = 0b1100111;
  9877. let Inst{24-21} = 0b0110;
  9878. let Inst{20-15} = 0b000001;
  9879. let Inst{14} = op0;
  9880. let Inst{13-12} = 0b00;
  9881. let Inst{11-10} = op1;
  9882. }
  9883. class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm>
  9884. : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">;
  9885. class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm>
  9886. : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">;
  9887. class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm,
  9888. string asmops, string cst>
  9889. : BaseCryptoV82<oops, iops, asm , asmops, cst, []> {
  9890. bits<5> Vm;
  9891. let Inst{24-21} = 0b0011;
  9892. let Inst{20-16} = Vm;
  9893. let Inst{15} = 0b1;
  9894. let Inst{14} = op0;
  9895. let Inst{13-12} = 0b00;
  9896. let Inst{11-10} = op1;
  9897. }
  9898. class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm>
  9899. : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
  9900. "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">;
  9901. class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm>
  9902. : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
  9903. "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
  9904. class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm>
  9905. : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
  9906. "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">;
  9907. class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm>
  9908. : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
  9909. "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
  9910. class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm>
  9911. : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm),
  9912. asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;
  9913. class CryptoRRRR<bits<2>op0, string asm, string asmops>
  9914. : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm,
  9915. asmops, "", []> {
  9916. bits<5> Vm;
  9917. bits<5> Va;
  9918. let Inst{24-23} = 0b00;
  9919. let Inst{22-21} = op0;
  9920. let Inst{20-16} = Vm;
  9921. let Inst{15} = 0b0;
  9922. let Inst{14-10} = Va;
  9923. }
  9924. class CryptoRRRR_16B<bits<2>op0, string asm>
  9925. : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" #
  9926. "|.16b\t$Vd, $Vn, $Vm, $Va}"> {
  9927. }
  9928. class CryptoRRRR_4S<bits<2>op0, string asm>
  9929. : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" #
  9930. "|.4s\t$Vd, $Vn, $Vm, $Va}"> {
  9931. }
  9932. class CryptoRRRi6<string asm>
  9933. : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm,
  9934. "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" #
  9935. "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> {
  9936. bits<6> imm;
  9937. bits<5> Vm;
  9938. let Inst{24-21} = 0b0100;
  9939. let Inst{20-16} = Vm;
  9940. let Inst{15-10} = imm;
  9941. let Inst{9-5} = Vn;
  9942. let Inst{4-0} = Vd;
  9943. }
  9944. class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm>
  9945. : BaseCryptoV82<(outs V128:$Vdst),
  9946. (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm),
  9947. asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" #
  9948. "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> {
  9949. bits<2> imm;
  9950. bits<5> Vm;
  9951. let Inst{24-21} = 0b0010;
  9952. let Inst{20-16} = Vm;
  9953. let Inst{15} = 0b1;
  9954. let Inst{14} = op0;
  9955. let Inst{13-12} = imm;
  9956. let Inst{11-10} = op1;
  9957. }
  9958. //----------------------------------------------------------------------------
  9959. // v8.1 atomic instructions extension:
  9960. // * CAS
  9961. // * CASP
  9962. // * SWP
  9963. // * LDOPregister<OP>, and aliases STOPregister<OP>
  9964. // Instruction encodings:
  9965. //
  9966. // 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
  9967. // CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
  9968. // CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
  9969. // SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
  9970. // LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
  9971. // ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
  9972. // Instruction syntax:
  9973. //
  9974. // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
  9975. // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
  9976. // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
  9977. // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
  9978. // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
  9979. // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
  9980. // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
  9981. // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
  9982. // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
  9983. // ST<OP>{<order>} <Xs>, [<Xn|SP>]
  9984. let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
  9985. class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
  9986. string cstr, list<dag> pattern>
  9987. : I<oops, iops, asm, operands, cstr, pattern> {
  9988. bits<2> Sz;
  9989. bit NP;
  9990. bit Acq;
  9991. bit Rel;
  9992. bits<5> Rs;
  9993. bits<5> Rn;
  9994. bits<5> Rt;
  9995. let Inst{31-30} = Sz;
  9996. let Inst{29-24} = 0b001000;
  9997. let Inst{23} = NP;
  9998. let Inst{22} = Acq;
  9999. let Inst{21} = 0b1;
  10000. let Inst{20-16} = Rs;
  10001. let Inst{15} = Rel;
  10002. let Inst{14-10} = 0b11111;
  10003. let Inst{9-5} = Rn;
  10004. let Inst{4-0} = Rt;
  10005. let Predicates = [HasLSE];
  10006. }
  10007. class BaseCAS<string order, string size, RegisterClass RC>
  10008. : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
  10009. "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
  10010. "$out = $Rs",[]>,
  10011. Sched<[WriteAtomic]> {
  10012. let NP = 1;
  10013. }
  10014. multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
  10015. let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>;
  10016. let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>;
  10017. let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>;
  10018. let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>;
  10019. }
  10020. class BaseCASP<string order, string size, RegisterOperand RC>
  10021. : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
  10022. "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
  10023. "$out = $Rs",[]>,
  10024. Sched<[WriteAtomic]> {
  10025. let NP = 0;
  10026. }
  10027. multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
  10028. let Sz = 0b00, Acq = Acq, Rel = Rel in
  10029. def W : BaseCASP<order, "", WSeqPairClassOperand>;
  10030. let Sz = 0b01, Acq = Acq, Rel = Rel in
  10031. def X : BaseCASP<order, "", XSeqPairClassOperand>;
  10032. }
  10033. let Predicates = [HasLSE] in
  10034. class BaseSWP<string order, string size, RegisterClass RC>
  10035. : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
  10036. "\t$Rs, $Rt, [$Rn]","",[]>,
  10037. Sched<[WriteAtomic]> {
  10038. bits<2> Sz;
  10039. bit Acq;
  10040. bit Rel;
  10041. bits<5> Rs;
  10042. bits<3> opc = 0b000;
  10043. bits<5> Rn;
  10044. bits<5> Rt;
  10045. let Inst{31-30} = Sz;
  10046. let Inst{29-24} = 0b111000;
  10047. let Inst{23} = Acq;
  10048. let Inst{22} = Rel;
  10049. let Inst{21} = 0b1;
  10050. let Inst{20-16} = Rs;
  10051. let Inst{15} = 0b1;
  10052. let Inst{14-12} = opc;
  10053. let Inst{11-10} = 0b00;
  10054. let Inst{9-5} = Rn;
  10055. let Inst{4-0} = Rt;
  10056. let Predicates = [HasLSE];
  10057. }
  10058. multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
  10059. let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>;
  10060. let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>;
  10061. let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>;
  10062. let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>;
  10063. }
  10064. let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
  10065. class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
  10066. : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
  10067. "\t$Rs, $Rt, [$Rn]","",[]>,
  10068. Sched<[WriteAtomic]> {
  10069. bits<2> Sz;
  10070. bit Acq;
  10071. bit Rel;
  10072. bits<5> Rs;
  10073. bits<3> opc;
  10074. bits<5> Rn;
  10075. bits<5> Rt;
  10076. let Inst{31-30} = Sz;
  10077. let Inst{29-24} = 0b111000;
  10078. let Inst{23} = Acq;
  10079. let Inst{22} = Rel;
  10080. let Inst{21} = 0b1;
  10081. let Inst{20-16} = Rs;
  10082. let Inst{15} = 0b0;
  10083. let Inst{14-12} = opc;
  10084. let Inst{11-10} = 0b00;
  10085. let Inst{9-5} = Rn;
  10086. let Inst{4-0} = Rt;
  10087. let Predicates = [HasLSE];
  10088. }
  10089. multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
  10090. string order> {
  10091. let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
  10092. def B : BaseLDOPregister<op, order, "b", GPR32>;
  10093. let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
  10094. def H : BaseLDOPregister<op, order, "h", GPR32>;
  10095. let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
  10096. def W : BaseLDOPregister<op, order, "", GPR32>;
  10097. let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
  10098. def X : BaseLDOPregister<op, order, "", GPR64>;
  10099. }
  10100. // Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more
  10101. // complex DAG for DstRHS.
  10102. let Predicates = [HasLSE] in
  10103. multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
  10104. string size, dag SrcRHS, dag DstRHS> {
  10105. def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
  10106. (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
  10107. def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
  10108. (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
  10109. def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
  10110. (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
  10111. def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
  10112. (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
  10113. def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
  10114. (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
  10115. }
  10116. multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,
  10117. string size, dag RHS> {
  10118. defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>;
  10119. }
  10120. multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,
  10121. string size, dag LHS, dag RHS> {
  10122. defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>;
  10123. }
  10124. multiclass LDOPregister_patterns<string inst, string op> {
  10125. defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>;
  10126. defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>;
  10127. defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>;
  10128. defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>;
  10129. }
  10130. multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
  10131. defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64",
  10132. (i64 GPR64:$Rm),
  10133. (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;
  10134. defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32",
  10135. (i32 GPR32:$Rm),
  10136. (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
  10137. defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16",
  10138. (i32 GPR32:$Rm),
  10139. (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
  10140. defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8",
  10141. (i32 GPR32:$Rm),
  10142. (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
  10143. }
  10144. let Predicates = [HasLSE] in
  10145. multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
  10146. string size, dag OLD, dag NEW> {
  10147. def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
  10148. (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
  10149. def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
  10150. (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
  10151. def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
  10152. (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
  10153. def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
  10154. (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
  10155. def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
  10156. (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
  10157. }
  10158. multiclass CASregister_patterns_ord<string inst, string suffix, string op,
  10159. string size, dag OLD, dag NEW> {
  10160. defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>;
  10161. }
  10162. multiclass CASregister_patterns<string inst, string op> {
  10163. defm : CASregister_patterns_ord<inst, "X", op, "64",
  10164. (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>;
  10165. defm : CASregister_patterns_ord<inst, "W", op, "32",
  10166. (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
  10167. defm : CASregister_patterns_ord<inst, "H", op, "16",
  10168. (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
  10169. defm : CASregister_patterns_ord<inst, "B", op, "8",
  10170. (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
  10171. }
  10172. let Predicates = [HasLSE] in
  10173. class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
  10174. Instruction inst> :
  10175. InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
  10176. multiclass STOPregister<string asm, string instr> {
  10177. def : BaseSTOPregister<asm # "lb", GPR32, WZR,
  10178. !cast<Instruction>(instr # "LB")>;
  10179. def : BaseSTOPregister<asm # "lh", GPR32, WZR,
  10180. !cast<Instruction>(instr # "LH")>;
  10181. def : BaseSTOPregister<asm # "l", GPR32, WZR,
  10182. !cast<Instruction>(instr # "LW")>;
  10183. def : BaseSTOPregister<asm # "l", GPR64, XZR,
  10184. !cast<Instruction>(instr # "LX")>;
  10185. def : BaseSTOPregister<asm # "b", GPR32, WZR,
  10186. !cast<Instruction>(instr # "B")>;
  10187. def : BaseSTOPregister<asm # "h", GPR32, WZR,
  10188. !cast<Instruction>(instr # "H")>;
  10189. def : BaseSTOPregister<asm, GPR32, WZR,
  10190. !cast<Instruction>(instr # "W")>;
  10191. def : BaseSTOPregister<asm, GPR64, XZR,
  10192. !cast<Instruction>(instr # "X")>;
  10193. }
  10194. class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops,
  10195. dag iops, dag oops, list<dag> pat>
  10196. : I<oops, iops, asm_inst, asm_ops, "", pat>,
  10197. Sched<[]> /* FIXME: fill in scheduling details once known */ {
  10198. bits<5> Rt;
  10199. bits<5> Rn;
  10200. let Inst{31-21} = 0b11111000001;
  10201. let Inst{15} = 1;
  10202. let Inst{14-12} = opc;
  10203. let Inst{11-10} = 0b00;
  10204. let Inst{9-5} = Rn;
  10205. let Inst{4-0} = Rt;
  10206. let Predicates = [HasV8_7a];
  10207. }
  10208. class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops,
  10209. list<dag> pat = []>
  10210. : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> {
  10211. let Inst{20-16} = 0b11111;
  10212. }
  10213. class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []>
  10214. : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]",
  10215. (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> {
  10216. bits<5> Rs;
  10217. let Inst{20-16} = Rs;
  10218. }
  10219. class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1,
  10220. bits<2> op2, string asm>
  10221. : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb),
  10222. (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn),
  10223. asm, "\t[$Rd]!, [$Rs]!, $Rn!",
  10224. "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>,
  10225. Sched<[]> {
  10226. bits<5> Rd;
  10227. bits<5> Rs;
  10228. bits<5> Rn;
  10229. let Inst{31-27} = 0b00011;
  10230. let Inst{26} = isMove;
  10231. let Inst{25-24} = 0b01;
  10232. let Inst{23-22} = opcode;
  10233. let Inst{21} = 0b0;
  10234. let Inst{20-16} = Rs;
  10235. let Inst{15-14} = op2;
  10236. let Inst{13-12} = op1;
  10237. let Inst{11-10} = 0b01;
  10238. let Inst{9-5} = Rn;
  10239. let Inst{4-0} = Rd;
  10240. let DecoderMethod = "DecodeCPYMemOpInstruction";
  10241. let mayLoad = 1;
  10242. let mayStore = 1;
  10243. }
  10244. class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm>
  10245. : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>;
  10246. class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm>
  10247. : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>;
  10248. class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2,
  10249. string asm>
  10250. : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb),
  10251. (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm),
  10252. asm, "\t[$Rd]!, $Rn!, $Rm",
  10253. "$Rd = $Rd_wb,$Rn = $Rn_wb", []>,
  10254. Sched<[]> {
  10255. bits<5> Rd;
  10256. bits<5> Rn;
  10257. bits<5> Rm;
  10258. let Inst{31-27} = 0b00011;
  10259. let Inst{26} = isTagging;
  10260. let Inst{25-21} = 0b01110;
  10261. let Inst{20-16} = Rm;
  10262. let Inst{15-14} = opcode;
  10263. let Inst{13} = op2;
  10264. let Inst{12} = op1;
  10265. let Inst{11-10} = 0b01;
  10266. let Inst{9-5} = Rn;
  10267. let Inst{4-0} = Rd;
  10268. let DecoderMethod = "DecodeSETMemOpInstruction";
  10269. let mayLoad = 0;
  10270. let mayStore = 1;
  10271. }
  10272. class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm>
  10273. : MOPSMemorySetBase<0, opcode, op1, op2, asm>;
  10274. class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm>
  10275. : MOPSMemorySetBase<1, opcode, op1, op2, asm>;
  10276. multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> {
  10277. def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>;
  10278. def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">;
  10279. def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">;
  10280. def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">;
  10281. def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">;
  10282. def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">;
  10283. def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">;
  10284. def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">;
  10285. def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">;
  10286. def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">;
  10287. def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">;
  10288. def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">;
  10289. def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">;
  10290. def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">;
  10291. def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">;
  10292. def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">;
  10293. }
  10294. multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> {
  10295. def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>;
  10296. def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">;
  10297. def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">;
  10298. def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">;
  10299. def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">;
  10300. def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">;
  10301. def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">;
  10302. def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">;
  10303. def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">;
  10304. def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">;
  10305. def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">;
  10306. def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">;
  10307. def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">;
  10308. def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">;
  10309. def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">;
  10310. def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">;
  10311. }
  10312. multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> {
  10313. def "" : MOPSMemorySet<opcode, 0, 0, asm>;
  10314. def T : MOPSMemorySet<opcode, 1, 0, asm # "t">;
  10315. def N : MOPSMemorySet<opcode, 0, 1, asm # "n">;
  10316. def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">;
  10317. }
  10318. multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> {
  10319. def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>;
  10320. def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">;
  10321. def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">;
  10322. def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">;
  10323. }
  10324. //----------------------------------------------------------------------------
  10325. // Allow the size specifier tokens to be upper case, not just lower.
  10326. def : TokenAlias<".4B", ".4b">; // Add dot product
  10327. def : TokenAlias<".8B", ".8b">;
  10328. def : TokenAlias<".4H", ".4h">;
  10329. def : TokenAlias<".2S", ".2s">;
  10330. def : TokenAlias<".1D", ".1d">;
  10331. def : TokenAlias<".16B", ".16b">;
  10332. def : TokenAlias<".8H", ".8h">;
  10333. def : TokenAlias<".4S", ".4s">;
  10334. def : TokenAlias<".2D", ".2d">;
  10335. def : TokenAlias<".1Q", ".1q">;
  10336. def : TokenAlias<".2H", ".2h">;
  10337. def : TokenAlias<".B", ".b">;
  10338. def : TokenAlias<".H", ".h">;
  10339. def : TokenAlias<".S", ".s">;
  10340. def : TokenAlias<".D", ".d">;
  10341. def : TokenAlias<".Q", ".q">;