NVPTXInstrInfo.td 142 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325
  1. //===- NVPTXInstrInfo.td - NVPTX Instruction defs -------------*- 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. // This file describes the PTX instructions in TableGen format.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. include "NVPTXInstrFormats.td"
  13. // A NOP instruction
  14. let hasSideEffects = false in {
  15. def NOP : NVPTXInst<(outs), (ins), "", []>;
  16. }
  17. let OperandType = "OPERAND_IMMEDIATE" in {
  18. def f16imm : Operand<f16>;
  19. }
  20. // List of vector specific properties
  21. def isVecLD : VecInstTypeEnum<1>;
  22. def isVecST : VecInstTypeEnum<2>;
  23. def isVecBuild : VecInstTypeEnum<3>;
  24. def isVecShuffle : VecInstTypeEnum<4>;
  25. def isVecExtract : VecInstTypeEnum<5>;
  26. def isVecInsert : VecInstTypeEnum<6>;
  27. def isVecDest : VecInstTypeEnum<7>;
  28. def isVecOther : VecInstTypeEnum<15>;
  29. //===----------------------------------------------------------------------===//
  30. // NVPTX Operand Definitions.
  31. //===----------------------------------------------------------------------===//
  32. def brtarget : Operand<OtherVT>;
  33. // CVT conversion modes
  34. // These must match the enum in NVPTX.h
  35. def CvtNONE : PatLeaf<(i32 0x0)>;
  36. def CvtRNI : PatLeaf<(i32 0x1)>;
  37. def CvtRZI : PatLeaf<(i32 0x2)>;
  38. def CvtRMI : PatLeaf<(i32 0x3)>;
  39. def CvtRPI : PatLeaf<(i32 0x4)>;
  40. def CvtRN : PatLeaf<(i32 0x5)>;
  41. def CvtRZ : PatLeaf<(i32 0x6)>;
  42. def CvtRM : PatLeaf<(i32 0x7)>;
  43. def CvtRP : PatLeaf<(i32 0x8)>;
  44. def CvtRNA : PatLeaf<(i32 0x9)>;
  45. def CvtNONE_FTZ : PatLeaf<(i32 0x10)>;
  46. def CvtRNI_FTZ : PatLeaf<(i32 0x11)>;
  47. def CvtRZI_FTZ : PatLeaf<(i32 0x12)>;
  48. def CvtRMI_FTZ : PatLeaf<(i32 0x13)>;
  49. def CvtRPI_FTZ : PatLeaf<(i32 0x14)>;
  50. def CvtRN_FTZ : PatLeaf<(i32 0x15)>;
  51. def CvtRZ_FTZ : PatLeaf<(i32 0x16)>;
  52. def CvtRM_FTZ : PatLeaf<(i32 0x17)>;
  53. def CvtRP_FTZ : PatLeaf<(i32 0x18)>;
  54. def CvtSAT : PatLeaf<(i32 0x20)>;
  55. def CvtSAT_FTZ : PatLeaf<(i32 0x30)>;
  56. def CvtNONE_RELU : PatLeaf<(i32 0x40)>;
  57. def CvtRN_RELU : PatLeaf<(i32 0x45)>;
  58. def CvtRZ_RELU : PatLeaf<(i32 0x46)>;
  59. def CvtMode : Operand<i32> {
  60. let PrintMethod = "printCvtMode";
  61. }
  62. // Compare modes
  63. // These must match the enum in NVPTX.h
  64. def CmpEQ : PatLeaf<(i32 0)>;
  65. def CmpNE : PatLeaf<(i32 1)>;
  66. def CmpLT : PatLeaf<(i32 2)>;
  67. def CmpLE : PatLeaf<(i32 3)>;
  68. def CmpGT : PatLeaf<(i32 4)>;
  69. def CmpGE : PatLeaf<(i32 5)>;
  70. def CmpEQU : PatLeaf<(i32 10)>;
  71. def CmpNEU : PatLeaf<(i32 11)>;
  72. def CmpLTU : PatLeaf<(i32 12)>;
  73. def CmpLEU : PatLeaf<(i32 13)>;
  74. def CmpGTU : PatLeaf<(i32 14)>;
  75. def CmpGEU : PatLeaf<(i32 15)>;
  76. def CmpNUM : PatLeaf<(i32 16)>;
  77. def CmpNAN : PatLeaf<(i32 17)>;
  78. def CmpEQ_FTZ : PatLeaf<(i32 0x100)>;
  79. def CmpNE_FTZ : PatLeaf<(i32 0x101)>;
  80. def CmpLT_FTZ : PatLeaf<(i32 0x102)>;
  81. def CmpLE_FTZ : PatLeaf<(i32 0x103)>;
  82. def CmpGT_FTZ : PatLeaf<(i32 0x104)>;
  83. def CmpGE_FTZ : PatLeaf<(i32 0x105)>;
  84. def CmpEQU_FTZ : PatLeaf<(i32 0x10A)>;
  85. def CmpNEU_FTZ : PatLeaf<(i32 0x10B)>;
  86. def CmpLTU_FTZ : PatLeaf<(i32 0x10C)>;
  87. def CmpLEU_FTZ : PatLeaf<(i32 0x10D)>;
  88. def CmpGTU_FTZ : PatLeaf<(i32 0x10E)>;
  89. def CmpGEU_FTZ : PatLeaf<(i32 0x10F)>;
  90. def CmpNUM_FTZ : PatLeaf<(i32 0x110)>;
  91. def CmpNAN_FTZ : PatLeaf<(i32 0x111)>;
  92. def CmpMode : Operand<i32> {
  93. let PrintMethod = "printCmpMode";
  94. }
  95. def VecElement : Operand<i32> {
  96. let PrintMethod = "printVecElement";
  97. }
  98. //===----------------------------------------------------------------------===//
  99. // NVPTX Instruction Predicate Definitions
  100. //===----------------------------------------------------------------------===//
  101. def hasAtomAddF64 : Predicate<"Subtarget->hasAtomAddF64()">;
  102. def hasAtomScope : Predicate<"Subtarget->hasAtomScope()">;
  103. def hasAtomBitwise64 : Predicate<"Subtarget->hasAtomBitwise64()">;
  104. def hasAtomMinMax64 : Predicate<"Subtarget->hasAtomMinMax64()">;
  105. def hasVote : Predicate<"Subtarget->hasVote()">;
  106. def hasDouble : Predicate<"Subtarget->hasDouble()">;
  107. def hasLDG : Predicate<"Subtarget->hasLDG()">;
  108. def hasLDU : Predicate<"Subtarget->hasLDU()">;
  109. def doF32FTZ : Predicate<"useF32FTZ()">;
  110. def doNoF32FTZ : Predicate<"!useF32FTZ()">;
  111. def doMulWide : Predicate<"doMulWide">;
  112. def allowFMA : Predicate<"allowFMA()">;
  113. def noFMA : Predicate<"!allowFMA()">;
  114. def allowUnsafeFPMath : Predicate<"allowUnsafeFPMath()">;
  115. def noUnsafeFPMath : Predicate<"!allowUnsafeFPMath()">;
  116. def do_DIVF32_APPROX : Predicate<"getDivF32Level()==0">;
  117. def do_DIVF32_FULL : Predicate<"getDivF32Level()==1">;
  118. def do_SQRTF32_APPROX : Predicate<"!usePrecSqrtF32()">;
  119. def do_SQRTF32_RN : Predicate<"usePrecSqrtF32()">;
  120. def hasHWROT32 : Predicate<"Subtarget->hasHWROT32()">;
  121. def noHWROT32 : Predicate<"!Subtarget->hasHWROT32()">;
  122. def True : Predicate<"true">;
  123. def hasPTX31 : Predicate<"Subtarget->getPTXVersion() >= 31">;
  124. def hasPTX42 : Predicate<"Subtarget->getPTXVersion() >= 42">;
  125. def hasPTX43 : Predicate<"Subtarget->getPTXVersion() >= 43">;
  126. def hasPTX60 : Predicate<"Subtarget->getPTXVersion() >= 60">;
  127. def hasPTX61 : Predicate<"Subtarget->getPTXVersion() >= 61">;
  128. def hasPTX63 : Predicate<"Subtarget->getPTXVersion() >= 63">;
  129. def hasPTX64 : Predicate<"Subtarget->getPTXVersion() >= 64">;
  130. def hasPTX65 : Predicate<"Subtarget->getPTXVersion() >= 65">;
  131. def hasPTX70 : Predicate<"Subtarget->getPTXVersion() >= 70">;
  132. def hasPTX71 : Predicate<"Subtarget->getPTXVersion() >= 71">;
  133. def hasPTX72 : Predicate<"Subtarget->getPTXVersion() >= 72">;
  134. def hasSM30 : Predicate<"Subtarget->getSmVersion() >= 30">;
  135. def hasSM32 : Predicate<"Subtarget->getSmVersion() >= 32">;
  136. def hasSM53 : Predicate<"Subtarget->getSmVersion() >= 53">;
  137. def hasSM70 : Predicate<"Subtarget->getSmVersion() >= 70">;
  138. def hasSM72 : Predicate<"Subtarget->getSmVersion() >= 72">;
  139. def hasSM75 : Predicate<"Subtarget->getSmVersion() >= 75">;
  140. def hasSM80 : Predicate<"Subtarget->getSmVersion() >= 80">;
  141. def hasSM86 : Predicate<"Subtarget->getSmVersion() >= 86">;
  142. // non-sync shfl instructions are not available on sm_70+ in PTX6.4+
  143. def hasSHFL : Predicate<"!(Subtarget->getSmVersion() >= 70"
  144. "&& Subtarget->getPTXVersion() >= 64)">;
  145. def useShortPtr : Predicate<"useShortPointers()">;
  146. def useFP16Math: Predicate<"Subtarget->allowFP16Math()">;
  147. // Helper class to aid conversion between ValueType and a matching RegisterClass.
  148. class ValueToRegClass<ValueType T> {
  149. string name = !cast<string>(T);
  150. NVPTXRegClass ret = !cond(
  151. !eq(name, "i1"): Int1Regs,
  152. !eq(name, "i16"): Int16Regs,
  153. !eq(name, "i32"): Int32Regs,
  154. !eq(name, "i64"): Int64Regs,
  155. !eq(name, "f16"): Float16Regs,
  156. !eq(name, "v2f16"): Float16x2Regs,
  157. !eq(name, "bf16"): Float16Regs,
  158. !eq(name, "v2bf16"): Float16x2Regs,
  159. !eq(name, "f32"): Float32Regs,
  160. !eq(name, "f64"): Float64Regs,
  161. !eq(name, "ai32"): Int32ArgRegs,
  162. !eq(name, "ai64"): Int64ArgRegs,
  163. !eq(name, "af32"): Float32ArgRegs,
  164. !eq(name, "if64"): Float64ArgRegs,
  165. );
  166. }
  167. //===----------------------------------------------------------------------===//
  168. // Some Common Instruction Class Templates
  169. //===----------------------------------------------------------------------===//
  170. // Template for instructions which take three int64, int32, or int16 args.
  171. // The instructions are named "<OpcStr><Width>" (e.g. "add.s64").
  172. multiclass I3<string OpcStr, SDNode OpNode> {
  173. def i64rr :
  174. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, Int64Regs:$b),
  175. !strconcat(OpcStr, "64 \t$dst, $a, $b;"),
  176. [(set Int64Regs:$dst, (OpNode Int64Regs:$a, Int64Regs:$b))]>;
  177. def i64ri :
  178. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, i64imm:$b),
  179. !strconcat(OpcStr, "64 \t$dst, $a, $b;"),
  180. [(set Int64Regs:$dst, (OpNode Int64Regs:$a, imm:$b))]>;
  181. def i32rr :
  182. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
  183. !strconcat(OpcStr, "32 \t$dst, $a, $b;"),
  184. [(set Int32Regs:$dst, (OpNode Int32Regs:$a, Int32Regs:$b))]>;
  185. def i32ri :
  186. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
  187. !strconcat(OpcStr, "32 \t$dst, $a, $b;"),
  188. [(set Int32Regs:$dst, (OpNode Int32Regs:$a, imm:$b))]>;
  189. def i16rr :
  190. NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
  191. !strconcat(OpcStr, "16 \t$dst, $a, $b;"),
  192. [(set Int16Regs:$dst, (OpNode Int16Regs:$a, Int16Regs:$b))]>;
  193. def i16ri :
  194. NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, i16imm:$b),
  195. !strconcat(OpcStr, "16 \t$dst, $a, $b;"),
  196. [(set Int16Regs:$dst, (OpNode Int16Regs:$a, (imm):$b))]>;
  197. }
  198. // Template for instructions which take 3 int args. The instructions are
  199. // named "<OpcStr>.s32" (e.g. "addc.cc.s32").
  200. multiclass ADD_SUB_INT_CARRY<string OpcStr, SDNode OpNode> {
  201. let hasSideEffects = 1 in {
  202. def i32rr :
  203. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
  204. !strconcat(OpcStr, ".s32 \t$dst, $a, $b;"),
  205. [(set Int32Regs:$dst, (OpNode Int32Regs:$a, Int32Regs:$b))]>;
  206. def i32ri :
  207. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
  208. !strconcat(OpcStr, ".s32 \t$dst, $a, $b;"),
  209. [(set Int32Regs:$dst, (OpNode Int32Regs:$a, imm:$b))]>;
  210. def i64rr :
  211. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, Int64Regs:$b),
  212. !strconcat(OpcStr, ".s64 \t$dst, $a, $b;"),
  213. [(set Int64Regs:$dst, (OpNode Int64Regs:$a, Int64Regs:$b))]>,
  214. Requires<[hasPTX43]>;
  215. def i64ri :
  216. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, i64imm:$b),
  217. !strconcat(OpcStr, ".s64 \t$dst, $a, $b;"),
  218. [(set Int64Regs:$dst, (OpNode Int64Regs:$a, imm:$b))]>,
  219. Requires<[hasPTX43]>;
  220. }
  221. }
  222. // Template for instructions which take three fp64 or fp32 args. The
  223. // instructions are named "<OpcStr>.f<Width>" (e.g. "min.f64").
  224. //
  225. // Also defines ftz (flush subnormal inputs and results to sign-preserving
  226. // zero) variants for fp32 functions.
  227. //
  228. // This multiclass should be used for nodes that cannot be folded into FMAs.
  229. // For nodes that can be folded into FMAs (i.e. adds and muls), use
  230. // F3_fma_component.
  231. multiclass F3<string OpcStr, SDNode OpNode> {
  232. def f64rr :
  233. NVPTXInst<(outs Float64Regs:$dst),
  234. (ins Float64Regs:$a, Float64Regs:$b),
  235. !strconcat(OpcStr, ".f64 \t$dst, $a, $b;"),
  236. [(set Float64Regs:$dst, (OpNode Float64Regs:$a, Float64Regs:$b))]>;
  237. def f64ri :
  238. NVPTXInst<(outs Float64Regs:$dst),
  239. (ins Float64Regs:$a, f64imm:$b),
  240. !strconcat(OpcStr, ".f64 \t$dst, $a, $b;"),
  241. [(set Float64Regs:$dst, (OpNode Float64Regs:$a, fpimm:$b))]>;
  242. def f32rr_ftz :
  243. NVPTXInst<(outs Float32Regs:$dst),
  244. (ins Float32Regs:$a, Float32Regs:$b),
  245. !strconcat(OpcStr, ".ftz.f32 \t$dst, $a, $b;"),
  246. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>,
  247. Requires<[doF32FTZ]>;
  248. def f32ri_ftz :
  249. NVPTXInst<(outs Float32Regs:$dst),
  250. (ins Float32Regs:$a, f32imm:$b),
  251. !strconcat(OpcStr, ".ftz.f32 \t$dst, $a, $b;"),
  252. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>,
  253. Requires<[doF32FTZ]>;
  254. def f32rr :
  255. NVPTXInst<(outs Float32Regs:$dst),
  256. (ins Float32Regs:$a, Float32Regs:$b),
  257. !strconcat(OpcStr, ".f32 \t$dst, $a, $b;"),
  258. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>;
  259. def f32ri :
  260. NVPTXInst<(outs Float32Regs:$dst),
  261. (ins Float32Regs:$a, f32imm:$b),
  262. !strconcat(OpcStr, ".f32 \t$dst, $a, $b;"),
  263. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>;
  264. def f16rr_ftz :
  265. NVPTXInst<(outs Float16Regs:$dst),
  266. (ins Float16Regs:$a, Float16Regs:$b),
  267. !strconcat(OpcStr, ".ftz.f16 \t$dst, $a, $b;"),
  268. [(set Float16Regs:$dst, (OpNode (f16 Float16Regs:$a), (f16 Float16Regs:$b)))]>,
  269. Requires<[useFP16Math, doF32FTZ]>;
  270. def f16rr :
  271. NVPTXInst<(outs Float16Regs:$dst),
  272. (ins Float16Regs:$a, Float16Regs:$b),
  273. !strconcat(OpcStr, ".f16 \t$dst, $a, $b;"),
  274. [(set Float16Regs:$dst, (OpNode (f16 Float16Regs:$a), (f16 Float16Regs:$b)))]>,
  275. Requires<[useFP16Math]>;
  276. def f16x2rr_ftz :
  277. NVPTXInst<(outs Float16x2Regs:$dst),
  278. (ins Float16x2Regs:$a, Float16x2Regs:$b),
  279. !strconcat(OpcStr, ".ftz.f16x2 \t$dst, $a, $b;"),
  280. [(set Float16x2Regs:$dst, (OpNode (v2f16 Float16x2Regs:$a), (v2f16 Float16x2Regs:$b)))]>,
  281. Requires<[useFP16Math, doF32FTZ]>;
  282. def f16x2rr :
  283. NVPTXInst<(outs Float16x2Regs:$dst),
  284. (ins Float16x2Regs:$a, Float16x2Regs:$b),
  285. !strconcat(OpcStr, ".f16x2 \t$dst, $a, $b;"),
  286. [(set Float16x2Regs:$dst, (OpNode (v2f16 Float16x2Regs:$a), (v2f16 Float16x2Regs:$b)))]>,
  287. Requires<[useFP16Math]>;
  288. }
  289. // Template for instructions which take three FP args. The
  290. // instructions are named "<OpcStr>.f<Width>" (e.g. "add.f64").
  291. //
  292. // Also defines ftz (flush subnormal inputs and results to sign-preserving
  293. // zero) variants for fp32/fp16 functions.
  294. //
  295. // This multiclass should be used for nodes that can be folded to make fma ops.
  296. // In this case, we use the ".rn" variant when FMA is disabled, as this behaves
  297. // just like the non ".rn" op, but prevents ptxas from creating FMAs.
  298. multiclass F3_fma_component<string OpcStr, SDNode OpNode> {
  299. def f64rr :
  300. NVPTXInst<(outs Float64Regs:$dst),
  301. (ins Float64Regs:$a, Float64Regs:$b),
  302. !strconcat(OpcStr, ".f64 \t$dst, $a, $b;"),
  303. [(set Float64Regs:$dst, (OpNode Float64Regs:$a, Float64Regs:$b))]>,
  304. Requires<[allowFMA]>;
  305. def f64ri :
  306. NVPTXInst<(outs Float64Regs:$dst),
  307. (ins Float64Regs:$a, f64imm:$b),
  308. !strconcat(OpcStr, ".f64 \t$dst, $a, $b;"),
  309. [(set Float64Regs:$dst, (OpNode Float64Regs:$a, fpimm:$b))]>,
  310. Requires<[allowFMA]>;
  311. def f32rr_ftz :
  312. NVPTXInst<(outs Float32Regs:$dst),
  313. (ins Float32Regs:$a, Float32Regs:$b),
  314. !strconcat(OpcStr, ".ftz.f32 \t$dst, $a, $b;"),
  315. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>,
  316. Requires<[allowFMA, doF32FTZ]>;
  317. def f32ri_ftz :
  318. NVPTXInst<(outs Float32Regs:$dst),
  319. (ins Float32Regs:$a, f32imm:$b),
  320. !strconcat(OpcStr, ".ftz.f32 \t$dst, $a, $b;"),
  321. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>,
  322. Requires<[allowFMA, doF32FTZ]>;
  323. def f32rr :
  324. NVPTXInst<(outs Float32Regs:$dst),
  325. (ins Float32Regs:$a, Float32Regs:$b),
  326. !strconcat(OpcStr, ".f32 \t$dst, $a, $b;"),
  327. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>,
  328. Requires<[allowFMA]>;
  329. def f32ri :
  330. NVPTXInst<(outs Float32Regs:$dst),
  331. (ins Float32Regs:$a, f32imm:$b),
  332. !strconcat(OpcStr, ".f32 \t$dst, $a, $b;"),
  333. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>,
  334. Requires<[allowFMA]>;
  335. def f16rr_ftz :
  336. NVPTXInst<(outs Float16Regs:$dst),
  337. (ins Float16Regs:$a, Float16Regs:$b),
  338. !strconcat(OpcStr, ".ftz.f16 \t$dst, $a, $b;"),
  339. [(set Float16Regs:$dst, (OpNode (f16 Float16Regs:$a), (f16 Float16Regs:$b)))]>,
  340. Requires<[useFP16Math, allowFMA, doF32FTZ]>;
  341. def f16rr :
  342. NVPTXInst<(outs Float16Regs:$dst),
  343. (ins Float16Regs:$a, Float16Regs:$b),
  344. !strconcat(OpcStr, ".f16 \t$dst, $a, $b;"),
  345. [(set Float16Regs:$dst, (OpNode (f16 Float16Regs:$a), (f16 Float16Regs:$b)))]>,
  346. Requires<[useFP16Math, allowFMA]>;
  347. def f16x2rr_ftz :
  348. NVPTXInst<(outs Float16x2Regs:$dst),
  349. (ins Float16x2Regs:$a, Float16x2Regs:$b),
  350. !strconcat(OpcStr, ".ftz.f16x2 \t$dst, $a, $b;"),
  351. [(set (v2f16 Float16x2Regs:$dst), (OpNode (v2f16 Float16x2Regs:$a), (v2f16 Float16x2Regs:$b)))]>,
  352. Requires<[useFP16Math, allowFMA, doF32FTZ]>;
  353. def f16x2rr :
  354. NVPTXInst<(outs Float16x2Regs:$dst),
  355. (ins Float16x2Regs:$a, Float16x2Regs:$b),
  356. !strconcat(OpcStr, ".f16x2 \t$dst, $a, $b;"),
  357. [(set Float16x2Regs:$dst, (OpNode (v2f16 Float16x2Regs:$a), (v2f16 Float16x2Regs:$b)))]>,
  358. Requires<[useFP16Math, allowFMA]>;
  359. // These have strange names so we don't perturb existing mir tests.
  360. def _rnf64rr :
  361. NVPTXInst<(outs Float64Regs:$dst),
  362. (ins Float64Regs:$a, Float64Regs:$b),
  363. !strconcat(OpcStr, ".rn.f64 \t$dst, $a, $b;"),
  364. [(set Float64Regs:$dst, (OpNode Float64Regs:$a, Float64Regs:$b))]>,
  365. Requires<[noFMA]>;
  366. def _rnf64ri :
  367. NVPTXInst<(outs Float64Regs:$dst),
  368. (ins Float64Regs:$a, f64imm:$b),
  369. !strconcat(OpcStr, ".rn.f64 \t$dst, $a, $b;"),
  370. [(set Float64Regs:$dst, (OpNode Float64Regs:$a, fpimm:$b))]>,
  371. Requires<[noFMA]>;
  372. def _rnf32rr_ftz :
  373. NVPTXInst<(outs Float32Regs:$dst),
  374. (ins Float32Regs:$a, Float32Regs:$b),
  375. !strconcat(OpcStr, ".rn.ftz.f32 \t$dst, $a, $b;"),
  376. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>,
  377. Requires<[noFMA, doF32FTZ]>;
  378. def _rnf32ri_ftz :
  379. NVPTXInst<(outs Float32Regs:$dst),
  380. (ins Float32Regs:$a, f32imm:$b),
  381. !strconcat(OpcStr, ".rn.ftz.f32 \t$dst, $a, $b;"),
  382. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>,
  383. Requires<[noFMA, doF32FTZ]>;
  384. def _rnf32rr :
  385. NVPTXInst<(outs Float32Regs:$dst),
  386. (ins Float32Regs:$a, Float32Regs:$b),
  387. !strconcat(OpcStr, ".rn.f32 \t$dst, $a, $b;"),
  388. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>,
  389. Requires<[noFMA]>;
  390. def _rnf32ri :
  391. NVPTXInst<(outs Float32Regs:$dst),
  392. (ins Float32Regs:$a, f32imm:$b),
  393. !strconcat(OpcStr, ".rn.f32 \t$dst, $a, $b;"),
  394. [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>,
  395. Requires<[noFMA]>;
  396. def _rnf16rr_ftz :
  397. NVPTXInst<(outs Float16Regs:$dst),
  398. (ins Float16Regs:$a, Float16Regs:$b),
  399. !strconcat(OpcStr, ".rn.ftz.f16 \t$dst, $a, $b;"),
  400. [(set Float16Regs:$dst, (OpNode (f16 Float16Regs:$a), (f16 Float16Regs:$b)))]>,
  401. Requires<[useFP16Math, noFMA, doF32FTZ]>;
  402. def _rnf16rr :
  403. NVPTXInst<(outs Float16Regs:$dst),
  404. (ins Float16Regs:$a, Float16Regs:$b),
  405. !strconcat(OpcStr, ".rn.f16 \t$dst, $a, $b;"),
  406. [(set Float16Regs:$dst, (OpNode (f16 Float16Regs:$a), (f16 Float16Regs:$b)))]>,
  407. Requires<[useFP16Math, noFMA]>;
  408. def _rnf16x2rr_ftz :
  409. NVPTXInst<(outs Float16x2Regs:$dst),
  410. (ins Float16x2Regs:$a, Float16x2Regs:$b),
  411. !strconcat(OpcStr, ".rn.ftz.f16x2 \t$dst, $a, $b;"),
  412. [(set Float16x2Regs:$dst, (OpNode (v2f16 Float16x2Regs:$a), (v2f16 Float16x2Regs:$b)))]>,
  413. Requires<[useFP16Math, noFMA, doF32FTZ]>;
  414. def _rnf16x2rr :
  415. NVPTXInst<(outs Float16x2Regs:$dst),
  416. (ins Float16x2Regs:$a, Float16x2Regs:$b),
  417. !strconcat(OpcStr, ".rn.f16x2 \t$dst, $a, $b;"),
  418. [(set Float16x2Regs:$dst, (OpNode (v2f16 Float16x2Regs:$a), (v2f16 Float16x2Regs:$b)))]>,
  419. Requires<[useFP16Math, noFMA]>;
  420. }
  421. // Template for operations which take two f32 or f64 operands. Provides three
  422. // instructions: <OpcStr>.f64, <OpcStr>.f32, and <OpcStr>.ftz.f32 (flush
  423. // subnormal inputs and results to zero).
  424. multiclass F2<string OpcStr, SDNode OpNode> {
  425. def f64 : NVPTXInst<(outs Float64Regs:$dst), (ins Float64Regs:$a),
  426. !strconcat(OpcStr, ".f64 \t$dst, $a;"),
  427. [(set Float64Regs:$dst, (OpNode Float64Regs:$a))]>;
  428. def f32_ftz : NVPTXInst<(outs Float32Regs:$dst), (ins Float32Regs:$a),
  429. !strconcat(OpcStr, ".ftz.f32 \t$dst, $a;"),
  430. [(set Float32Regs:$dst, (OpNode Float32Regs:$a))]>,
  431. Requires<[doF32FTZ]>;
  432. def f32 : NVPTXInst<(outs Float32Regs:$dst), (ins Float32Regs:$a),
  433. !strconcat(OpcStr, ".f32 \t$dst, $a;"),
  434. [(set Float32Regs:$dst, (OpNode Float32Regs:$a))]>;
  435. }
  436. //===----------------------------------------------------------------------===//
  437. // NVPTX Instructions.
  438. //===----------------------------------------------------------------------===//
  439. //-----------------------------------
  440. // Type Conversion
  441. //-----------------------------------
  442. let hasSideEffects = false in {
  443. // Generate a cvt to the given type from all possible types. Each instance
  444. // takes a CvtMode immediate that defines the conversion mode to use. It can
  445. // be CvtNONE to omit a conversion mode.
  446. multiclass CVT_FROM_ALL<string FromName, RegisterClass RC> {
  447. def _s8 :
  448. NVPTXInst<(outs RC:$dst),
  449. (ins Int16Regs:$src, CvtMode:$mode),
  450. !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
  451. FromName, ".s8 \t$dst, $src;"), []>;
  452. def _u8 :
  453. NVPTXInst<(outs RC:$dst),
  454. (ins Int16Regs:$src, CvtMode:$mode),
  455. !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
  456. FromName, ".u8 \t$dst, $src;"), []>;
  457. def _s16 :
  458. NVPTXInst<(outs RC:$dst),
  459. (ins Int16Regs:$src, CvtMode:$mode),
  460. !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
  461. FromName, ".s16 \t$dst, $src;"), []>;
  462. def _u16 :
  463. NVPTXInst<(outs RC:$dst),
  464. (ins Int16Regs:$src, CvtMode:$mode),
  465. !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
  466. FromName, ".u16 \t$dst, $src;"), []>;
  467. def _s32 :
  468. NVPTXInst<(outs RC:$dst),
  469. (ins Int32Regs:$src, CvtMode:$mode),
  470. !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
  471. FromName, ".s32 \t$dst, $src;"), []>;
  472. def _u32 :
  473. NVPTXInst<(outs RC:$dst),
  474. (ins Int32Regs:$src, CvtMode:$mode),
  475. !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
  476. FromName, ".u32 \t$dst, $src;"), []>;
  477. def _s64 :
  478. NVPTXInst<(outs RC:$dst),
  479. (ins Int64Regs:$src, CvtMode:$mode),
  480. !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
  481. FromName, ".s64 \t$dst, $src;"), []>;
  482. def _u64 :
  483. NVPTXInst<(outs RC:$dst),
  484. (ins Int64Regs:$src, CvtMode:$mode),
  485. !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
  486. FromName, ".u64 \t$dst, $src;"), []>;
  487. def _f16 :
  488. NVPTXInst<(outs RC:$dst),
  489. (ins Float16Regs:$src, CvtMode:$mode),
  490. !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
  491. FromName, ".f16 \t$dst, $src;"), []>;
  492. def _f32 :
  493. NVPTXInst<(outs RC:$dst),
  494. (ins Float32Regs:$src, CvtMode:$mode),
  495. !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
  496. FromName, ".f32 \t$dst, $src;"), []>;
  497. def _f64 :
  498. NVPTXInst<(outs RC:$dst),
  499. (ins Float64Regs:$src, CvtMode:$mode),
  500. !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
  501. FromName, ".f64 \t$dst, $src;"), []>;
  502. }
  503. // Generate cvts from all types to all types.
  504. defm CVT_s8 : CVT_FROM_ALL<"s8", Int16Regs>;
  505. defm CVT_u8 : CVT_FROM_ALL<"u8", Int16Regs>;
  506. defm CVT_s16 : CVT_FROM_ALL<"s16", Int16Regs>;
  507. defm CVT_u16 : CVT_FROM_ALL<"u16", Int16Regs>;
  508. defm CVT_s32 : CVT_FROM_ALL<"s32", Int32Regs>;
  509. defm CVT_u32 : CVT_FROM_ALL<"u32", Int32Regs>;
  510. defm CVT_s64 : CVT_FROM_ALL<"s64", Int64Regs>;
  511. defm CVT_u64 : CVT_FROM_ALL<"u64", Int64Regs>;
  512. defm CVT_f16 : CVT_FROM_ALL<"f16", Float16Regs>;
  513. defm CVT_f32 : CVT_FROM_ALL<"f32", Float32Regs>;
  514. defm CVT_f64 : CVT_FROM_ALL<"f64", Float64Regs>;
  515. // These cvts are different from those above: The source and dest registers
  516. // are of the same type.
  517. def CVT_INREG_s16_s8 : NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
  518. "cvt.s16.s8 \t$dst, $src;", []>;
  519. def CVT_INREG_s32_s8 : NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src),
  520. "cvt.s32.s8 \t$dst, $src;", []>;
  521. def CVT_INREG_s32_s16 : NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src),
  522. "cvt.s32.s16 \t$dst, $src;", []>;
  523. def CVT_INREG_s64_s8 : NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
  524. "cvt.s64.s8 \t$dst, $src;", []>;
  525. def CVT_INREG_s64_s16 : NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
  526. "cvt.s64.s16 \t$dst, $src;", []>;
  527. def CVT_INREG_s64_s32 : NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
  528. "cvt.s64.s32 \t$dst, $src;", []>;
  529. multiclass CVT_FROM_FLOAT_SM80<string FromName, RegisterClass RC> {
  530. def _f32 :
  531. NVPTXInst<(outs RC:$dst),
  532. (ins Float32Regs:$src, CvtMode:$mode),
  533. !strconcat("cvt${mode:base}${mode:relu}.",
  534. FromName, ".f32 \t$dst, $src;"), []>,
  535. Requires<[hasPTX70, hasSM80]>;
  536. }
  537. defm CVT_bf16 : CVT_FROM_FLOAT_SM80<"bf16", Int16Regs>;
  538. multiclass CVT_FROM_FLOAT_V2_SM80<string FromName, RegisterClass RC> {
  539. def _f32 :
  540. NVPTXInst<(outs RC:$dst),
  541. (ins Float32Regs:$src1, Float32Regs:$src2, CvtMode:$mode),
  542. !strconcat("cvt${mode:base}${mode:relu}.",
  543. FromName, ".f32 \t$dst, $src1, $src2;"), []>,
  544. Requires<[hasPTX70, hasSM80]>;
  545. }
  546. defm CVT_f16x2 : CVT_FROM_FLOAT_V2_SM80<"f16x2", Float16x2Regs>;
  547. defm CVT_bf16x2 : CVT_FROM_FLOAT_V2_SM80<"bf16x2", Int32Regs>;
  548. }
  549. //-----------------------------------
  550. // Selection instructions (selp)
  551. //-----------------------------------
  552. // TODO: Missing slct
  553. // selp instructions that don't have any pattern matches; we explicitly use
  554. // them within this file.
  555. let hasSideEffects = false in {
  556. multiclass SELP<string TypeStr, RegisterClass RC, Operand ImmCls> {
  557. def rr : NVPTXInst<(outs RC:$dst),
  558. (ins RC:$a, RC:$b, Int1Regs:$p),
  559. !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"), []>;
  560. def ri : NVPTXInst<(outs RC:$dst),
  561. (ins RC:$a, ImmCls:$b, Int1Regs:$p),
  562. !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"), []>;
  563. def ir : NVPTXInst<(outs RC:$dst),
  564. (ins ImmCls:$a, RC:$b, Int1Regs:$p),
  565. !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"), []>;
  566. def ii : NVPTXInst<(outs RC:$dst),
  567. (ins ImmCls:$a, ImmCls:$b, Int1Regs:$p),
  568. !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"), []>;
  569. }
  570. multiclass SELP_PATTERN<string TypeStr, ValueType T, RegisterClass RC,
  571. Operand ImmCls, SDNode ImmNode> {
  572. def rr :
  573. NVPTXInst<(outs RC:$dst),
  574. (ins RC:$a, RC:$b, Int1Regs:$p),
  575. !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"),
  576. [(set (T RC:$dst), (select Int1Regs:$p, (T RC:$a), (T RC:$b)))]>;
  577. def ri :
  578. NVPTXInst<(outs RC:$dst),
  579. (ins RC:$a, ImmCls:$b, Int1Regs:$p),
  580. !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"),
  581. [(set (T RC:$dst), (select Int1Regs:$p, (T RC:$a), (T ImmNode:$b)))]>;
  582. def ir :
  583. NVPTXInst<(outs RC:$dst),
  584. (ins ImmCls:$a, RC:$b, Int1Regs:$p),
  585. !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"),
  586. [(set (T RC:$dst), (select Int1Regs:$p, ImmNode:$a, (T RC:$b)))]>;
  587. def ii :
  588. NVPTXInst<(outs RC:$dst),
  589. (ins ImmCls:$a, ImmCls:$b, Int1Regs:$p),
  590. !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"),
  591. [(set (T RC:$dst), (select Int1Regs:$p, ImmNode:$a, ImmNode:$b))]>;
  592. }
  593. }
  594. // Don't pattern match on selp.{s,u}{16,32,64} -- selp.b{16,32,64} is just as
  595. // good.
  596. defm SELP_b16 : SELP_PATTERN<"b16", i16, Int16Regs, i16imm, imm>;
  597. defm SELP_s16 : SELP<"s16", Int16Regs, i16imm>;
  598. defm SELP_u16 : SELP<"u16", Int16Regs, i16imm>;
  599. defm SELP_b32 : SELP_PATTERN<"b32", i32, Int32Regs, i32imm, imm>;
  600. defm SELP_s32 : SELP<"s32", Int32Regs, i32imm>;
  601. defm SELP_u32 : SELP<"u32", Int32Regs, i32imm>;
  602. defm SELP_b64 : SELP_PATTERN<"b64", i64, Int64Regs, i64imm, imm>;
  603. defm SELP_s64 : SELP<"s64", Int64Regs, i64imm>;
  604. defm SELP_u64 : SELP<"u64", Int64Regs, i64imm>;
  605. defm SELP_f16 : SELP_PATTERN<"b16", f16, Float16Regs, f16imm, fpimm>;
  606. defm SELP_f32 : SELP_PATTERN<"f32", f32, Float32Regs, f32imm, fpimm>;
  607. defm SELP_f64 : SELP_PATTERN<"f64", f64, Float64Regs, f64imm, fpimm>;
  608. // This does not work as tablegen fails to infer the type of 'imm'.
  609. // def v2f16imm : Operand<v2f16>;
  610. // defm SELP_f16x2 : SELP_PATTERN<"b32", v2f16, Float16x2Regs, v2f16imm, imm>;
  611. def SELP_f16x2rr :
  612. NVPTXInst<(outs Float16x2Regs:$dst),
  613. (ins Float16x2Regs:$a, Float16x2Regs:$b, Int1Regs:$p),
  614. "selp.b32 \t$dst, $a, $b, $p;",
  615. [(set Float16x2Regs:$dst,
  616. (select Int1Regs:$p, (v2f16 Float16x2Regs:$a), (v2f16 Float16x2Regs:$b)))]>;
  617. //-----------------------------------
  618. // Test Instructions
  619. //-----------------------------------
  620. def TESTINF_f32r : NVPTXInst<(outs Int1Regs:$p), (ins Float32Regs:$a),
  621. "testp.infinite.f32 \t$p, $a;",
  622. []>;
  623. def TESTINF_f32i : NVPTXInst<(outs Int1Regs:$p), (ins f32imm:$a),
  624. "testp.infinite.f32 \t$p, $a;",
  625. []>;
  626. def TESTINF_f64r : NVPTXInst<(outs Int1Regs:$p), (ins Float64Regs:$a),
  627. "testp.infinite.f64 \t$p, $a;",
  628. []>;
  629. def TESTINF_f64i : NVPTXInst<(outs Int1Regs:$p), (ins f64imm:$a),
  630. "testp.infinite.f64 \t$p, $a;",
  631. []>;
  632. //-----------------------------------
  633. // Integer Arithmetic
  634. //-----------------------------------
  635. // Template for xor masquerading as int1 arithmetic.
  636. multiclass ADD_SUB_i1<SDNode OpNode> {
  637. def _rr: NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$a, Int1Regs:$b),
  638. "xor.pred \t$dst, $a, $b;",
  639. [(set Int1Regs:$dst, (OpNode Int1Regs:$a, Int1Regs:$b))]>;
  640. def _ri: NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$a, i1imm:$b),
  641. "xor.pred \t$dst, $a, $b;",
  642. [(set Int1Regs:$dst, (OpNode Int1Regs:$a, (imm):$b))]>;
  643. }
  644. // int1 addition and subtraction are both just xor.
  645. defm ADD_i1 : ADD_SUB_i1<add>;
  646. defm SUB_i1 : ADD_SUB_i1<sub>;
  647. // int16, int32, and int64 signed addition. Since nvptx is 2's complement, we
  648. // also use these for unsigned arithmetic.
  649. defm ADD : I3<"add.s", add>;
  650. defm SUB : I3<"sub.s", sub>;
  651. // in32 and int64 addition and subtraction with carry-out.
  652. defm ADDCC : ADD_SUB_INT_CARRY<"add.cc", addc>;
  653. defm SUBCC : ADD_SUB_INT_CARRY<"sub.cc", subc>;
  654. // int32 and int64 addition and subtraction with carry-in and carry-out.
  655. defm ADDCCC : ADD_SUB_INT_CARRY<"addc.cc", adde>;
  656. defm SUBCCC : ADD_SUB_INT_CARRY<"subc.cc", sube>;
  657. defm MULT : I3<"mul.lo.s", mul>;
  658. defm MULTHS : I3<"mul.hi.s", mulhs>;
  659. defm MULTHU : I3<"mul.hi.u", mulhu>;
  660. defm SDIV : I3<"div.s", sdiv>;
  661. defm UDIV : I3<"div.u", udiv>;
  662. // The ri versions of rem.s and rem.u won't be selected; DAGCombiner::visitSREM
  663. // will lower it.
  664. defm SREM : I3<"rem.s", srem>;
  665. defm UREM : I3<"rem.u", urem>;
  666. // Integer absolute value. NumBits should be one minus the bit width of RC.
  667. // This idiom implements the algorithm at
  668. // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs.
  669. multiclass ABS<RegisterClass RC, string SizeName> {
  670. def : NVPTXInst<(outs RC:$dst), (ins RC:$a),
  671. !strconcat("abs", SizeName, " \t$dst, $a;"),
  672. [(set RC:$dst, (abs RC:$a))]>;
  673. }
  674. defm ABS_16 : ABS<Int16Regs, ".s16">;
  675. defm ABS_32 : ABS<Int32Regs, ".s32">;
  676. defm ABS_64 : ABS<Int64Regs, ".s64">;
  677. // Integer min/max.
  678. defm SMAX : I3<"max.s", smax>;
  679. defm UMAX : I3<"max.u", umax>;
  680. defm SMIN : I3<"min.s", smin>;
  681. defm UMIN : I3<"min.u", umin>;
  682. //
  683. // Wide multiplication
  684. //
  685. def MULWIDES64 :
  686. NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
  687. "mul.wide.s32 \t$dst, $a, $b;", []>;
  688. def MULWIDES64Imm :
  689. NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
  690. "mul.wide.s32 \t$dst, $a, $b;", []>;
  691. def MULWIDES64Imm64 :
  692. NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i64imm:$b),
  693. "mul.wide.s32 \t$dst, $a, $b;", []>;
  694. def MULWIDEU64 :
  695. NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
  696. "mul.wide.u32 \t$dst, $a, $b;", []>;
  697. def MULWIDEU64Imm :
  698. NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
  699. "mul.wide.u32 \t$dst, $a, $b;", []>;
  700. def MULWIDEU64Imm64 :
  701. NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i64imm:$b),
  702. "mul.wide.u32 \t$dst, $a, $b;", []>;
  703. def MULWIDES32 :
  704. NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
  705. "mul.wide.s16 \t$dst, $a, $b;", []>;
  706. def MULWIDES32Imm :
  707. NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i16imm:$b),
  708. "mul.wide.s16 \t$dst, $a, $b;", []>;
  709. def MULWIDES32Imm32 :
  710. NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i32imm:$b),
  711. "mul.wide.s16 \t$dst, $a, $b;", []>;
  712. def MULWIDEU32 :
  713. NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
  714. "mul.wide.u16 \t$dst, $a, $b;", []>;
  715. def MULWIDEU32Imm :
  716. NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i16imm:$b),
  717. "mul.wide.u16 \t$dst, $a, $b;", []>;
  718. def MULWIDEU32Imm32 :
  719. NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i32imm:$b),
  720. "mul.wide.u16 \t$dst, $a, $b;", []>;
  721. def SDTMulWide : SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>]>;
  722. def mul_wide_signed : SDNode<"NVPTXISD::MUL_WIDE_SIGNED", SDTMulWide>;
  723. def mul_wide_unsigned : SDNode<"NVPTXISD::MUL_WIDE_UNSIGNED", SDTMulWide>;
  724. // Matchers for signed, unsigned mul.wide ISD nodes.
  725. def : Pat<(i32 (mul_wide_signed Int16Regs:$a, Int16Regs:$b)),
  726. (MULWIDES32 Int16Regs:$a, Int16Regs:$b)>,
  727. Requires<[doMulWide]>;
  728. def : Pat<(i32 (mul_wide_signed Int16Regs:$a, imm:$b)),
  729. (MULWIDES32Imm Int16Regs:$a, imm:$b)>,
  730. Requires<[doMulWide]>;
  731. def : Pat<(i32 (mul_wide_unsigned Int16Regs:$a, Int16Regs:$b)),
  732. (MULWIDEU32 Int16Regs:$a, Int16Regs:$b)>,
  733. Requires<[doMulWide]>;
  734. def : Pat<(i32 (mul_wide_unsigned Int16Regs:$a, imm:$b)),
  735. (MULWIDEU32Imm Int16Regs:$a, imm:$b)>,
  736. Requires<[doMulWide]>;
  737. def : Pat<(i64 (mul_wide_signed Int32Regs:$a, Int32Regs:$b)),
  738. (MULWIDES64 Int32Regs:$a, Int32Regs:$b)>,
  739. Requires<[doMulWide]>;
  740. def : Pat<(i64 (mul_wide_signed Int32Regs:$a, imm:$b)),
  741. (MULWIDES64Imm Int32Regs:$a, imm:$b)>,
  742. Requires<[doMulWide]>;
  743. def : Pat<(i64 (mul_wide_unsigned Int32Regs:$a, Int32Regs:$b)),
  744. (MULWIDEU64 Int32Regs:$a, Int32Regs:$b)>,
  745. Requires<[doMulWide]>;
  746. def : Pat<(i64 (mul_wide_unsigned Int32Regs:$a, imm:$b)),
  747. (MULWIDEU64Imm Int32Regs:$a, imm:$b)>,
  748. Requires<[doMulWide]>;
  749. // Predicates used for converting some patterns to mul.wide.
  750. def SInt32Const : PatLeaf<(imm), [{
  751. const APInt &v = N->getAPIntValue();
  752. return v.isSignedIntN(32);
  753. }]>;
  754. def UInt32Const : PatLeaf<(imm), [{
  755. const APInt &v = N->getAPIntValue();
  756. return v.isIntN(32);
  757. }]>;
  758. def SInt16Const : PatLeaf<(imm), [{
  759. const APInt &v = N->getAPIntValue();
  760. return v.isSignedIntN(16);
  761. }]>;
  762. def UInt16Const : PatLeaf<(imm), [{
  763. const APInt &v = N->getAPIntValue();
  764. return v.isIntN(16);
  765. }]>;
  766. def IntConst_0_30 : PatLeaf<(imm), [{
  767. // Check if 0 <= v < 31; only then will the result of (x << v) be an int32.
  768. const APInt &v = N->getAPIntValue();
  769. return v.sge(0) && v.slt(31);
  770. }]>;
  771. def IntConst_0_14 : PatLeaf<(imm), [{
  772. // Check if 0 <= v < 15; only then will the result of (x << v) be an int16.
  773. const APInt &v = N->getAPIntValue();
  774. return v.sge(0) && v.slt(15);
  775. }]>;
  776. def SHL2MUL32 : SDNodeXForm<imm, [{
  777. const APInt &v = N->getAPIntValue();
  778. APInt temp(32, 1);
  779. return CurDAG->getTargetConstant(temp.shl(v), SDLoc(N), MVT::i32);
  780. }]>;
  781. def SHL2MUL16 : SDNodeXForm<imm, [{
  782. const APInt &v = N->getAPIntValue();
  783. APInt temp(16, 1);
  784. return CurDAG->getTargetConstant(temp.shl(v), SDLoc(N), MVT::i16);
  785. }]>;
  786. // Convert "sign/zero-extend, then shift left by an immediate" to mul.wide.
  787. def : Pat<(shl (sext Int32Regs:$a), (i32 IntConst_0_30:$b)),
  788. (MULWIDES64Imm Int32Regs:$a, (SHL2MUL32 node:$b))>,
  789. Requires<[doMulWide]>;
  790. def : Pat<(shl (zext Int32Regs:$a), (i32 IntConst_0_30:$b)),
  791. (MULWIDEU64Imm Int32Regs:$a, (SHL2MUL32 node:$b))>,
  792. Requires<[doMulWide]>;
  793. def : Pat<(shl (sext Int16Regs:$a), (i16 IntConst_0_14:$b)),
  794. (MULWIDES32Imm Int16Regs:$a, (SHL2MUL16 node:$b))>,
  795. Requires<[doMulWide]>;
  796. def : Pat<(shl (zext Int16Regs:$a), (i16 IntConst_0_14:$b)),
  797. (MULWIDEU32Imm Int16Regs:$a, (SHL2MUL16 node:$b))>,
  798. Requires<[doMulWide]>;
  799. // Convert "sign/zero-extend then multiply" to mul.wide.
  800. def : Pat<(mul (sext Int32Regs:$a), (sext Int32Regs:$b)),
  801. (MULWIDES64 Int32Regs:$a, Int32Regs:$b)>,
  802. Requires<[doMulWide]>;
  803. def : Pat<(mul (sext Int32Regs:$a), (i64 SInt32Const:$b)),
  804. (MULWIDES64Imm64 Int32Regs:$a, (i64 SInt32Const:$b))>,
  805. Requires<[doMulWide]>;
  806. def : Pat<(mul (zext Int32Regs:$a), (zext Int32Regs:$b)),
  807. (MULWIDEU64 Int32Regs:$a, Int32Regs:$b)>,
  808. Requires<[doMulWide]>;
  809. def : Pat<(mul (zext Int32Regs:$a), (i64 UInt32Const:$b)),
  810. (MULWIDEU64Imm64 Int32Regs:$a, (i64 UInt32Const:$b))>,
  811. Requires<[doMulWide]>;
  812. def : Pat<(mul (sext Int16Regs:$a), (sext Int16Regs:$b)),
  813. (MULWIDES32 Int16Regs:$a, Int16Regs:$b)>,
  814. Requires<[doMulWide]>;
  815. def : Pat<(mul (sext Int16Regs:$a), (i32 SInt16Const:$b)),
  816. (MULWIDES32Imm32 Int16Regs:$a, (i32 SInt16Const:$b))>,
  817. Requires<[doMulWide]>;
  818. def : Pat<(mul (zext Int16Regs:$a), (zext Int16Regs:$b)),
  819. (MULWIDEU32 Int16Regs:$a, Int16Regs:$b)>,
  820. Requires<[doMulWide]>;
  821. def : Pat<(mul (zext Int16Regs:$a), (i32 UInt16Const:$b)),
  822. (MULWIDEU32Imm32 Int16Regs:$a, (i32 UInt16Const:$b))>,
  823. Requires<[doMulWide]>;
  824. //
  825. // Integer multiply-add
  826. //
  827. def SDTIMAD :
  828. SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2>,
  829. SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>]>;
  830. def imad : SDNode<"NVPTXISD::IMAD", SDTIMAD>;
  831. def MAD16rrr :
  832. NVPTXInst<(outs Int16Regs:$dst),
  833. (ins Int16Regs:$a, Int16Regs:$b, Int16Regs:$c),
  834. "mad.lo.s16 \t$dst, $a, $b, $c;",
  835. [(set Int16Regs:$dst, (imad Int16Regs:$a, Int16Regs:$b, Int16Regs:$c))]>;
  836. def MAD16rri :
  837. NVPTXInst<(outs Int16Regs:$dst),
  838. (ins Int16Regs:$a, Int16Regs:$b, i16imm:$c),
  839. "mad.lo.s16 \t$dst, $a, $b, $c;",
  840. [(set Int16Regs:$dst, (imad Int16Regs:$a, Int16Regs:$b, imm:$c))]>;
  841. def MAD16rir :
  842. NVPTXInst<(outs Int16Regs:$dst),
  843. (ins Int16Regs:$a, i16imm:$b, Int16Regs:$c),
  844. "mad.lo.s16 \t$dst, $a, $b, $c;",
  845. [(set Int16Regs:$dst, (imad Int16Regs:$a, imm:$b, Int16Regs:$c))]>;
  846. def MAD16rii :
  847. NVPTXInst<(outs Int16Regs:$dst),
  848. (ins Int16Regs:$a, i16imm:$b, i16imm:$c),
  849. "mad.lo.s16 \t$dst, $a, $b, $c;",
  850. [(set Int16Regs:$dst, (imad Int16Regs:$a, imm:$b, imm:$c))]>;
  851. def MAD32rrr :
  852. NVPTXInst<(outs Int32Regs:$dst),
  853. (ins Int32Regs:$a, Int32Regs:$b, Int32Regs:$c),
  854. "mad.lo.s32 \t$dst, $a, $b, $c;",
  855. [(set Int32Regs:$dst, (imad Int32Regs:$a, Int32Regs:$b, Int32Regs:$c))]>;
  856. def MAD32rri :
  857. NVPTXInst<(outs Int32Regs:$dst),
  858. (ins Int32Regs:$a, Int32Regs:$b, i32imm:$c),
  859. "mad.lo.s32 \t$dst, $a, $b, $c;",
  860. [(set Int32Regs:$dst, (imad Int32Regs:$a, Int32Regs:$b, imm:$c))]>;
  861. def MAD32rir :
  862. NVPTXInst<(outs Int32Regs:$dst),
  863. (ins Int32Regs:$a, i32imm:$b, Int32Regs:$c),
  864. "mad.lo.s32 \t$dst, $a, $b, $c;",
  865. [(set Int32Regs:$dst, (imad Int32Regs:$a, imm:$b, Int32Regs:$c))]>;
  866. def MAD32rii :
  867. NVPTXInst<(outs Int32Regs:$dst),
  868. (ins Int32Regs:$a, i32imm:$b, i32imm:$c),
  869. "mad.lo.s32 \t$dst, $a, $b, $c;",
  870. [(set Int32Regs:$dst, (imad Int32Regs:$a, imm:$b, imm:$c))]>;
  871. def MAD64rrr :
  872. NVPTXInst<(outs Int64Regs:$dst),
  873. (ins Int64Regs:$a, Int64Regs:$b, Int64Regs:$c),
  874. "mad.lo.s64 \t$dst, $a, $b, $c;",
  875. [(set Int64Regs:$dst, (imad Int64Regs:$a, Int64Regs:$b, Int64Regs:$c))]>;
  876. def MAD64rri :
  877. NVPTXInst<(outs Int64Regs:$dst),
  878. (ins Int64Regs:$a, Int64Regs:$b, i64imm:$c),
  879. "mad.lo.s64 \t$dst, $a, $b, $c;",
  880. [(set Int64Regs:$dst, (imad Int64Regs:$a, Int64Regs:$b, imm:$c))]>;
  881. def MAD64rir :
  882. NVPTXInst<(outs Int64Regs:$dst),
  883. (ins Int64Regs:$a, i64imm:$b, Int64Regs:$c),
  884. "mad.lo.s64 \t$dst, $a, $b, $c;",
  885. [(set Int64Regs:$dst, (imad Int64Regs:$a, imm:$b, Int64Regs:$c))]>;
  886. def MAD64rii :
  887. NVPTXInst<(outs Int64Regs:$dst),
  888. (ins Int64Regs:$a, i64imm:$b, i64imm:$c),
  889. "mad.lo.s64 \t$dst, $a, $b, $c;",
  890. [(set Int64Regs:$dst, (imad Int64Regs:$a, imm:$b, imm:$c))]>;
  891. def INEG16 :
  892. NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
  893. "neg.s16 \t$dst, $src;",
  894. [(set Int16Regs:$dst, (ineg Int16Regs:$src))]>;
  895. def INEG32 :
  896. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src),
  897. "neg.s32 \t$dst, $src;",
  898. [(set Int32Regs:$dst, (ineg Int32Regs:$src))]>;
  899. def INEG64 :
  900. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
  901. "neg.s64 \t$dst, $src;",
  902. [(set Int64Regs:$dst, (ineg Int64Regs:$src))]>;
  903. //-----------------------------------
  904. // Floating Point Arithmetic
  905. //-----------------------------------
  906. // Constant 1.0f
  907. def FloatConst1 : PatLeaf<(fpimm), [{
  908. return &N->getValueAPF().getSemantics() == &llvm::APFloat::IEEEsingle() &&
  909. N->getValueAPF().convertToFloat() == 1.0f;
  910. }]>;
  911. // Constant 1.0 (double)
  912. def DoubleConst1 : PatLeaf<(fpimm), [{
  913. return &N->getValueAPF().getSemantics() == &llvm::APFloat::IEEEdouble() &&
  914. N->getValueAPF().convertToDouble() == 1.0;
  915. }]>;
  916. // Loads FP16 constant into a register.
  917. //
  918. // ptxas does not have hex representation for fp16, so we can't use
  919. // fp16 immediate values in .f16 instructions. Instead we have to load
  920. // the constant into a register using mov.b16.
  921. def LOAD_CONST_F16 :
  922. NVPTXInst<(outs Float16Regs:$dst), (ins f16imm:$a),
  923. "mov.b16 \t$dst, $a;", []>;
  924. defm FADD : F3_fma_component<"add", fadd>;
  925. defm FSUB : F3_fma_component<"sub", fsub>;
  926. defm FMUL : F3_fma_component<"mul", fmul>;
  927. defm FMIN : F3<"min", fminnum>;
  928. defm FMAX : F3<"max", fmaxnum>;
  929. // Note: min.NaN.f64 and max.NaN.f64 do not actually exist.
  930. defm FMINNAN : F3<"min.NaN", fminimum>;
  931. defm FMAXNAN : F3<"max.NaN", fmaximum>;
  932. defm FABS : F2<"abs", fabs>;
  933. defm FNEG : F2<"neg", fneg>;
  934. defm FSQRT : F2<"sqrt.rn", fsqrt>;
  935. //
  936. // F16 NEG
  937. //
  938. class FNEG_F16_F16X2<string OpcStr, ValueType T, RegisterClass RC, Predicate Pred> :
  939. NVPTXInst<(outs RC:$dst), (ins RC:$src),
  940. !strconcat(OpcStr, " \t$dst, $src;"),
  941. [(set RC:$dst, (fneg (T RC:$src)))]>,
  942. Requires<[useFP16Math, hasPTX60, hasSM53, Pred]>;
  943. def FNEG16_ftz : FNEG_F16_F16X2<"neg.ftz.f16", f16, Float16Regs, doF32FTZ>;
  944. def FNEG16 : FNEG_F16_F16X2<"neg.f16", f16, Float16Regs, True>;
  945. def FNEG16x2_ftz : FNEG_F16_F16X2<"neg.ftz.f16x2", v2f16, Float16x2Regs, doF32FTZ>;
  946. def FNEG16x2 : FNEG_F16_F16X2<"neg.f16x2", v2f16, Float16x2Regs, True>;
  947. //
  948. // F64 division
  949. //
  950. def FDIV641r :
  951. NVPTXInst<(outs Float64Regs:$dst),
  952. (ins f64imm:$a, Float64Regs:$b),
  953. "rcp.rn.f64 \t$dst, $b;",
  954. [(set Float64Regs:$dst, (fdiv DoubleConst1:$a, Float64Regs:$b))]>;
  955. def FDIV64rr :
  956. NVPTXInst<(outs Float64Regs:$dst),
  957. (ins Float64Regs:$a, Float64Regs:$b),
  958. "div.rn.f64 \t$dst, $a, $b;",
  959. [(set Float64Regs:$dst, (fdiv Float64Regs:$a, Float64Regs:$b))]>;
  960. def FDIV64ri :
  961. NVPTXInst<(outs Float64Regs:$dst),
  962. (ins Float64Regs:$a, f64imm:$b),
  963. "div.rn.f64 \t$dst, $a, $b;",
  964. [(set Float64Regs:$dst, (fdiv Float64Regs:$a, fpimm:$b))]>;
  965. //
  966. // F32 Approximate reciprocal
  967. //
  968. def FDIV321r_ftz :
  969. NVPTXInst<(outs Float32Regs:$dst),
  970. (ins f32imm:$a, Float32Regs:$b),
  971. "rcp.approx.ftz.f32 \t$dst, $b;",
  972. [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>,
  973. Requires<[do_DIVF32_APPROX, doF32FTZ]>;
  974. def FDIV321r :
  975. NVPTXInst<(outs Float32Regs:$dst),
  976. (ins f32imm:$a, Float32Regs:$b),
  977. "rcp.approx.f32 \t$dst, $b;",
  978. [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>,
  979. Requires<[do_DIVF32_APPROX]>;
  980. //
  981. // F32 Approximate division
  982. //
  983. def FDIV32approxrr_ftz :
  984. NVPTXInst<(outs Float32Regs:$dst),
  985. (ins Float32Regs:$a, Float32Regs:$b),
  986. "div.approx.ftz.f32 \t$dst, $a, $b;",
  987. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>,
  988. Requires<[do_DIVF32_APPROX, doF32FTZ]>;
  989. def FDIV32approxri_ftz :
  990. NVPTXInst<(outs Float32Regs:$dst),
  991. (ins Float32Regs:$a, f32imm:$b),
  992. "div.approx.ftz.f32 \t$dst, $a, $b;",
  993. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>,
  994. Requires<[do_DIVF32_APPROX, doF32FTZ]>;
  995. def FDIV32approxrr :
  996. NVPTXInst<(outs Float32Regs:$dst),
  997. (ins Float32Regs:$a, Float32Regs:$b),
  998. "div.approx.f32 \t$dst, $a, $b;",
  999. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>,
  1000. Requires<[do_DIVF32_APPROX]>;
  1001. def FDIV32approxri :
  1002. NVPTXInst<(outs Float32Regs:$dst),
  1003. (ins Float32Regs:$a, f32imm:$b),
  1004. "div.approx.f32 \t$dst, $a, $b;",
  1005. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>,
  1006. Requires<[do_DIVF32_APPROX]>;
  1007. //
  1008. // F32 Semi-accurate reciprocal
  1009. //
  1010. // rcp.approx gives the same result as div.full(1.0f, a) and is faster.
  1011. //
  1012. def FDIV321r_approx_ftz :
  1013. NVPTXInst<(outs Float32Regs:$dst),
  1014. (ins f32imm:$a, Float32Regs:$b),
  1015. "rcp.approx.ftz.f32 \t$dst, $b;",
  1016. [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>,
  1017. Requires<[do_DIVF32_FULL, doF32FTZ]>;
  1018. def FDIV321r_approx :
  1019. NVPTXInst<(outs Float32Regs:$dst),
  1020. (ins f32imm:$a, Float32Regs:$b),
  1021. "rcp.approx.f32 \t$dst, $b;",
  1022. [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>,
  1023. Requires<[do_DIVF32_FULL]>;
  1024. //
  1025. // F32 Semi-accurate division
  1026. //
  1027. def FDIV32rr_ftz :
  1028. NVPTXInst<(outs Float32Regs:$dst),
  1029. (ins Float32Regs:$a, Float32Regs:$b),
  1030. "div.full.ftz.f32 \t$dst, $a, $b;",
  1031. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>,
  1032. Requires<[do_DIVF32_FULL, doF32FTZ]>;
  1033. def FDIV32ri_ftz :
  1034. NVPTXInst<(outs Float32Regs:$dst),
  1035. (ins Float32Regs:$a, f32imm:$b),
  1036. "div.full.ftz.f32 \t$dst, $a, $b;",
  1037. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>,
  1038. Requires<[do_DIVF32_FULL, doF32FTZ]>;
  1039. def FDIV32rr :
  1040. NVPTXInst<(outs Float32Regs:$dst),
  1041. (ins Float32Regs:$a, Float32Regs:$b),
  1042. "div.full.f32 \t$dst, $a, $b;",
  1043. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>,
  1044. Requires<[do_DIVF32_FULL]>;
  1045. def FDIV32ri :
  1046. NVPTXInst<(outs Float32Regs:$dst),
  1047. (ins Float32Regs:$a, f32imm:$b),
  1048. "div.full.f32 \t$dst, $a, $b;",
  1049. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>,
  1050. Requires<[do_DIVF32_FULL]>;
  1051. //
  1052. // F32 Accurate reciprocal
  1053. //
  1054. def FDIV321r_prec_ftz :
  1055. NVPTXInst<(outs Float32Regs:$dst),
  1056. (ins f32imm:$a, Float32Regs:$b),
  1057. "rcp.rn.ftz.f32 \t$dst, $b;",
  1058. [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>,
  1059. Requires<[doF32FTZ]>;
  1060. def FDIV321r_prec :
  1061. NVPTXInst<(outs Float32Regs:$dst),
  1062. (ins f32imm:$a, Float32Regs:$b),
  1063. "rcp.rn.f32 \t$dst, $b;",
  1064. [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>;
  1065. //
  1066. // F32 Accurate division
  1067. //
  1068. def FDIV32rr_prec_ftz :
  1069. NVPTXInst<(outs Float32Regs:$dst),
  1070. (ins Float32Regs:$a, Float32Regs:$b),
  1071. "div.rn.ftz.f32 \t$dst, $a, $b;",
  1072. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>,
  1073. Requires<[doF32FTZ]>;
  1074. def FDIV32ri_prec_ftz :
  1075. NVPTXInst<(outs Float32Regs:$dst),
  1076. (ins Float32Regs:$a, f32imm:$b),
  1077. "div.rn.ftz.f32 \t$dst, $a, $b;",
  1078. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>,
  1079. Requires<[doF32FTZ]>;
  1080. def FDIV32rr_prec :
  1081. NVPTXInst<(outs Float32Regs:$dst),
  1082. (ins Float32Regs:$a, Float32Regs:$b),
  1083. "div.rn.f32 \t$dst, $a, $b;",
  1084. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>;
  1085. def FDIV32ri_prec :
  1086. NVPTXInst<(outs Float32Regs:$dst),
  1087. (ins Float32Regs:$a, f32imm:$b),
  1088. "div.rn.f32 \t$dst, $a, $b;",
  1089. [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>;
  1090. //
  1091. // FMA
  1092. //
  1093. multiclass FMA<string OpcStr, RegisterClass RC, Operand ImmCls, Predicate Pred> {
  1094. def rrr : NVPTXInst<(outs RC:$dst), (ins RC:$a, RC:$b, RC:$c),
  1095. !strconcat(OpcStr, " \t$dst, $a, $b, $c;"),
  1096. [(set RC:$dst, (fma RC:$a, RC:$b, RC:$c))]>,
  1097. Requires<[Pred]>;
  1098. def rri : NVPTXInst<(outs RC:$dst),
  1099. (ins RC:$a, RC:$b, ImmCls:$c),
  1100. !strconcat(OpcStr, " \t$dst, $a, $b, $c;"),
  1101. [(set RC:$dst, (fma RC:$a, RC:$b, fpimm:$c))]>,
  1102. Requires<[Pred]>;
  1103. def rir : NVPTXInst<(outs RC:$dst),
  1104. (ins RC:$a, ImmCls:$b, RC:$c),
  1105. !strconcat(OpcStr, " \t$dst, $a, $b, $c;"),
  1106. [(set RC:$dst, (fma RC:$a, fpimm:$b, RC:$c))]>,
  1107. Requires<[Pred]>;
  1108. def rii : NVPTXInst<(outs RC:$dst),
  1109. (ins RC:$a, ImmCls:$b, ImmCls:$c),
  1110. !strconcat(OpcStr, " \t$dst, $a, $b, $c;"),
  1111. [(set RC:$dst, (fma RC:$a, fpimm:$b, fpimm:$c))]>,
  1112. Requires<[Pred]>;
  1113. }
  1114. multiclass FMA_F16<string OpcStr, ValueType T, RegisterClass RC, Predicate Pred> {
  1115. def rrr : NVPTXInst<(outs RC:$dst), (ins RC:$a, RC:$b, RC:$c),
  1116. !strconcat(OpcStr, " \t$dst, $a, $b, $c;"),
  1117. [(set RC:$dst, (fma (T RC:$a), (T RC:$b), (T RC:$c)))]>,
  1118. Requires<[useFP16Math, Pred]>;
  1119. }
  1120. defm FMA16_ftz : FMA_F16<"fma.rn.ftz.f16", f16, Float16Regs, doF32FTZ>;
  1121. defm FMA16 : FMA_F16<"fma.rn.f16", f16, Float16Regs, True>;
  1122. defm FMA16x2_ftz : FMA_F16<"fma.rn.ftz.f16x2", v2f16, Float16x2Regs, doF32FTZ>;
  1123. defm FMA16x2 : FMA_F16<"fma.rn.f16x2", v2f16, Float16x2Regs, True>;
  1124. defm FMA32_ftz : FMA<"fma.rn.ftz.f32", Float32Regs, f32imm, doF32FTZ>;
  1125. defm FMA32 : FMA<"fma.rn.f32", Float32Regs, f32imm, True>;
  1126. defm FMA64 : FMA<"fma.rn.f64", Float64Regs, f64imm, True>;
  1127. // sin/cos
  1128. def SINF: NVPTXInst<(outs Float32Regs:$dst), (ins Float32Regs:$src),
  1129. "sin.approx.f32 \t$dst, $src;",
  1130. [(set Float32Regs:$dst, (fsin Float32Regs:$src))]>,
  1131. Requires<[allowUnsafeFPMath]>;
  1132. def COSF: NVPTXInst<(outs Float32Regs:$dst), (ins Float32Regs:$src),
  1133. "cos.approx.f32 \t$dst, $src;",
  1134. [(set Float32Regs:$dst, (fcos Float32Regs:$src))]>,
  1135. Requires<[allowUnsafeFPMath]>;
  1136. // Lower (frem x, y) into (sub x, (mul (ftrunc (div x, y)) y)),
  1137. // i.e. "poor man's fmod()". When y is infinite, x is returned. This matches the
  1138. // semantics of LLVM's frem.
  1139. // frem - f32 FTZ
  1140. def : Pat<(frem Float32Regs:$x, Float32Regs:$y),
  1141. (FSUBf32rr_ftz Float32Regs:$x, (FMULf32rr_ftz (CVT_f32_f32
  1142. (FDIV32rr_prec_ftz Float32Regs:$x, Float32Regs:$y), CvtRZI_FTZ),
  1143. Float32Regs:$y))>,
  1144. Requires<[doF32FTZ, allowUnsafeFPMath]>;
  1145. def : Pat<(frem Float32Regs:$x, fpimm:$y),
  1146. (FSUBf32rr_ftz Float32Regs:$x, (FMULf32ri_ftz (CVT_f32_f32
  1147. (FDIV32ri_prec_ftz Float32Regs:$x, fpimm:$y), CvtRZI_FTZ),
  1148. fpimm:$y))>,
  1149. Requires<[doF32FTZ, allowUnsafeFPMath]>;
  1150. def : Pat<(frem Float32Regs:$x, Float32Regs:$y),
  1151. (SELP_f32rr Float32Regs:$x,
  1152. (FSUBf32rr_ftz Float32Regs:$x, (FMULf32rr_ftz (CVT_f32_f32
  1153. (FDIV32rr_prec_ftz Float32Regs:$x, Float32Regs:$y), CvtRZI_FTZ),
  1154. Float32Regs:$y)),
  1155. (TESTINF_f32r Float32Regs:$y))>,
  1156. Requires<[doF32FTZ, noUnsafeFPMath]>;
  1157. def : Pat<(frem Float32Regs:$x, fpimm:$y),
  1158. (SELP_f32rr Float32Regs:$x,
  1159. (FSUBf32rr_ftz Float32Regs:$x, (FMULf32ri_ftz (CVT_f32_f32
  1160. (FDIV32ri_prec_ftz Float32Regs:$x, fpimm:$y), CvtRZI_FTZ),
  1161. fpimm:$y)),
  1162. (TESTINF_f32i fpimm:$y))>,
  1163. Requires<[doF32FTZ, noUnsafeFPMath]>;
  1164. // frem - f32
  1165. def : Pat<(frem Float32Regs:$x, Float32Regs:$y),
  1166. (FSUBf32rr Float32Regs:$x, (FMULf32rr (CVT_f32_f32
  1167. (FDIV32rr_prec Float32Regs:$x, Float32Regs:$y), CvtRZI),
  1168. Float32Regs:$y))>,
  1169. Requires<[allowUnsafeFPMath]>;
  1170. def : Pat<(frem Float32Regs:$x, fpimm:$y),
  1171. (FSUBf32rr Float32Regs:$x, (FMULf32ri (CVT_f32_f32
  1172. (FDIV32ri_prec Float32Regs:$x, fpimm:$y), CvtRZI),
  1173. fpimm:$y))>,
  1174. Requires<[allowUnsafeFPMath]>;
  1175. def : Pat<(frem Float32Regs:$x, Float32Regs:$y),
  1176. (SELP_f32rr Float32Regs:$x,
  1177. (FSUBf32rr Float32Regs:$x, (FMULf32rr (CVT_f32_f32
  1178. (FDIV32rr_prec Float32Regs:$x, Float32Regs:$y), CvtRZI),
  1179. Float32Regs:$y)),
  1180. (TESTINF_f32r Float32Regs:$y))>,
  1181. Requires<[noUnsafeFPMath]>;
  1182. def : Pat<(frem Float32Regs:$x, fpimm:$y),
  1183. (SELP_f32rr Float32Regs:$x,
  1184. (FSUBf32rr Float32Regs:$x, (FMULf32ri (CVT_f32_f32
  1185. (FDIV32ri_prec Float32Regs:$x, fpimm:$y), CvtRZI),
  1186. fpimm:$y)),
  1187. (TESTINF_f32i fpimm:$y))>,
  1188. Requires<[noUnsafeFPMath]>;
  1189. // frem - f64
  1190. def : Pat<(frem Float64Regs:$x, Float64Regs:$y),
  1191. (FSUBf64rr Float64Regs:$x, (FMULf64rr (CVT_f64_f64
  1192. (FDIV64rr Float64Regs:$x, Float64Regs:$y), CvtRZI),
  1193. Float64Regs:$y))>,
  1194. Requires<[allowUnsafeFPMath]>;
  1195. def : Pat<(frem Float64Regs:$x, fpimm:$y),
  1196. (FSUBf64rr Float64Regs:$x, (FMULf64ri (CVT_f64_f64
  1197. (FDIV64ri Float64Regs:$x, fpimm:$y), CvtRZI),
  1198. fpimm:$y))>,
  1199. Requires<[allowUnsafeFPMath]>;
  1200. def : Pat<(frem Float64Regs:$x, Float64Regs:$y),
  1201. (SELP_f64rr Float64Regs:$x,
  1202. (FSUBf64rr Float64Regs:$x, (FMULf64rr (CVT_f64_f64
  1203. (FDIV64rr Float64Regs:$x, Float64Regs:$y), CvtRZI),
  1204. Float64Regs:$y)),
  1205. (TESTINF_f64r Float64Regs:$y))>,
  1206. Requires<[noUnsafeFPMath]>;
  1207. def : Pat<(frem Float64Regs:$x, fpimm:$y),
  1208. (SELP_f64rr Float64Regs:$x,
  1209. (FSUBf64rr Float64Regs:$x, (FMULf64ri (CVT_f64_f64
  1210. (FDIV64ri Float64Regs:$x, fpimm:$y), CvtRZI),
  1211. fpimm:$y)),
  1212. (TESTINF_f64r Float64Regs:$y))>,
  1213. Requires<[noUnsafeFPMath]>;
  1214. //-----------------------------------
  1215. // Bitwise operations
  1216. //-----------------------------------
  1217. // Template for three-arg bitwise operations. Takes three args, Creates .b16,
  1218. // .b32, .b64, and .pred (predicate registers -- i.e., i1) versions of OpcStr.
  1219. multiclass BITWISE<string OpcStr, SDNode OpNode> {
  1220. def b1rr :
  1221. NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$a, Int1Regs:$b),
  1222. !strconcat(OpcStr, ".pred \t$dst, $a, $b;"),
  1223. [(set Int1Regs:$dst, (OpNode Int1Regs:$a, Int1Regs:$b))]>;
  1224. def b1ri :
  1225. NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$a, i1imm:$b),
  1226. !strconcat(OpcStr, ".pred \t$dst, $a, $b;"),
  1227. [(set Int1Regs:$dst, (OpNode Int1Regs:$a, imm:$b))]>;
  1228. def b16rr :
  1229. NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
  1230. !strconcat(OpcStr, ".b16 \t$dst, $a, $b;"),
  1231. [(set Int16Regs:$dst, (OpNode Int16Regs:$a, Int16Regs:$b))]>;
  1232. def b16ri :
  1233. NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, i16imm:$b),
  1234. !strconcat(OpcStr, ".b16 \t$dst, $a, $b;"),
  1235. [(set Int16Regs:$dst, (OpNode Int16Regs:$a, imm:$b))]>;
  1236. def b32rr :
  1237. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
  1238. !strconcat(OpcStr, ".b32 \t$dst, $a, $b;"),
  1239. [(set Int32Regs:$dst, (OpNode Int32Regs:$a, Int32Regs:$b))]>;
  1240. def b32ri :
  1241. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
  1242. !strconcat(OpcStr, ".b32 \t$dst, $a, $b;"),
  1243. [(set Int32Regs:$dst, (OpNode Int32Regs:$a, imm:$b))]>;
  1244. def b64rr :
  1245. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, Int64Regs:$b),
  1246. !strconcat(OpcStr, ".b64 \t$dst, $a, $b;"),
  1247. [(set Int64Regs:$dst, (OpNode Int64Regs:$a, Int64Regs:$b))]>;
  1248. def b64ri :
  1249. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, i64imm:$b),
  1250. !strconcat(OpcStr, ".b64 \t$dst, $a, $b;"),
  1251. [(set Int64Regs:$dst, (OpNode Int64Regs:$a, imm:$b))]>;
  1252. }
  1253. defm OR : BITWISE<"or", or>;
  1254. defm AND : BITWISE<"and", and>;
  1255. defm XOR : BITWISE<"xor", xor>;
  1256. def NOT1 : NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$src),
  1257. "not.pred \t$dst, $src;",
  1258. [(set Int1Regs:$dst, (not Int1Regs:$src))]>;
  1259. def NOT16 : NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
  1260. "not.b16 \t$dst, $src;",
  1261. [(set Int16Regs:$dst, (not Int16Regs:$src))]>;
  1262. def NOT32 : NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src),
  1263. "not.b32 \t$dst, $src;",
  1264. [(set Int32Regs:$dst, (not Int32Regs:$src))]>;
  1265. def NOT64 : NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
  1266. "not.b64 \t$dst, $src;",
  1267. [(set Int64Regs:$dst, (not Int64Regs:$src))]>;
  1268. // Template for left/right shifts. Takes three operands,
  1269. // [dest (reg), src (reg), shift (reg or imm)].
  1270. // dest and src may be int64, int32, or int16, but shift is always int32.
  1271. //
  1272. // This template also defines a 32-bit shift (imm, imm) instruction.
  1273. multiclass SHIFT<string OpcStr, SDNode OpNode> {
  1274. def i64rr :
  1275. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, Int32Regs:$b),
  1276. !strconcat(OpcStr, "64 \t$dst, $a, $b;"),
  1277. [(set Int64Regs:$dst, (OpNode Int64Regs:$a, Int32Regs:$b))]>;
  1278. def i64ri :
  1279. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, i32imm:$b),
  1280. !strconcat(OpcStr, "64 \t$dst, $a, $b;"),
  1281. [(set Int64Regs:$dst, (OpNode Int64Regs:$a, (i32 imm:$b)))]>;
  1282. def i32rr :
  1283. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
  1284. !strconcat(OpcStr, "32 \t$dst, $a, $b;"),
  1285. [(set Int32Regs:$dst, (OpNode Int32Regs:$a, Int32Regs:$b))]>;
  1286. def i32ri :
  1287. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
  1288. !strconcat(OpcStr, "32 \t$dst, $a, $b;"),
  1289. [(set Int32Regs:$dst, (OpNode Int32Regs:$a, (i32 imm:$b)))]>;
  1290. def i32ii :
  1291. NVPTXInst<(outs Int32Regs:$dst), (ins i32imm:$a, i32imm:$b),
  1292. !strconcat(OpcStr, "32 \t$dst, $a, $b;"),
  1293. [(set Int32Regs:$dst, (OpNode (i32 imm:$a), (i32 imm:$b)))]>;
  1294. def i16rr :
  1295. NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, Int32Regs:$b),
  1296. !strconcat(OpcStr, "16 \t$dst, $a, $b;"),
  1297. [(set Int16Regs:$dst, (OpNode Int16Regs:$a, Int32Regs:$b))]>;
  1298. def i16ri :
  1299. NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, i32imm:$b),
  1300. !strconcat(OpcStr, "16 \t$dst, $a, $b;"),
  1301. [(set Int16Regs:$dst, (OpNode Int16Regs:$a, (i32 imm:$b)))]>;
  1302. }
  1303. defm SHL : SHIFT<"shl.b", shl>;
  1304. defm SRA : SHIFT<"shr.s", sra>;
  1305. defm SRL : SHIFT<"shr.u", srl>;
  1306. // Bit-reverse
  1307. def BREV32 :
  1308. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a),
  1309. "brev.b32 \t$dst, $a;",
  1310. [(set Int32Regs:$dst, (bitreverse Int32Regs:$a))]>;
  1311. def BREV64 :
  1312. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a),
  1313. "brev.b64 \t$dst, $a;",
  1314. [(set Int64Regs:$dst, (bitreverse Int64Regs:$a))]>;
  1315. //
  1316. // Rotate: Use ptx shf instruction if available.
  1317. //
  1318. // 32 bit r2 = rotl r1, n
  1319. // =>
  1320. // r2 = shf.l r1, r1, n
  1321. def ROTL32imm_hw :
  1322. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, i32imm:$amt),
  1323. "shf.l.wrap.b32 \t$dst, $src, $src, $amt;",
  1324. [(set Int32Regs:$dst, (rotl Int32Regs:$src, (i32 imm:$amt)))]>,
  1325. Requires<[hasHWROT32]>;
  1326. def ROTL32reg_hw :
  1327. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, Int32Regs:$amt),
  1328. "shf.l.wrap.b32 \t$dst, $src, $src, $amt;",
  1329. [(set Int32Regs:$dst, (rotl Int32Regs:$src, Int32Regs:$amt))]>,
  1330. Requires<[hasHWROT32]>;
  1331. // 32 bit r2 = rotr r1, n
  1332. // =>
  1333. // r2 = shf.r r1, r1, n
  1334. def ROTR32imm_hw :
  1335. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, i32imm:$amt),
  1336. "shf.r.wrap.b32 \t$dst, $src, $src, $amt;",
  1337. [(set Int32Regs:$dst, (rotr Int32Regs:$src, (i32 imm:$amt)))]>,
  1338. Requires<[hasHWROT32]>;
  1339. def ROTR32reg_hw :
  1340. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, Int32Regs:$amt),
  1341. "shf.r.wrap.b32 \t$dst, $src, $src, $amt;",
  1342. [(set Int32Regs:$dst, (rotr Int32Regs:$src, Int32Regs:$amt))]>,
  1343. Requires<[hasHWROT32]>;
  1344. // 32-bit software rotate by immediate. $amt2 should equal 32 - $amt1.
  1345. def ROT32imm_sw :
  1346. NVPTXInst<(outs Int32Regs:$dst),
  1347. (ins Int32Regs:$src, i32imm:$amt1, i32imm:$amt2),
  1348. "{{\n\t"
  1349. ".reg .b32 %lhs;\n\t"
  1350. ".reg .b32 %rhs;\n\t"
  1351. "shl.b32 \t%lhs, $src, $amt1;\n\t"
  1352. "shr.b32 \t%rhs, $src, $amt2;\n\t"
  1353. "add.u32 \t$dst, %lhs, %rhs;\n\t"
  1354. "}}",
  1355. []>;
  1356. def SUB_FRM_32 : SDNodeXForm<imm, [{
  1357. return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N), MVT::i32);
  1358. }]>;
  1359. def : Pat<(rotl Int32Regs:$src, (i32 imm:$amt)),
  1360. (ROT32imm_sw Int32Regs:$src, imm:$amt, (SUB_FRM_32 node:$amt))>,
  1361. Requires<[noHWROT32]>;
  1362. def : Pat<(rotr Int32Regs:$src, (i32 imm:$amt)),
  1363. (ROT32imm_sw Int32Regs:$src, (SUB_FRM_32 node:$amt), imm:$amt)>,
  1364. Requires<[noHWROT32]>;
  1365. // 32-bit software rotate left by register.
  1366. def ROTL32reg_sw :
  1367. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, Int32Regs:$amt),
  1368. "{{\n\t"
  1369. ".reg .b32 %lhs;\n\t"
  1370. ".reg .b32 %rhs;\n\t"
  1371. ".reg .b32 %amt2;\n\t"
  1372. "shl.b32 \t%lhs, $src, $amt;\n\t"
  1373. "sub.s32 \t%amt2, 32, $amt;\n\t"
  1374. "shr.b32 \t%rhs, $src, %amt2;\n\t"
  1375. "add.u32 \t$dst, %lhs, %rhs;\n\t"
  1376. "}}",
  1377. [(set Int32Regs:$dst, (rotl Int32Regs:$src, Int32Regs:$amt))]>,
  1378. Requires<[noHWROT32]>;
  1379. // 32-bit software rotate right by register.
  1380. def ROTR32reg_sw :
  1381. NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, Int32Regs:$amt),
  1382. "{{\n\t"
  1383. ".reg .b32 %lhs;\n\t"
  1384. ".reg .b32 %rhs;\n\t"
  1385. ".reg .b32 %amt2;\n\t"
  1386. "shr.b32 \t%lhs, $src, $amt;\n\t"
  1387. "sub.s32 \t%amt2, 32, $amt;\n\t"
  1388. "shl.b32 \t%rhs, $src, %amt2;\n\t"
  1389. "add.u32 \t$dst, %lhs, %rhs;\n\t"
  1390. "}}",
  1391. [(set Int32Regs:$dst, (rotr Int32Regs:$src, Int32Regs:$amt))]>,
  1392. Requires<[noHWROT32]>;
  1393. // 64-bit software rotate by immediate. $amt2 should equal 64 - $amt1.
  1394. def ROT64imm_sw :
  1395. NVPTXInst<(outs Int64Regs:$dst),
  1396. (ins Int64Regs:$src, i32imm:$amt1, i32imm:$amt2),
  1397. "{{\n\t"
  1398. ".reg .b64 %lhs;\n\t"
  1399. ".reg .b64 %rhs;\n\t"
  1400. "shl.b64 \t%lhs, $src, $amt1;\n\t"
  1401. "shr.b64 \t%rhs, $src, $amt2;\n\t"
  1402. "add.u64 \t$dst, %lhs, %rhs;\n\t"
  1403. "}}",
  1404. []>;
  1405. def SUB_FRM_64 : SDNodeXForm<imm, [{
  1406. return CurDAG->getTargetConstant(64-N->getZExtValue(), SDLoc(N), MVT::i32);
  1407. }]>;
  1408. def : Pat<(rotl Int64Regs:$src, (i32 imm:$amt)),
  1409. (ROT64imm_sw Int64Regs:$src, imm:$amt, (SUB_FRM_64 node:$amt))>;
  1410. def : Pat<(rotr Int64Regs:$src, (i32 imm:$amt)),
  1411. (ROT64imm_sw Int64Regs:$src, (SUB_FRM_64 node:$amt), imm:$amt)>;
  1412. // 64-bit software rotate left by register.
  1413. def ROTL64reg_sw :
  1414. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src, Int32Regs:$amt),
  1415. "{{\n\t"
  1416. ".reg .b64 %lhs;\n\t"
  1417. ".reg .b64 %rhs;\n\t"
  1418. ".reg .u32 %amt2;\n\t"
  1419. "shl.b64 \t%lhs, $src, $amt;\n\t"
  1420. "sub.u32 \t%amt2, 64, $amt;\n\t"
  1421. "shr.b64 \t%rhs, $src, %amt2;\n\t"
  1422. "add.u64 \t$dst, %lhs, %rhs;\n\t"
  1423. "}}",
  1424. [(set Int64Regs:$dst, (rotl Int64Regs:$src, Int32Regs:$amt))]>;
  1425. def ROTR64reg_sw :
  1426. NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src, Int32Regs:$amt),
  1427. "{{\n\t"
  1428. ".reg .b64 %lhs;\n\t"
  1429. ".reg .b64 %rhs;\n\t"
  1430. ".reg .u32 %amt2;\n\t"
  1431. "shr.b64 \t%lhs, $src, $amt;\n\t"
  1432. "sub.u32 \t%amt2, 64, $amt;\n\t"
  1433. "shl.b64 \t%rhs, $src, %amt2;\n\t"
  1434. "add.u64 \t$dst, %lhs, %rhs;\n\t"
  1435. "}}",
  1436. [(set Int64Regs:$dst, (rotr Int64Regs:$src, Int32Regs:$amt))]>;
  1437. //
  1438. // Funnnel shift in clamp mode
  1439. //
  1440. // Create SDNodes so they can be used in the DAG code, e.g.
  1441. // NVPTXISelLowering (LowerShiftLeftParts and LowerShiftRightParts)
  1442. def FUN_SHFL_CLAMP : SDNode<"NVPTXISD::FUN_SHFL_CLAMP", SDTIntShiftDOp, []>;
  1443. def FUN_SHFR_CLAMP : SDNode<"NVPTXISD::FUN_SHFR_CLAMP", SDTIntShiftDOp, []>;
  1444. def FUNSHFLCLAMP :
  1445. NVPTXInst<(outs Int32Regs:$dst),
  1446. (ins Int32Regs:$lo, Int32Regs:$hi, Int32Regs:$amt),
  1447. "shf.l.clamp.b32 \t$dst, $lo, $hi, $amt;",
  1448. [(set Int32Regs:$dst,
  1449. (FUN_SHFL_CLAMP Int32Regs:$lo, Int32Regs:$hi, Int32Regs:$amt))]>;
  1450. def FUNSHFRCLAMP :
  1451. NVPTXInst<(outs Int32Regs:$dst),
  1452. (ins Int32Regs:$lo, Int32Regs:$hi, Int32Regs:$amt),
  1453. "shf.r.clamp.b32 \t$dst, $lo, $hi, $amt;",
  1454. [(set Int32Regs:$dst,
  1455. (FUN_SHFR_CLAMP Int32Regs:$lo, Int32Regs:$hi, Int32Regs:$amt))]>;
  1456. //
  1457. // BFE - bit-field extract
  1458. //
  1459. // Template for BFE instructions. Takes four args,
  1460. // [dest (reg), src (reg), start (reg or imm), end (reg or imm)].
  1461. // Start may be an imm only if end is also an imm. FIXME: Is this a
  1462. // restriction in PTX?
  1463. //
  1464. // dest and src may be int32 or int64, but start and end are always int32.
  1465. multiclass BFE<string TyStr, RegisterClass RC> {
  1466. def rrr
  1467. : NVPTXInst<(outs RC:$d),
  1468. (ins RC:$a, Int32Regs:$b, Int32Regs:$c),
  1469. !strconcat("bfe.", TyStr, " \t$d, $a, $b, $c;"), []>;
  1470. def rri
  1471. : NVPTXInst<(outs RC:$d),
  1472. (ins RC:$a, Int32Regs:$b, i32imm:$c),
  1473. !strconcat("bfe.", TyStr, " \t$d, $a, $b, $c;"), []>;
  1474. def rii
  1475. : NVPTXInst<(outs RC:$d),
  1476. (ins RC:$a, i32imm:$b, i32imm:$c),
  1477. !strconcat("bfe.", TyStr, " \t$d, $a, $b, $c;"), []>;
  1478. }
  1479. let hasSideEffects = false in {
  1480. defm BFE_S32 : BFE<"s32", Int32Regs>;
  1481. defm BFE_U32 : BFE<"u32", Int32Regs>;
  1482. defm BFE_S64 : BFE<"s64", Int64Regs>;
  1483. defm BFE_U64 : BFE<"u64", Int64Regs>;
  1484. }
  1485. //-----------------------------------
  1486. // Comparison instructions (setp, set)
  1487. //-----------------------------------
  1488. // FIXME: This doesn't cover versions of set and setp that combine with a
  1489. // boolean predicate, e.g. setp.eq.and.b16.
  1490. let hasSideEffects = false in {
  1491. multiclass SETP<string TypeStr, RegisterClass RC, Operand ImmCls> {
  1492. def rr :
  1493. NVPTXInst<(outs Int1Regs:$dst), (ins RC:$a, RC:$b, CmpMode:$cmp),
  1494. !strconcat("setp${cmp:base}${cmp:ftz}.", TypeStr,
  1495. " \t$dst, $a, $b;"), []>;
  1496. def ri :
  1497. NVPTXInst<(outs Int1Regs:$dst), (ins RC:$a, ImmCls:$b, CmpMode:$cmp),
  1498. !strconcat("setp${cmp:base}${cmp:ftz}.", TypeStr,
  1499. " \t$dst, $a, $b;"), []>;
  1500. def ir :
  1501. NVPTXInst<(outs Int1Regs:$dst), (ins ImmCls:$a, RC:$b, CmpMode:$cmp),
  1502. !strconcat("setp${cmp:base}${cmp:ftz}.", TypeStr,
  1503. " \t$dst, $a, $b;"), []>;
  1504. }
  1505. }
  1506. defm SETP_b16 : SETP<"b16", Int16Regs, i16imm>;
  1507. defm SETP_s16 : SETP<"s16", Int16Regs, i16imm>;
  1508. defm SETP_u16 : SETP<"u16", Int16Regs, i16imm>;
  1509. defm SETP_b32 : SETP<"b32", Int32Regs, i32imm>;
  1510. defm SETP_s32 : SETP<"s32", Int32Regs, i32imm>;
  1511. defm SETP_u32 : SETP<"u32", Int32Regs, i32imm>;
  1512. defm SETP_b64 : SETP<"b64", Int64Regs, i64imm>;
  1513. defm SETP_s64 : SETP<"s64", Int64Regs, i64imm>;
  1514. defm SETP_u64 : SETP<"u64", Int64Regs, i64imm>;
  1515. defm SETP_f32 : SETP<"f32", Float32Regs, f32imm>;
  1516. defm SETP_f64 : SETP<"f64", Float64Regs, f64imm>;
  1517. def SETP_f16rr :
  1518. NVPTXInst<(outs Int1Regs:$dst),
  1519. (ins Float16Regs:$a, Float16Regs:$b, CmpMode:$cmp),
  1520. "setp${cmp:base}${cmp:ftz}.f16 \t$dst, $a, $b;",
  1521. []>, Requires<[useFP16Math]>;
  1522. def SETP_f16x2rr :
  1523. NVPTXInst<(outs Int1Regs:$p, Int1Regs:$q),
  1524. (ins Float16x2Regs:$a, Float16x2Regs:$b, CmpMode:$cmp),
  1525. "setp${cmp:base}${cmp:ftz}.f16x2 \t$p|$q, $a, $b;",
  1526. []>,
  1527. Requires<[useFP16Math]>;
  1528. // FIXME: This doesn't appear to be correct. The "set" mnemonic has the form
  1529. // "set.CmpOp{.ftz}.dtype.stype", where dtype is the type of the destination
  1530. // reg, either u32, s32, or f32. Anyway these aren't used at the moment.
  1531. let hasSideEffects = false in {
  1532. multiclass SET<string TypeStr, RegisterClass RC, Operand ImmCls> {
  1533. def rr : NVPTXInst<(outs Int32Regs:$dst),
  1534. (ins RC:$a, RC:$b, CmpMode:$cmp),
  1535. !strconcat("set$cmp.", TypeStr, " \t$dst, $a, $b;"), []>;
  1536. def ri : NVPTXInst<(outs Int32Regs:$dst),
  1537. (ins RC:$a, ImmCls:$b, CmpMode:$cmp),
  1538. !strconcat("set$cmp.", TypeStr, " \t$dst, $a, $b;"), []>;
  1539. def ir : NVPTXInst<(outs Int32Regs:$dst),
  1540. (ins ImmCls:$a, RC:$b, CmpMode:$cmp),
  1541. !strconcat("set$cmp.", TypeStr, " \t$dst, $a, $b;"), []>;
  1542. }
  1543. }
  1544. defm SET_b16 : SET<"b16", Int16Regs, i16imm>;
  1545. defm SET_s16 : SET<"s16", Int16Regs, i16imm>;
  1546. defm SET_u16 : SET<"u16", Int16Regs, i16imm>;
  1547. defm SET_b32 : SET<"b32", Int32Regs, i32imm>;
  1548. defm SET_s32 : SET<"s32", Int32Regs, i32imm>;
  1549. defm SET_u32 : SET<"u32", Int32Regs, i32imm>;
  1550. defm SET_b64 : SET<"b64", Int64Regs, i64imm>;
  1551. defm SET_s64 : SET<"s64", Int64Regs, i64imm>;
  1552. defm SET_u64 : SET<"u64", Int64Regs, i64imm>;
  1553. defm SET_f16 : SET<"f16", Float16Regs, f16imm>;
  1554. defm SET_f32 : SET<"f32", Float32Regs, f32imm>;
  1555. defm SET_f64 : SET<"f64", Float64Regs, f64imm>;
  1556. //-----------------------------------
  1557. // Data Movement (Load / Store, Move)
  1558. //-----------------------------------
  1559. def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [frameindex],
  1560. [SDNPWantRoot]>;
  1561. def ADDRri64 : ComplexPattern<i64, 2, "SelectADDRri64", [frameindex],
  1562. [SDNPWantRoot]>;
  1563. def ADDRvar : ComplexPattern<iPTR, 1, "SelectDirectAddr", [], []>;
  1564. def MEMri : Operand<i32> {
  1565. let PrintMethod = "printMemOperand";
  1566. let MIOperandInfo = (ops Int32Regs, i32imm);
  1567. }
  1568. def MEMri64 : Operand<i64> {
  1569. let PrintMethod = "printMemOperand";
  1570. let MIOperandInfo = (ops Int64Regs, i64imm);
  1571. }
  1572. def imem : Operand<iPTR> {
  1573. let PrintMethod = "printOperand";
  1574. }
  1575. def imemAny : Operand<iPTRAny> {
  1576. let PrintMethod = "printOperand";
  1577. }
  1578. def LdStCode : Operand<i32> {
  1579. let PrintMethod = "printLdStCode";
  1580. }
  1581. def MmaCode : Operand<i32> {
  1582. let PrintMethod = "printMmaCode";
  1583. }
  1584. def SDTWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
  1585. def Wrapper : SDNode<"NVPTXISD::Wrapper", SDTWrapper>;
  1586. // Load a memory address into a u32 or u64 register.
  1587. def MOV_ADDR : NVPTXInst<(outs Int32Regs:$dst), (ins imem:$a),
  1588. "mov.u32 \t$dst, $a;",
  1589. [(set Int32Regs:$dst, (Wrapper tglobaladdr:$a))]>;
  1590. def MOV_ADDR64 : NVPTXInst<(outs Int64Regs:$dst), (ins imem:$a),
  1591. "mov.u64 \t$dst, $a;",
  1592. [(set Int64Regs:$dst, (Wrapper tglobaladdr:$a))]>;
  1593. // Get pointer to local stack.
  1594. let hasSideEffects = false in {
  1595. def MOV_DEPOT_ADDR : NVPTXInst<(outs Int32Regs:$d), (ins i32imm:$num),
  1596. "mov.u32 \t$d, __local_depot$num;", []>;
  1597. def MOV_DEPOT_ADDR_64 : NVPTXInst<(outs Int64Regs:$d), (ins i32imm:$num),
  1598. "mov.u64 \t$d, __local_depot$num;", []>;
  1599. }
  1600. // copyPhysreg is hard-coded in NVPTXInstrInfo.cpp
  1601. let IsSimpleMove=1, hasSideEffects=0 in {
  1602. def IMOV1rr : NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$sss),
  1603. "mov.pred \t$dst, $sss;", []>;
  1604. def IMOV16rr : NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$sss),
  1605. "mov.u16 \t$dst, $sss;", []>;
  1606. def IMOV32rr : NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$sss),
  1607. "mov.u32 \t$dst, $sss;", []>;
  1608. def IMOV64rr : NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$sss),
  1609. "mov.u64 \t$dst, $sss;", []>;
  1610. def FMOV16rr : NVPTXInst<(outs Float16Regs:$dst), (ins Float16Regs:$src),
  1611. // We have to use .b16 here as there's no mov.f16.
  1612. "mov.b16 \t$dst, $src;", []>;
  1613. def FMOV32rr : NVPTXInst<(outs Float32Regs:$dst), (ins Float32Regs:$src),
  1614. "mov.f32 \t$dst, $src;", []>;
  1615. def FMOV64rr : NVPTXInst<(outs Float64Regs:$dst), (ins Float64Regs:$src),
  1616. "mov.f64 \t$dst, $src;", []>;
  1617. }
  1618. def IMOV1ri : NVPTXInst<(outs Int1Regs:$dst), (ins i1imm:$src),
  1619. "mov.pred \t$dst, $src;",
  1620. [(set Int1Regs:$dst, imm:$src)]>;
  1621. def IMOV16ri : NVPTXInst<(outs Int16Regs:$dst), (ins i16imm:$src),
  1622. "mov.u16 \t$dst, $src;",
  1623. [(set Int16Regs:$dst, imm:$src)]>;
  1624. def IMOV32ri : NVPTXInst<(outs Int32Regs:$dst), (ins i32imm:$src),
  1625. "mov.u32 \t$dst, $src;",
  1626. [(set Int32Regs:$dst, imm:$src)]>;
  1627. def IMOV64ri : NVPTXInst<(outs Int64Regs:$dst), (ins i64imm:$src),
  1628. "mov.u64 \t$dst, $src;",
  1629. [(set Int64Regs:$dst, imm:$src)]>;
  1630. def FMOV32ri : NVPTXInst<(outs Float32Regs:$dst), (ins f32imm:$src),
  1631. "mov.f32 \t$dst, $src;",
  1632. [(set Float32Regs:$dst, fpimm:$src)]>;
  1633. def FMOV64ri : NVPTXInst<(outs Float64Regs:$dst), (ins f64imm:$src),
  1634. "mov.f64 \t$dst, $src;",
  1635. [(set Float64Regs:$dst, fpimm:$src)]>;
  1636. def : Pat<(i32 (Wrapper texternalsym:$dst)), (IMOV32ri texternalsym:$dst)>;
  1637. def : Pat<(i64 (Wrapper texternalsym:$dst)), (IMOV64ri texternalsym:$dst)>;
  1638. //---- Copy Frame Index ----
  1639. def LEA_ADDRi : NVPTXInst<(outs Int32Regs:$dst), (ins MEMri:$addr),
  1640. "add.u32 \t$dst, ${addr:add};",
  1641. [(set Int32Regs:$dst, ADDRri:$addr)]>;
  1642. def LEA_ADDRi64 : NVPTXInst<(outs Int64Regs:$dst), (ins MEMri64:$addr),
  1643. "add.u64 \t$dst, ${addr:add};",
  1644. [(set Int64Regs:$dst, ADDRri64:$addr)]>;
  1645. //-----------------------------------
  1646. // Comparison and Selection
  1647. //-----------------------------------
  1648. multiclass ISET_FORMAT<PatFrag OpNode, PatLeaf Mode,
  1649. Instruction setp_16rr,
  1650. Instruction setp_16ri,
  1651. Instruction setp_16ir,
  1652. Instruction setp_32rr,
  1653. Instruction setp_32ri,
  1654. Instruction setp_32ir,
  1655. Instruction setp_64rr,
  1656. Instruction setp_64ri,
  1657. Instruction setp_64ir,
  1658. Instruction set_16rr,
  1659. Instruction set_16ri,
  1660. Instruction set_16ir,
  1661. Instruction set_32rr,
  1662. Instruction set_32ri,
  1663. Instruction set_32ir,
  1664. Instruction set_64rr,
  1665. Instruction set_64ri,
  1666. Instruction set_64ir> {
  1667. // i16 -> pred
  1668. def : Pat<(i1 (OpNode Int16Regs:$a, Int16Regs:$b)),
  1669. (setp_16rr Int16Regs:$a, Int16Regs:$b, Mode)>;
  1670. def : Pat<(i1 (OpNode Int16Regs:$a, imm:$b)),
  1671. (setp_16ri Int16Regs:$a, imm:$b, Mode)>;
  1672. def : Pat<(i1 (OpNode imm:$a, Int16Regs:$b)),
  1673. (setp_16ir imm:$a, Int16Regs:$b, Mode)>;
  1674. // i32 -> pred
  1675. def : Pat<(i1 (OpNode Int32Regs:$a, Int32Regs:$b)),
  1676. (setp_32rr Int32Regs:$a, Int32Regs:$b, Mode)>;
  1677. def : Pat<(i1 (OpNode Int32Regs:$a, imm:$b)),
  1678. (setp_32ri Int32Regs:$a, imm:$b, Mode)>;
  1679. def : Pat<(i1 (OpNode imm:$a, Int32Regs:$b)),
  1680. (setp_32ir imm:$a, Int32Regs:$b, Mode)>;
  1681. // i64 -> pred
  1682. def : Pat<(i1 (OpNode Int64Regs:$a, Int64Regs:$b)),
  1683. (setp_64rr Int64Regs:$a, Int64Regs:$b, Mode)>;
  1684. def : Pat<(i1 (OpNode Int64Regs:$a, imm:$b)),
  1685. (setp_64ri Int64Regs:$a, imm:$b, Mode)>;
  1686. def : Pat<(i1 (OpNode imm:$a, Int64Regs:$b)),
  1687. (setp_64ir imm:$a, Int64Regs:$b, Mode)>;
  1688. // i16 -> i32
  1689. def : Pat<(i32 (OpNode Int16Regs:$a, Int16Regs:$b)),
  1690. (set_16rr Int16Regs:$a, Int16Regs:$b, Mode)>;
  1691. def : Pat<(i32 (OpNode Int16Regs:$a, imm:$b)),
  1692. (set_16ri Int16Regs:$a, imm:$b, Mode)>;
  1693. def : Pat<(i32 (OpNode imm:$a, Int16Regs:$b)),
  1694. (set_16ir imm:$a, Int16Regs:$b, Mode)>;
  1695. // i32 -> i32
  1696. def : Pat<(i32 (OpNode Int32Regs:$a, Int32Regs:$b)),
  1697. (set_32rr Int32Regs:$a, Int32Regs:$b, Mode)>;
  1698. def : Pat<(i32 (OpNode Int32Regs:$a, imm:$b)),
  1699. (set_32ri Int32Regs:$a, imm:$b, Mode)>;
  1700. def : Pat<(i32 (OpNode imm:$a, Int32Regs:$b)),
  1701. (set_32ir imm:$a, Int32Regs:$b, Mode)>;
  1702. // i64 -> i32
  1703. def : Pat<(i32 (OpNode Int64Regs:$a, Int64Regs:$b)),
  1704. (set_64rr Int64Regs:$a, Int64Regs:$b, Mode)>;
  1705. def : Pat<(i32 (OpNode Int64Regs:$a, imm:$b)),
  1706. (set_64ri Int64Regs:$a, imm:$b, Mode)>;
  1707. def : Pat<(i32 (OpNode imm:$a, Int64Regs:$b)),
  1708. (set_64ir imm:$a, Int64Regs:$b, Mode)>;
  1709. }
  1710. multiclass ISET_FORMAT_SIGNED<PatFrag OpNode, PatLeaf Mode>
  1711. : ISET_FORMAT<OpNode, Mode,
  1712. SETP_s16rr, SETP_s16ri, SETP_s16ir,
  1713. SETP_s32rr, SETP_s32ri, SETP_s32ir,
  1714. SETP_s64rr, SETP_s64ri, SETP_s64ir,
  1715. SET_s16rr, SET_s16ri, SET_s16ir,
  1716. SET_s32rr, SET_s32ri, SET_s32ir,
  1717. SET_s64rr, SET_s64ri, SET_s64ir> {
  1718. // TableGen doesn't like empty multiclasses.
  1719. def : PatLeaf<(i32 0)>;
  1720. }
  1721. multiclass ISET_FORMAT_UNSIGNED<PatFrag OpNode, PatLeaf Mode>
  1722. : ISET_FORMAT<OpNode, Mode,
  1723. SETP_u16rr, SETP_u16ri, SETP_u16ir,
  1724. SETP_u32rr, SETP_u32ri, SETP_u32ir,
  1725. SETP_u64rr, SETP_u64ri, SETP_u64ir,
  1726. SET_u16rr, SET_u16ri, SET_u16ir,
  1727. SET_u32rr, SET_u32ri, SET_u32ir,
  1728. SET_u64rr, SET_u64ri, SET_u64ir> {
  1729. // TableGen doesn't like empty multiclasses.
  1730. def : PatLeaf<(i32 0)>;
  1731. }
  1732. defm : ISET_FORMAT_SIGNED<setgt, CmpGT>;
  1733. defm : ISET_FORMAT_SIGNED<setlt, CmpLT>;
  1734. defm : ISET_FORMAT_SIGNED<setge, CmpGE>;
  1735. defm : ISET_FORMAT_SIGNED<setle, CmpLE>;
  1736. defm : ISET_FORMAT_SIGNED<seteq, CmpEQ>;
  1737. defm : ISET_FORMAT_SIGNED<setne, CmpNE>;
  1738. defm : ISET_FORMAT_UNSIGNED<setugt, CmpGT>;
  1739. defm : ISET_FORMAT_UNSIGNED<setult, CmpLT>;
  1740. defm : ISET_FORMAT_UNSIGNED<setuge, CmpGE>;
  1741. defm : ISET_FORMAT_UNSIGNED<setule, CmpLE>;
  1742. defm : ISET_FORMAT_UNSIGNED<setueq, CmpEQ>;
  1743. defm : ISET_FORMAT_UNSIGNED<setune, CmpNE>;
  1744. // i1 compares
  1745. def : Pat<(setne Int1Regs:$a, Int1Regs:$b),
  1746. (XORb1rr Int1Regs:$a, Int1Regs:$b)>;
  1747. def : Pat<(setune Int1Regs:$a, Int1Regs:$b),
  1748. (XORb1rr Int1Regs:$a, Int1Regs:$b)>;
  1749. def : Pat<(seteq Int1Regs:$a, Int1Regs:$b),
  1750. (NOT1 (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
  1751. def : Pat<(setueq Int1Regs:$a, Int1Regs:$b),
  1752. (NOT1 (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
  1753. // i1 compare -> i32
  1754. def : Pat<(i32 (setne Int1Regs:$a, Int1Regs:$b)),
  1755. (SELP_u32ii -1, 0, (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
  1756. def : Pat<(i32 (setne Int1Regs:$a, Int1Regs:$b)),
  1757. (SELP_u32ii 0, -1, (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
  1758. multiclass FSET_FORMAT<PatFrag OpNode, PatLeaf Mode, PatLeaf ModeFTZ> {
  1759. // f16 -> pred
  1760. def : Pat<(i1 (OpNode (f16 Float16Regs:$a), (f16 Float16Regs:$b))),
  1761. (SETP_f16rr Float16Regs:$a, Float16Regs:$b, ModeFTZ)>,
  1762. Requires<[useFP16Math,doF32FTZ]>;
  1763. def : Pat<(i1 (OpNode (f16 Float16Regs:$a), (f16 Float16Regs:$b))),
  1764. (SETP_f16rr Float16Regs:$a, Float16Regs:$b, Mode)>,
  1765. Requires<[useFP16Math]>;
  1766. def : Pat<(i1 (OpNode (f16 Float16Regs:$a), fpimm:$b)),
  1767. (SETP_f16rr Float16Regs:$a, (LOAD_CONST_F16 fpimm:$b), ModeFTZ)>,
  1768. Requires<[useFP16Math,doF32FTZ]>;
  1769. def : Pat<(i1 (OpNode (f16 Float16Regs:$a), fpimm:$b)),
  1770. (SETP_f16rr Float16Regs:$a, (LOAD_CONST_F16 fpimm:$b), Mode)>,
  1771. Requires<[useFP16Math]>;
  1772. def : Pat<(i1 (OpNode fpimm:$a, (f16 Float16Regs:$b))),
  1773. (SETP_f16rr (LOAD_CONST_F16 fpimm:$a), Float16Regs:$b, ModeFTZ)>,
  1774. Requires<[useFP16Math,doF32FTZ]>;
  1775. def : Pat<(i1 (OpNode fpimm:$a, (f16 Float16Regs:$b))),
  1776. (SETP_f16rr (LOAD_CONST_F16 fpimm:$a), Float16Regs:$b, Mode)>,
  1777. Requires<[useFP16Math]>;
  1778. // f32 -> pred
  1779. def : Pat<(i1 (OpNode Float32Regs:$a, Float32Regs:$b)),
  1780. (SETP_f32rr Float32Regs:$a, Float32Regs:$b, ModeFTZ)>,
  1781. Requires<[doF32FTZ]>;
  1782. def : Pat<(i1 (OpNode Float32Regs:$a, Float32Regs:$b)),
  1783. (SETP_f32rr Float32Regs:$a, Float32Regs:$b, Mode)>;
  1784. def : Pat<(i1 (OpNode Float32Regs:$a, fpimm:$b)),
  1785. (SETP_f32ri Float32Regs:$a, fpimm:$b, ModeFTZ)>,
  1786. Requires<[doF32FTZ]>;
  1787. def : Pat<(i1 (OpNode Float32Regs:$a, fpimm:$b)),
  1788. (SETP_f32ri Float32Regs:$a, fpimm:$b, Mode)>;
  1789. def : Pat<(i1 (OpNode fpimm:$a, Float32Regs:$b)),
  1790. (SETP_f32ir fpimm:$a, Float32Regs:$b, ModeFTZ)>,
  1791. Requires<[doF32FTZ]>;
  1792. def : Pat<(i1 (OpNode fpimm:$a, Float32Regs:$b)),
  1793. (SETP_f32ir fpimm:$a, Float32Regs:$b, Mode)>;
  1794. // f64 -> pred
  1795. def : Pat<(i1 (OpNode Float64Regs:$a, Float64Regs:$b)),
  1796. (SETP_f64rr Float64Regs:$a, Float64Regs:$b, Mode)>;
  1797. def : Pat<(i1 (OpNode Float64Regs:$a, fpimm:$b)),
  1798. (SETP_f64ri Float64Regs:$a, fpimm:$b, Mode)>;
  1799. def : Pat<(i1 (OpNode fpimm:$a, Float64Regs:$b)),
  1800. (SETP_f64ir fpimm:$a, Float64Regs:$b, Mode)>;
  1801. // f16 -> i32
  1802. def : Pat<(i32 (OpNode (f16 Float16Regs:$a), (f16 Float16Regs:$b))),
  1803. (SET_f16rr Float16Regs:$a, Float16Regs:$b, ModeFTZ)>,
  1804. Requires<[useFP16Math, doF32FTZ]>;
  1805. def : Pat<(i32 (OpNode (f16 Float16Regs:$a), (f16 Float16Regs:$b))),
  1806. (SET_f16rr Float16Regs:$a, Float16Regs:$b, Mode)>,
  1807. Requires<[useFP16Math]>;
  1808. def : Pat<(i32 (OpNode (f16 Float16Regs:$a), fpimm:$b)),
  1809. (SET_f16rr Float16Regs:$a, (LOAD_CONST_F16 fpimm:$b), ModeFTZ)>,
  1810. Requires<[useFP16Math, doF32FTZ]>;
  1811. def : Pat<(i32 (OpNode (f16 Float16Regs:$a), fpimm:$b)),
  1812. (SET_f16rr Float16Regs:$a, (LOAD_CONST_F16 fpimm:$b), Mode)>,
  1813. Requires<[useFP16Math]>;
  1814. def : Pat<(i32 (OpNode fpimm:$a, (f16 Float16Regs:$b))),
  1815. (SET_f16ir (LOAD_CONST_F16 fpimm:$a), Float16Regs:$b, ModeFTZ)>,
  1816. Requires<[useFP16Math, doF32FTZ]>;
  1817. def : Pat<(i32 (OpNode fpimm:$a, (f16 Float16Regs:$b))),
  1818. (SET_f16ir (LOAD_CONST_F16 fpimm:$a), Float16Regs:$b, Mode)>,
  1819. Requires<[useFP16Math]>;
  1820. // f32 -> i32
  1821. def : Pat<(i32 (OpNode Float32Regs:$a, Float32Regs:$b)),
  1822. (SET_f32rr Float32Regs:$a, Float32Regs:$b, ModeFTZ)>,
  1823. Requires<[doF32FTZ]>;
  1824. def : Pat<(i32 (OpNode Float32Regs:$a, Float32Regs:$b)),
  1825. (SET_f32rr Float32Regs:$a, Float32Regs:$b, Mode)>;
  1826. def : Pat<(i32 (OpNode Float32Regs:$a, fpimm:$b)),
  1827. (SET_f32ri Float32Regs:$a, fpimm:$b, ModeFTZ)>,
  1828. Requires<[doF32FTZ]>;
  1829. def : Pat<(i32 (OpNode Float32Regs:$a, fpimm:$b)),
  1830. (SET_f32ri Float32Regs:$a, fpimm:$b, Mode)>;
  1831. def : Pat<(i32 (OpNode fpimm:$a, Float32Regs:$b)),
  1832. (SET_f32ir fpimm:$a, Float32Regs:$b, ModeFTZ)>,
  1833. Requires<[doF32FTZ]>;
  1834. def : Pat<(i32 (OpNode fpimm:$a, Float32Regs:$b)),
  1835. (SET_f32ir fpimm:$a, Float32Regs:$b, Mode)>;
  1836. // f64 -> i32
  1837. def : Pat<(i32 (OpNode Float64Regs:$a, Float64Regs:$b)),
  1838. (SET_f64rr Float64Regs:$a, Float64Regs:$b, Mode)>;
  1839. def : Pat<(i32 (OpNode Float64Regs:$a, fpimm:$b)),
  1840. (SET_f64ri Float64Regs:$a, fpimm:$b, Mode)>;
  1841. def : Pat<(i32 (OpNode fpimm:$a, Float64Regs:$b)),
  1842. (SET_f64ir fpimm:$a, Float64Regs:$b, Mode)>;
  1843. }
  1844. defm FSetOGT : FSET_FORMAT<setogt, CmpGT, CmpGT_FTZ>;
  1845. defm FSetOLT : FSET_FORMAT<setolt, CmpLT, CmpLT_FTZ>;
  1846. defm FSetOGE : FSET_FORMAT<setoge, CmpGE, CmpGE_FTZ>;
  1847. defm FSetOLE : FSET_FORMAT<setole, CmpLE, CmpLE_FTZ>;
  1848. defm FSetOEQ : FSET_FORMAT<setoeq, CmpEQ, CmpEQ_FTZ>;
  1849. defm FSetONE : FSET_FORMAT<setone, CmpNE, CmpNE_FTZ>;
  1850. defm FSetUGT : FSET_FORMAT<setugt, CmpGTU, CmpGTU_FTZ>;
  1851. defm FSetULT : FSET_FORMAT<setult, CmpLTU, CmpLTU_FTZ>;
  1852. defm FSetUGE : FSET_FORMAT<setuge, CmpGEU, CmpGEU_FTZ>;
  1853. defm FSetULE : FSET_FORMAT<setule, CmpLEU, CmpLEU_FTZ>;
  1854. defm FSetUEQ : FSET_FORMAT<setueq, CmpEQU, CmpEQU_FTZ>;
  1855. defm FSetUNE : FSET_FORMAT<setune, CmpNEU, CmpNEU_FTZ>;
  1856. defm FSetGT : FSET_FORMAT<setgt, CmpGT, CmpGT_FTZ>;
  1857. defm FSetLT : FSET_FORMAT<setlt, CmpLT, CmpLT_FTZ>;
  1858. defm FSetGE : FSET_FORMAT<setge, CmpGE, CmpGE_FTZ>;
  1859. defm FSetLE : FSET_FORMAT<setle, CmpLE, CmpLE_FTZ>;
  1860. defm FSetEQ : FSET_FORMAT<seteq, CmpEQ, CmpEQ_FTZ>;
  1861. defm FSetNE : FSET_FORMAT<setne, CmpNE, CmpNE_FTZ>;
  1862. defm FSetNUM : FSET_FORMAT<seto, CmpNUM, CmpNUM_FTZ>;
  1863. defm FSetNAN : FSET_FORMAT<setuo, CmpNAN, CmpNAN_FTZ>;
  1864. // FIXME: What is this doing here? Can it be deleted?
  1865. // def ld_param : SDNode<"NVPTXISD::LOAD_PARAM", SDTLoad,
  1866. // [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
  1867. def SDTDeclareParamProfile :
  1868. SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
  1869. def SDTDeclareScalarParamProfile :
  1870. SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
  1871. def SDTLoadParamProfile : SDTypeProfile<1, 2, [SDTCisInt<1>, SDTCisInt<2>]>;
  1872. def SDTLoadParamV2Profile : SDTypeProfile<2, 2, [SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisInt<3>]>;
  1873. def SDTLoadParamV4Profile : SDTypeProfile<4, 2, [SDTCisInt<4>, SDTCisInt<5>]>;
  1874. def SDTPrintCallProfile : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
  1875. def SDTPrintCallUniProfile : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
  1876. def SDTStoreParamProfile : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>]>;
  1877. def SDTStoreParamV2Profile : SDTypeProfile<0, 4, [SDTCisInt<0>, SDTCisInt<1>]>;
  1878. def SDTStoreParamV4Profile : SDTypeProfile<0, 6, [SDTCisInt<0>, SDTCisInt<1>]>;
  1879. def SDTStoreParam32Profile : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>]>;
  1880. def SDTCallArgProfile : SDTypeProfile<0, 2, [SDTCisInt<0>]>;
  1881. def SDTCallArgMarkProfile : SDTypeProfile<0, 0, []>;
  1882. def SDTCallVoidProfile : SDTypeProfile<0, 1, []>;
  1883. def SDTCallValProfile : SDTypeProfile<1, 0, []>;
  1884. def SDTMoveParamProfile : SDTypeProfile<1, 1, []>;
  1885. def SDTStoreRetvalProfile : SDTypeProfile<0, 2, [SDTCisInt<0>]>;
  1886. def SDTStoreRetvalV2Profile : SDTypeProfile<0, 3, [SDTCisInt<0>]>;
  1887. def SDTStoreRetvalV4Profile : SDTypeProfile<0, 5, [SDTCisInt<0>]>;
  1888. def SDTPseudoUseParamProfile : SDTypeProfile<0, 1, []>;
  1889. def SDTProxyRegProfile : SDTypeProfile<1, 1, []>;
  1890. def DeclareParam :
  1891. SDNode<"NVPTXISD::DeclareParam", SDTDeclareParamProfile,
  1892. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1893. def DeclareScalarParam :
  1894. SDNode<"NVPTXISD::DeclareScalarParam", SDTDeclareScalarParamProfile,
  1895. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1896. def DeclareRetParam :
  1897. SDNode<"NVPTXISD::DeclareRetParam", SDTDeclareParamProfile,
  1898. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1899. def DeclareRet :
  1900. SDNode<"NVPTXISD::DeclareRet", SDTDeclareScalarParamProfile,
  1901. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1902. def LoadParam :
  1903. SDNode<"NVPTXISD::LoadParam", SDTLoadParamProfile,
  1904. [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
  1905. def LoadParamV2 :
  1906. SDNode<"NVPTXISD::LoadParamV2", SDTLoadParamV2Profile,
  1907. [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
  1908. def LoadParamV4 :
  1909. SDNode<"NVPTXISD::LoadParamV4", SDTLoadParamV4Profile,
  1910. [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
  1911. def PrintCall :
  1912. SDNode<"NVPTXISD::PrintCall", SDTPrintCallProfile,
  1913. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1914. def PrintConvergentCall :
  1915. SDNode<"NVPTXISD::PrintConvergentCall", SDTPrintCallProfile,
  1916. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1917. def PrintCallUni :
  1918. SDNode<"NVPTXISD::PrintCallUni", SDTPrintCallUniProfile,
  1919. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1920. def PrintConvergentCallUni :
  1921. SDNode<"NVPTXISD::PrintConvergentCallUni", SDTPrintCallUniProfile,
  1922. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1923. def StoreParam :
  1924. SDNode<"NVPTXISD::StoreParam", SDTStoreParamProfile,
  1925. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1926. def StoreParamV2 :
  1927. SDNode<"NVPTXISD::StoreParamV2", SDTStoreParamV2Profile,
  1928. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1929. def StoreParamV4 :
  1930. SDNode<"NVPTXISD::StoreParamV4", SDTStoreParamV4Profile,
  1931. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1932. def StoreParamU32 :
  1933. SDNode<"NVPTXISD::StoreParamU32", SDTStoreParam32Profile,
  1934. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1935. def StoreParamS32 :
  1936. SDNode<"NVPTXISD::StoreParamS32", SDTStoreParam32Profile,
  1937. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1938. def CallArgBegin :
  1939. SDNode<"NVPTXISD::CallArgBegin", SDTCallArgMarkProfile,
  1940. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1941. def CallArg :
  1942. SDNode<"NVPTXISD::CallArg", SDTCallArgProfile,
  1943. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1944. def LastCallArg :
  1945. SDNode<"NVPTXISD::LastCallArg", SDTCallArgProfile,
  1946. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1947. def CallArgEnd :
  1948. SDNode<"NVPTXISD::CallArgEnd", SDTCallVoidProfile,
  1949. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1950. def CallVoid :
  1951. SDNode<"NVPTXISD::CallVoid", SDTCallVoidProfile,
  1952. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1953. def Prototype :
  1954. SDNode<"NVPTXISD::Prototype", SDTCallVoidProfile,
  1955. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1956. def CallVal :
  1957. SDNode<"NVPTXISD::CallVal", SDTCallValProfile,
  1958. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1959. def MoveParam :
  1960. SDNode<"NVPTXISD::MoveParam", SDTMoveParamProfile, []>;
  1961. def StoreRetval :
  1962. SDNode<"NVPTXISD::StoreRetval", SDTStoreRetvalProfile,
  1963. [SDNPHasChain, SDNPSideEffect]>;
  1964. def StoreRetvalV2 :
  1965. SDNode<"NVPTXISD::StoreRetvalV2", SDTStoreRetvalV2Profile,
  1966. [SDNPHasChain, SDNPSideEffect]>;
  1967. def StoreRetvalV4 :
  1968. SDNode<"NVPTXISD::StoreRetvalV4", SDTStoreRetvalV4Profile,
  1969. [SDNPHasChain, SDNPSideEffect]>;
  1970. def PseudoUseParam :
  1971. SDNode<"NVPTXISD::PseudoUseParam", SDTPseudoUseParamProfile,
  1972. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1973. def RETURNNode :
  1974. SDNode<"NVPTXISD::RETURN", SDTCallArgMarkProfile,
  1975. [SDNPHasChain, SDNPSideEffect]>;
  1976. def ProxyReg :
  1977. SDNode<"NVPTXISD::ProxyReg", SDTProxyRegProfile,
  1978. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  1979. let mayLoad = true in {
  1980. class LoadParamMemInst<NVPTXRegClass regclass, string opstr> :
  1981. NVPTXInst<(outs regclass:$dst), (ins i32imm:$b),
  1982. !strconcat("ld.param", opstr, " \t$dst, [retval0+$b];"),
  1983. []>;
  1984. class LoadParamV2MemInst<NVPTXRegClass regclass, string opstr> :
  1985. NVPTXInst<(outs regclass:$dst, regclass:$dst2), (ins i32imm:$b),
  1986. !strconcat("ld.param.v2", opstr,
  1987. " \t{{$dst, $dst2}}, [retval0+$b];"), []>;
  1988. class LoadParamV4MemInst<NVPTXRegClass regclass, string opstr> :
  1989. NVPTXInst<(outs regclass:$dst, regclass:$dst2, regclass:$dst3,
  1990. regclass:$dst4),
  1991. (ins i32imm:$b),
  1992. !strconcat("ld.param.v4", opstr,
  1993. " \t{{$dst, $dst2, $dst3, $dst4}}, [retval0+$b];"),
  1994. []>;
  1995. }
  1996. class LoadParamRegInst<NVPTXRegClass regclass, string opstr> :
  1997. NVPTXInst<(outs regclass:$dst), (ins i32imm:$b),
  1998. !strconcat("mov", opstr, " \t$dst, retval$b;"),
  1999. [(set regclass:$dst, (LoadParam (i32 0), (i32 imm:$b)))]>;
  2000. let mayStore = true in {
  2001. class StoreParamInst<NVPTXRegClass regclass, string opstr> :
  2002. NVPTXInst<(outs), (ins regclass:$val, i32imm:$a, i32imm:$b),
  2003. !strconcat("st.param", opstr, " \t[param$a+$b], $val;"),
  2004. []>;
  2005. class StoreParamV2Inst<NVPTXRegClass regclass, string opstr> :
  2006. NVPTXInst<(outs), (ins regclass:$val, regclass:$val2,
  2007. i32imm:$a, i32imm:$b),
  2008. !strconcat("st.param.v2", opstr,
  2009. " \t[param$a+$b], {{$val, $val2}};"),
  2010. []>;
  2011. class StoreParamV4Inst<NVPTXRegClass regclass, string opstr> :
  2012. NVPTXInst<(outs), (ins regclass:$val, regclass:$val2, regclass:$val3,
  2013. regclass:$val4, i32imm:$a,
  2014. i32imm:$b),
  2015. !strconcat("st.param.v4", opstr,
  2016. " \t[param$a+$b], {{$val, $val2, $val3, $val4}};"),
  2017. []>;
  2018. class StoreRetvalInst<NVPTXRegClass regclass, string opstr> :
  2019. NVPTXInst<(outs), (ins regclass:$val, i32imm:$a),
  2020. !strconcat("st.param", opstr, " \t[func_retval0+$a], $val;"),
  2021. []>;
  2022. class StoreRetvalV2Inst<NVPTXRegClass regclass, string opstr> :
  2023. NVPTXInst<(outs), (ins regclass:$val, regclass:$val2, i32imm:$a),
  2024. !strconcat("st.param.v2", opstr,
  2025. " \t[func_retval0+$a], {{$val, $val2}};"),
  2026. []>;
  2027. class StoreRetvalV4Inst<NVPTXRegClass regclass, string opstr> :
  2028. NVPTXInst<(outs),
  2029. (ins regclass:$val, regclass:$val2, regclass:$val3,
  2030. regclass:$val4, i32imm:$a),
  2031. !strconcat("st.param.v4", opstr,
  2032. " \t[func_retval0+$a], {{$val, $val2, $val3, $val4}};"),
  2033. []>;
  2034. }
  2035. let isCall=1 in {
  2036. multiclass CALL<string OpcStr, SDNode OpNode> {
  2037. def PrintCallNoRetInst : NVPTXInst<(outs), (ins),
  2038. !strconcat(OpcStr, " "), [(OpNode (i32 0))]>;
  2039. def PrintCallRetInst1 : NVPTXInst<(outs), (ins),
  2040. !strconcat(OpcStr, " (retval0), "), [(OpNode (i32 1))]>;
  2041. def PrintCallRetInst2 : NVPTXInst<(outs), (ins),
  2042. !strconcat(OpcStr, " (retval0, retval1), "), [(OpNode (i32 2))]>;
  2043. def PrintCallRetInst3 : NVPTXInst<(outs), (ins),
  2044. !strconcat(OpcStr, " (retval0, retval1, retval2), "), [(OpNode (i32 3))]>;
  2045. def PrintCallRetInst4 : NVPTXInst<(outs), (ins),
  2046. !strconcat(OpcStr, " (retval0, retval1, retval2, retval3), "),
  2047. [(OpNode (i32 4))]>;
  2048. def PrintCallRetInst5 : NVPTXInst<(outs), (ins),
  2049. !strconcat(OpcStr, " (retval0, retval1, retval2, retval3, retval4), "),
  2050. [(OpNode (i32 5))]>;
  2051. def PrintCallRetInst6 : NVPTXInst<(outs), (ins),
  2052. !strconcat(OpcStr, " (retval0, retval1, retval2, retval3, retval4, "
  2053. "retval5), "),
  2054. [(OpNode (i32 6))]>;
  2055. def PrintCallRetInst7 : NVPTXInst<(outs), (ins),
  2056. !strconcat(OpcStr, " (retval0, retval1, retval2, retval3, retval4, "
  2057. "retval5, retval6), "),
  2058. [(OpNode (i32 7))]>;
  2059. def PrintCallRetInst8 : NVPTXInst<(outs), (ins),
  2060. !strconcat(OpcStr, " (retval0, retval1, retval2, retval3, retval4, "
  2061. "retval5, retval6, retval7), "),
  2062. [(OpNode (i32 8))]>;
  2063. }
  2064. }
  2065. defm Call : CALL<"call", PrintCall>;
  2066. defm CallUni : CALL<"call.uni", PrintCallUni>;
  2067. // Convergent call instructions. These are identical to regular calls, except
  2068. // they have the isConvergent bit set.
  2069. let isConvergent=1 in {
  2070. defm ConvergentCall : CALL<"call", PrintConvergentCall>;
  2071. defm ConvergentCallUni : CALL<"call.uni", PrintConvergentCallUni>;
  2072. }
  2073. def LoadParamMemI64 : LoadParamMemInst<Int64Regs, ".b64">;
  2074. def LoadParamMemI32 : LoadParamMemInst<Int32Regs, ".b32">;
  2075. def LoadParamMemI16 : LoadParamMemInst<Int16Regs, ".b16">;
  2076. def LoadParamMemI8 : LoadParamMemInst<Int16Regs, ".b8">;
  2077. def LoadParamMemV2I64 : LoadParamV2MemInst<Int64Regs, ".b64">;
  2078. def LoadParamMemV2I32 : LoadParamV2MemInst<Int32Regs, ".b32">;
  2079. def LoadParamMemV2I16 : LoadParamV2MemInst<Int16Regs, ".b16">;
  2080. def LoadParamMemV2I8 : LoadParamV2MemInst<Int16Regs, ".b8">;
  2081. def LoadParamMemV4I32 : LoadParamV4MemInst<Int32Regs, ".b32">;
  2082. def LoadParamMemV4I16 : LoadParamV4MemInst<Int16Regs, ".b16">;
  2083. def LoadParamMemV4I8 : LoadParamV4MemInst<Int16Regs, ".b8">;
  2084. def LoadParamMemF16 : LoadParamMemInst<Float16Regs, ".b16">;
  2085. def LoadParamMemF16x2 : LoadParamMemInst<Float16x2Regs, ".b32">;
  2086. def LoadParamMemF32 : LoadParamMemInst<Float32Regs, ".f32">;
  2087. def LoadParamMemF64 : LoadParamMemInst<Float64Regs, ".f64">;
  2088. def LoadParamMemV2F16 : LoadParamV2MemInst<Float16Regs, ".b16">;
  2089. def LoadParamMemV2F16x2: LoadParamV2MemInst<Float16x2Regs, ".b32">;
  2090. def LoadParamMemV2F32 : LoadParamV2MemInst<Float32Regs, ".f32">;
  2091. def LoadParamMemV2F64 : LoadParamV2MemInst<Float64Regs, ".f64">;
  2092. def LoadParamMemV4F16 : LoadParamV4MemInst<Float16Regs, ".b16">;
  2093. def LoadParamMemV4F16x2: LoadParamV4MemInst<Float16x2Regs, ".b32">;
  2094. def LoadParamMemV4F32 : LoadParamV4MemInst<Float32Regs, ".f32">;
  2095. def StoreParamI64 : StoreParamInst<Int64Regs, ".b64">;
  2096. def StoreParamI32 : StoreParamInst<Int32Regs, ".b32">;
  2097. def StoreParamI16 : StoreParamInst<Int16Regs, ".b16">;
  2098. def StoreParamI8 : StoreParamInst<Int16Regs, ".b8">;
  2099. def StoreParamV2I64 : StoreParamV2Inst<Int64Regs, ".b64">;
  2100. def StoreParamV2I32 : StoreParamV2Inst<Int32Regs, ".b32">;
  2101. def StoreParamV2I16 : StoreParamV2Inst<Int16Regs, ".b16">;
  2102. def StoreParamV2I8 : StoreParamV2Inst<Int16Regs, ".b8">;
  2103. def StoreParamV4I32 : StoreParamV4Inst<Int32Regs, ".b32">;
  2104. def StoreParamV4I16 : StoreParamV4Inst<Int16Regs, ".b16">;
  2105. def StoreParamV4I8 : StoreParamV4Inst<Int16Regs, ".b8">;
  2106. def StoreParamF16 : StoreParamInst<Float16Regs, ".b16">;
  2107. def StoreParamF16x2 : StoreParamInst<Float16x2Regs, ".b32">;
  2108. def StoreParamF32 : StoreParamInst<Float32Regs, ".f32">;
  2109. def StoreParamF64 : StoreParamInst<Float64Regs, ".f64">;
  2110. def StoreParamV2F16 : StoreParamV2Inst<Float16Regs, ".b16">;
  2111. def StoreParamV2F16x2 : StoreParamV2Inst<Float16x2Regs, ".b32">;
  2112. def StoreParamV2F32 : StoreParamV2Inst<Float32Regs, ".f32">;
  2113. def StoreParamV2F64 : StoreParamV2Inst<Float64Regs, ".f64">;
  2114. def StoreParamV4F16 : StoreParamV4Inst<Float16Regs, ".b16">;
  2115. def StoreParamV4F16x2 : StoreParamV4Inst<Float16x2Regs, ".b32">;
  2116. def StoreParamV4F32 : StoreParamV4Inst<Float32Regs, ".f32">;
  2117. def StoreRetvalI64 : StoreRetvalInst<Int64Regs, ".b64">;
  2118. def StoreRetvalI32 : StoreRetvalInst<Int32Regs, ".b32">;
  2119. def StoreRetvalI16 : StoreRetvalInst<Int16Regs, ".b16">;
  2120. def StoreRetvalI8 : StoreRetvalInst<Int16Regs, ".b8">;
  2121. def StoreRetvalV2I64 : StoreRetvalV2Inst<Int64Regs, ".b64">;
  2122. def StoreRetvalV2I32 : StoreRetvalV2Inst<Int32Regs, ".b32">;
  2123. def StoreRetvalV2I16 : StoreRetvalV2Inst<Int16Regs, ".b16">;
  2124. def StoreRetvalV2I8 : StoreRetvalV2Inst<Int16Regs, ".b8">;
  2125. def StoreRetvalV4I32 : StoreRetvalV4Inst<Int32Regs, ".b32">;
  2126. def StoreRetvalV4I16 : StoreRetvalV4Inst<Int16Regs, ".b16">;
  2127. def StoreRetvalV4I8 : StoreRetvalV4Inst<Int16Regs, ".b8">;
  2128. def StoreRetvalF64 : StoreRetvalInst<Float64Regs, ".f64">;
  2129. def StoreRetvalF32 : StoreRetvalInst<Float32Regs, ".f32">;
  2130. def StoreRetvalF16 : StoreRetvalInst<Float16Regs, ".b16">;
  2131. def StoreRetvalF16x2 : StoreRetvalInst<Float16x2Regs, ".b32">;
  2132. def StoreRetvalV2F64 : StoreRetvalV2Inst<Float64Regs, ".f64">;
  2133. def StoreRetvalV2F32 : StoreRetvalV2Inst<Float32Regs, ".f32">;
  2134. def StoreRetvalV2F16 : StoreRetvalV2Inst<Float16Regs, ".b16">;
  2135. def StoreRetvalV2F16x2: StoreRetvalV2Inst<Float16x2Regs, ".b32">;
  2136. def StoreRetvalV4F32 : StoreRetvalV4Inst<Float32Regs, ".f32">;
  2137. def StoreRetvalV4F16 : StoreRetvalV4Inst<Float16Regs, ".b16">;
  2138. def StoreRetvalV4F16x2: StoreRetvalV4Inst<Float16x2Regs, ".b32">;
  2139. def CallArgBeginInst : NVPTXInst<(outs), (ins), "(", [(CallArgBegin)]>;
  2140. def CallArgEndInst1 : NVPTXInst<(outs), (ins), ");", [(CallArgEnd (i32 1))]>;
  2141. def CallArgEndInst0 : NVPTXInst<(outs), (ins), ")", [(CallArgEnd (i32 0))]>;
  2142. def RETURNInst : NVPTXInst<(outs), (ins), "ret;", [(RETURNNode)]>;
  2143. class CallArgInst<NVPTXRegClass regclass> :
  2144. NVPTXInst<(outs), (ins regclass:$a), "$a, ",
  2145. [(CallArg (i32 0), regclass:$a)]>;
  2146. class LastCallArgInst<NVPTXRegClass regclass> :
  2147. NVPTXInst<(outs), (ins regclass:$a), "$a",
  2148. [(LastCallArg (i32 0), regclass:$a)]>;
  2149. def CallArgI64 : CallArgInst<Int64Regs>;
  2150. def CallArgI32 : CallArgInst<Int32Regs>;
  2151. def CallArgI16 : CallArgInst<Int16Regs>;
  2152. def CallArgF64 : CallArgInst<Float64Regs>;
  2153. def CallArgF32 : CallArgInst<Float32Regs>;
  2154. def LastCallArgI64 : LastCallArgInst<Int64Regs>;
  2155. def LastCallArgI32 : LastCallArgInst<Int32Regs>;
  2156. def LastCallArgI16 : LastCallArgInst<Int16Regs>;
  2157. def LastCallArgF64 : LastCallArgInst<Float64Regs>;
  2158. def LastCallArgF32 : LastCallArgInst<Float32Regs>;
  2159. def CallArgI32imm : NVPTXInst<(outs), (ins i32imm:$a), "$a, ",
  2160. [(CallArg (i32 0), (i32 imm:$a))]>;
  2161. def LastCallArgI32imm : NVPTXInst<(outs), (ins i32imm:$a), "$a",
  2162. [(LastCallArg (i32 0), (i32 imm:$a))]>;
  2163. def CallArgParam : NVPTXInst<(outs), (ins i32imm:$a), "param$a, ",
  2164. [(CallArg (i32 1), (i32 imm:$a))]>;
  2165. def LastCallArgParam : NVPTXInst<(outs), (ins i32imm:$a), "param$a",
  2166. [(LastCallArg (i32 1), (i32 imm:$a))]>;
  2167. def CallVoidInst : NVPTXInst<(outs), (ins imem:$addr), "$addr, ",
  2168. [(CallVoid (Wrapper tglobaladdr:$addr))]>;
  2169. def CallVoidInstReg : NVPTXInst<(outs), (ins Int32Regs:$addr), "$addr, ",
  2170. [(CallVoid Int32Regs:$addr)]>;
  2171. def CallVoidInstReg64 : NVPTXInst<(outs), (ins Int64Regs:$addr), "$addr, ",
  2172. [(CallVoid Int64Regs:$addr)]>;
  2173. def PrototypeInst : NVPTXInst<(outs), (ins i32imm:$val), ", prototype_$val;",
  2174. [(Prototype (i32 imm:$val))]>;
  2175. def DeclareRetMemInst :
  2176. NVPTXInst<(outs), (ins i32imm:$align, i32imm:$size, i32imm:$num),
  2177. ".param .align $align .b8 retval$num[$size];",
  2178. [(DeclareRetParam (i32 imm:$align), (i32 imm:$size), (i32 imm:$num))]>;
  2179. def DeclareRetScalarInst :
  2180. NVPTXInst<(outs), (ins i32imm:$size, i32imm:$num),
  2181. ".param .b$size retval$num;",
  2182. [(DeclareRet (i32 1), (i32 imm:$size), (i32 imm:$num))]>;
  2183. def DeclareRetRegInst :
  2184. NVPTXInst<(outs), (ins i32imm:$size, i32imm:$num),
  2185. ".reg .b$size retval$num;",
  2186. [(DeclareRet (i32 2), (i32 imm:$size), (i32 imm:$num))]>;
  2187. def DeclareParamInst :
  2188. NVPTXInst<(outs), (ins i32imm:$align, i32imm:$a, i32imm:$size),
  2189. ".param .align $align .b8 param$a[$size];",
  2190. [(DeclareParam (i32 imm:$align), (i32 imm:$a), (i32 imm:$size))]>;
  2191. def DeclareScalarParamInst :
  2192. NVPTXInst<(outs), (ins i32imm:$a, i32imm:$size),
  2193. ".param .b$size param$a;",
  2194. [(DeclareScalarParam (i32 imm:$a), (i32 imm:$size), (i32 0))]>;
  2195. def DeclareScalarRegInst :
  2196. NVPTXInst<(outs), (ins i32imm:$a, i32imm:$size),
  2197. ".reg .b$size param$a;",
  2198. [(DeclareScalarParam (i32 imm:$a), (i32 imm:$size), (i32 1))]>;
  2199. class MoveParamInst<ValueType T, NVPTXRegClass regclass, string asmstr> :
  2200. NVPTXInst<(outs regclass:$dst), (ins regclass:$src),
  2201. !strconcat("mov", asmstr, " \t$dst, $src;"),
  2202. [(set (T regclass:$dst), (MoveParam (T regclass:$src)))]>;
  2203. class MoveParamSymbolInst<NVPTXRegClass regclass, Operand srcty,
  2204. string asmstr> :
  2205. NVPTXInst<(outs regclass:$dst), (ins srcty:$src),
  2206. !strconcat("mov", asmstr, " \t$dst, $src;"),
  2207. [(set regclass:$dst, (MoveParam texternalsym:$src))]>;
  2208. def MoveParamI64 : MoveParamInst<i64, Int64Regs, ".b64">;
  2209. def MoveParamI32 : MoveParamInst<i32, Int32Regs, ".b32">;
  2210. def MoveParamSymbolI64 : MoveParamSymbolInst<Int64Regs, i64imm, ".b64">;
  2211. def MoveParamSymbolI32 : MoveParamSymbolInst<Int32Regs, i32imm, ".b32">;
  2212. def MoveParamI16 :
  2213. NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
  2214. "cvt.u16.u32 \t$dst, $src;",
  2215. [(set Int16Regs:$dst, (MoveParam Int16Regs:$src))]>;
  2216. def MoveParamF64 : MoveParamInst<f64, Float64Regs, ".f64">;
  2217. def MoveParamF32 : MoveParamInst<f32, Float32Regs, ".f32">;
  2218. def MoveParamF16 : MoveParamInst<f16, Float16Regs, ".f16">;
  2219. class PseudoUseParamInst<NVPTXRegClass regclass> :
  2220. NVPTXInst<(outs), (ins regclass:$src),
  2221. "// Pseudo use of $src",
  2222. [(PseudoUseParam regclass:$src)]>;
  2223. def PseudoUseParamI64 : PseudoUseParamInst<Int64Regs>;
  2224. def PseudoUseParamI32 : PseudoUseParamInst<Int32Regs>;
  2225. def PseudoUseParamI16 : PseudoUseParamInst<Int16Regs>;
  2226. def PseudoUseParamF64 : PseudoUseParamInst<Float64Regs>;
  2227. def PseudoUseParamF32 : PseudoUseParamInst<Float32Regs>;
  2228. class ProxyRegInst<string SzStr, ValueType T, NVPTXRegClass regclass> :
  2229. NVPTXInst<(outs regclass:$dst), (ins regclass:$src),
  2230. !strconcat("mov.", SzStr, " \t$dst, $src;"),
  2231. [(set (T regclass:$dst), (ProxyReg (T regclass:$src)))]>;
  2232. let isCodeGenOnly=1, isPseudo=1 in {
  2233. def ProxyRegI1 : ProxyRegInst<"pred", i1, Int1Regs>;
  2234. def ProxyRegI16 : ProxyRegInst<"b16", i16, Int16Regs>;
  2235. def ProxyRegI32 : ProxyRegInst<"b32", i32, Int32Regs>;
  2236. def ProxyRegI64 : ProxyRegInst<"b64", i64, Int64Regs>;
  2237. def ProxyRegF16 : ProxyRegInst<"b16", f16, Float16Regs>;
  2238. def ProxyRegBF16 : ProxyRegInst<"b16", bf16, Float16Regs>;
  2239. def ProxyRegF32 : ProxyRegInst<"f32", f32, Float32Regs>;
  2240. def ProxyRegF64 : ProxyRegInst<"f64", f64, Float64Regs>;
  2241. def ProxyRegF16x2 : ProxyRegInst<"b32", v2f16, Float16x2Regs>;
  2242. def ProxyRegBF16x2 : ProxyRegInst<"b32", v2bf16, Float16x2Regs>;
  2243. }
  2244. //
  2245. // Load / Store Handling
  2246. //
  2247. multiclass LD<NVPTXRegClass regclass> {
  2248. def _avar : NVPTXInst<
  2249. (outs regclass:$dst),
  2250. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2251. i32imm:$fromWidth, imem:$addr),
  2252. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2253. "\t$dst, [$addr];", []>;
  2254. def _areg : NVPTXInst<
  2255. (outs regclass:$dst),
  2256. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2257. i32imm:$fromWidth, Int32Regs:$addr),
  2258. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2259. "\t$dst, [$addr];", []>;
  2260. def _areg_64 : NVPTXInst<
  2261. (outs regclass:$dst),
  2262. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2263. i32imm:$fromWidth, Int64Regs:$addr),
  2264. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2265. "\t$dst, [$addr];", []>;
  2266. def _ari : NVPTXInst<
  2267. (outs regclass:$dst),
  2268. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2269. i32imm:$fromWidth, Int32Regs:$addr, i32imm:$offset),
  2270. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2271. "\t$dst, [$addr+$offset];", []>;
  2272. def _ari_64 : NVPTXInst<
  2273. (outs regclass:$dst),
  2274. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
  2275. LdStCode:$Sign, i32imm:$fromWidth, Int64Regs:$addr, i32imm:$offset),
  2276. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2277. "\t$dst, [$addr+$offset];", []>;
  2278. def _asi : NVPTXInst<
  2279. (outs regclass:$dst),
  2280. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
  2281. LdStCode:$Sign, i32imm:$fromWidth, imem:$addr, i32imm:$offset),
  2282. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2283. "\t$dst, [$addr+$offset];", []>;
  2284. }
  2285. let mayLoad=1, hasSideEffects=0 in {
  2286. defm LD_i8 : LD<Int16Regs>;
  2287. defm LD_i16 : LD<Int16Regs>;
  2288. defm LD_i32 : LD<Int32Regs>;
  2289. defm LD_i64 : LD<Int64Regs>;
  2290. defm LD_f16 : LD<Float16Regs>;
  2291. defm LD_f16x2 : LD<Float16x2Regs>;
  2292. defm LD_f32 : LD<Float32Regs>;
  2293. defm LD_f64 : LD<Float64Regs>;
  2294. }
  2295. multiclass ST<NVPTXRegClass regclass> {
  2296. def _avar : NVPTXInst<
  2297. (outs),
  2298. (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
  2299. LdStCode:$Sign, i32imm:$toWidth, imem:$addr),
  2300. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
  2301. " \t[$addr], $src;", []>;
  2302. def _areg : NVPTXInst<
  2303. (outs),
  2304. (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp,
  2305. LdStCode:$Vec, LdStCode:$Sign, i32imm:$toWidth, Int32Regs:$addr),
  2306. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
  2307. " \t[$addr], $src;", []>;
  2308. def _areg_64 : NVPTXInst<
  2309. (outs),
  2310. (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
  2311. LdStCode:$Sign, i32imm:$toWidth, Int64Regs:$addr),
  2312. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
  2313. " \t[$addr], $src;", []>;
  2314. def _ari : NVPTXInst<
  2315. (outs),
  2316. (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
  2317. LdStCode:$Sign, i32imm:$toWidth, Int32Regs:$addr, i32imm:$offset),
  2318. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
  2319. " \t[$addr+$offset], $src;", []>;
  2320. def _ari_64 : NVPTXInst<
  2321. (outs),
  2322. (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
  2323. LdStCode:$Sign, i32imm:$toWidth, Int64Regs:$addr, i32imm:$offset),
  2324. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
  2325. " \t[$addr+$offset], $src;", []>;
  2326. def _asi : NVPTXInst<
  2327. (outs),
  2328. (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
  2329. LdStCode:$Sign, i32imm:$toWidth, imem:$addr, i32imm:$offset),
  2330. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
  2331. " \t[$addr+$offset], $src;", []>;
  2332. }
  2333. let mayStore=1, hasSideEffects=0 in {
  2334. defm ST_i8 : ST<Int16Regs>;
  2335. defm ST_i16 : ST<Int16Regs>;
  2336. defm ST_i32 : ST<Int32Regs>;
  2337. defm ST_i64 : ST<Int64Regs>;
  2338. defm ST_f16 : ST<Float16Regs>;
  2339. defm ST_f16x2 : ST<Float16x2Regs>;
  2340. defm ST_f32 : ST<Float32Regs>;
  2341. defm ST_f64 : ST<Float64Regs>;
  2342. }
  2343. // The following is used only in and after vector elementizations. Vector
  2344. // elementization happens at the machine instruction level, so the following
  2345. // instructions never appear in the DAG.
  2346. multiclass LD_VEC<NVPTXRegClass regclass> {
  2347. def _v2_avar : NVPTXInst<
  2348. (outs regclass:$dst1, regclass:$dst2),
  2349. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2350. i32imm:$fromWidth, imem:$addr),
  2351. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2352. "\t{{$dst1, $dst2}}, [$addr];", []>;
  2353. def _v2_areg : NVPTXInst<
  2354. (outs regclass:$dst1, regclass:$dst2),
  2355. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2356. i32imm:$fromWidth, Int32Regs:$addr),
  2357. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2358. "\t{{$dst1, $dst2}}, [$addr];", []>;
  2359. def _v2_areg_64 : NVPTXInst<
  2360. (outs regclass:$dst1, regclass:$dst2),
  2361. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2362. i32imm:$fromWidth, Int64Regs:$addr),
  2363. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2364. "\t{{$dst1, $dst2}}, [$addr];", []>;
  2365. def _v2_ari : NVPTXInst<
  2366. (outs regclass:$dst1, regclass:$dst2),
  2367. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2368. i32imm:$fromWidth, Int32Regs:$addr, i32imm:$offset),
  2369. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2370. "\t{{$dst1, $dst2}}, [$addr+$offset];", []>;
  2371. def _v2_ari_64 : NVPTXInst<
  2372. (outs regclass:$dst1, regclass:$dst2),
  2373. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2374. i32imm:$fromWidth, Int64Regs:$addr, i32imm:$offset),
  2375. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2376. "\t{{$dst1, $dst2}}, [$addr+$offset];", []>;
  2377. def _v2_asi : NVPTXInst<
  2378. (outs regclass:$dst1, regclass:$dst2),
  2379. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2380. i32imm:$fromWidth, imem:$addr, i32imm:$offset),
  2381. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2382. "\t{{$dst1, $dst2}}, [$addr+$offset];", []>;
  2383. def _v4_avar : NVPTXInst<
  2384. (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
  2385. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2386. i32imm:$fromWidth, imem:$addr),
  2387. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2388. "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr];", []>;
  2389. def _v4_areg : NVPTXInst<
  2390. (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
  2391. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2392. i32imm:$fromWidth, Int32Regs:$addr),
  2393. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2394. "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr];", []>;
  2395. def _v4_areg_64 : NVPTXInst<
  2396. (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
  2397. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2398. i32imm:$fromWidth, Int64Regs:$addr),
  2399. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2400. "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr];", []>;
  2401. def _v4_ari : NVPTXInst<
  2402. (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
  2403. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2404. i32imm:$fromWidth, Int32Regs:$addr, i32imm:$offset),
  2405. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2406. "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr+$offset];", []>;
  2407. def _v4_ari_64 : NVPTXInst<
  2408. (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
  2409. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2410. i32imm:$fromWidth, Int64Regs:$addr, i32imm:$offset),
  2411. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2412. "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr+$offset];", []>;
  2413. def _v4_asi : NVPTXInst<
  2414. (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
  2415. (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2416. i32imm:$fromWidth, imem:$addr, i32imm:$offset),
  2417. "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2418. "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr+$offset];", []>;
  2419. }
  2420. let mayLoad=1, hasSideEffects=0 in {
  2421. defm LDV_i8 : LD_VEC<Int16Regs>;
  2422. defm LDV_i16 : LD_VEC<Int16Regs>;
  2423. defm LDV_i32 : LD_VEC<Int32Regs>;
  2424. defm LDV_i64 : LD_VEC<Int64Regs>;
  2425. defm LDV_f16 : LD_VEC<Float16Regs>;
  2426. defm LDV_f16x2 : LD_VEC<Float16x2Regs>;
  2427. defm LDV_f32 : LD_VEC<Float32Regs>;
  2428. defm LDV_f64 : LD_VEC<Float64Regs>;
  2429. }
  2430. multiclass ST_VEC<NVPTXRegClass regclass> {
  2431. def _v2_avar : NVPTXInst<
  2432. (outs),
  2433. (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
  2434. LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, imem:$addr),
  2435. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2436. "\t[$addr], {{$src1, $src2}};", []>;
  2437. def _v2_areg : NVPTXInst<
  2438. (outs),
  2439. (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
  2440. LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, Int32Regs:$addr),
  2441. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2442. "\t[$addr], {{$src1, $src2}};", []>;
  2443. def _v2_areg_64 : NVPTXInst<
  2444. (outs),
  2445. (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
  2446. LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, Int64Regs:$addr),
  2447. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2448. "\t[$addr], {{$src1, $src2}};", []>;
  2449. def _v2_ari : NVPTXInst<
  2450. (outs),
  2451. (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
  2452. LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, Int32Regs:$addr,
  2453. i32imm:$offset),
  2454. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2455. "\t[$addr+$offset], {{$src1, $src2}};", []>;
  2456. def _v2_ari_64 : NVPTXInst<
  2457. (outs),
  2458. (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
  2459. LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, Int64Regs:$addr,
  2460. i32imm:$offset),
  2461. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2462. "\t[$addr+$offset], {{$src1, $src2}};", []>;
  2463. def _v2_asi : NVPTXInst<
  2464. (outs),
  2465. (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
  2466. LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, imem:$addr,
  2467. i32imm:$offset),
  2468. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2469. "\t[$addr+$offset], {{$src1, $src2}};", []>;
  2470. def _v4_avar : NVPTXInst<
  2471. (outs),
  2472. (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
  2473. LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2474. i32imm:$fromWidth, imem:$addr),
  2475. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2476. "\t[$addr], {{$src1, $src2, $src3, $src4}};", []>;
  2477. def _v4_areg : NVPTXInst<
  2478. (outs),
  2479. (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
  2480. LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2481. i32imm:$fromWidth, Int32Regs:$addr),
  2482. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2483. "\t[$addr], {{$src1, $src2, $src3, $src4}};", []>;
  2484. def _v4_areg_64 : NVPTXInst<
  2485. (outs),
  2486. (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
  2487. LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2488. i32imm:$fromWidth, Int64Regs:$addr),
  2489. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2490. "\t[$addr], {{$src1, $src2, $src3, $src4}};", []>;
  2491. def _v4_ari : NVPTXInst<
  2492. (outs),
  2493. (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
  2494. LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2495. i32imm:$fromWidth, Int32Regs:$addr, i32imm:$offset),
  2496. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2497. "\t[$addr+$offset], {{$src1, $src2, $src3, $src4}};", []>;
  2498. def _v4_ari_64 : NVPTXInst<
  2499. (outs),
  2500. (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
  2501. LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2502. i32imm:$fromWidth, Int64Regs:$addr, i32imm:$offset),
  2503. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
  2504. "\t[$addr+$offset], {{$src1, $src2, $src3, $src4}};", []>;
  2505. def _v4_asi : NVPTXInst<
  2506. (outs),
  2507. (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
  2508. LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
  2509. i32imm:$fromWidth, imem:$addr, i32imm:$offset),
  2510. "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}"
  2511. "$fromWidth \t[$addr+$offset], {{$src1, $src2, $src3, $src4}};", []>;
  2512. }
  2513. let mayStore=1, hasSideEffects=0 in {
  2514. defm STV_i8 : ST_VEC<Int16Regs>;
  2515. defm STV_i16 : ST_VEC<Int16Regs>;
  2516. defm STV_i32 : ST_VEC<Int32Regs>;
  2517. defm STV_i64 : ST_VEC<Int64Regs>;
  2518. defm STV_f16 : ST_VEC<Float16Regs>;
  2519. defm STV_f16x2 : ST_VEC<Float16x2Regs>;
  2520. defm STV_f32 : ST_VEC<Float32Regs>;
  2521. defm STV_f64 : ST_VEC<Float64Regs>;
  2522. }
  2523. //---- Conversion ----
  2524. class F_BITCONVERT<string SzStr, ValueType TIn, ValueType TOut,
  2525. NVPTXRegClass regclassIn = ValueToRegClass<TIn>.ret,
  2526. NVPTXRegClass regclassOut = ValueToRegClass<TOut>.ret> :
  2527. NVPTXInst<(outs regclassOut:$d), (ins regclassIn:$a),
  2528. !strconcat("mov.b", SzStr, " \t$d, $a;"),
  2529. [(set (TOut regclassOut:$d), (bitconvert (TIn regclassIn:$a)))]>;
  2530. def BITCONVERT_16_I2F : F_BITCONVERT<"16", i16, f16>;
  2531. def BITCONVERT_16_F2I : F_BITCONVERT<"16", f16, i16>;
  2532. def BITCONVERT_16_I2BF : F_BITCONVERT<"16", i16, bf16>;
  2533. def BITCONVERT_16_BF2I : F_BITCONVERT<"16", bf16, i16>;
  2534. def BITCONVERT_32_I2F : F_BITCONVERT<"32", i32, f32>;
  2535. def BITCONVERT_32_F2I : F_BITCONVERT<"32", f32, i32>;
  2536. def BITCONVERT_64_I2F : F_BITCONVERT<"64", i64, f64>;
  2537. def BITCONVERT_64_F2I : F_BITCONVERT<"64", f64, i64>;
  2538. def BITCONVERT_32_I2F16x2 : F_BITCONVERT<"32", i32, v2f16>;
  2539. def BITCONVERT_32_F16x22I : F_BITCONVERT<"32", v2f16, i32>;
  2540. def BITCONVERT_32_F2F16x2 : F_BITCONVERT<"32", f32, v2f16>;
  2541. def BITCONVERT_32_F16x22F : F_BITCONVERT<"32", v2f16, f32>;
  2542. def BITCONVERT_32_I2BF16x2 : F_BITCONVERT<"32", i32, v2bf16>;
  2543. def BITCONVERT_32_BF16x22I : F_BITCONVERT<"32", v2bf16, i32>;
  2544. def BITCONVERT_32_F2BF16x2 : F_BITCONVERT<"32", f32, v2bf16>;
  2545. def BITCONVERT_32_BF16x22F : F_BITCONVERT<"32", v2bf16, f32>;
  2546. // NOTE: pred->fp are currently sub-optimal due to an issue in TableGen where
  2547. // we cannot specify floating-point literals in isel patterns. Therefore, we
  2548. // use an integer selp to select either 1 or 0 and then cvt to floating-point.
  2549. // sint -> f16
  2550. def : Pat<(f16 (sint_to_fp Int1Regs:$a)),
  2551. (CVT_f16_s32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
  2552. def : Pat<(f16 (sint_to_fp Int16Regs:$a)),
  2553. (CVT_f16_s16 Int16Regs:$a, CvtRN)>;
  2554. def : Pat<(f16 (sint_to_fp Int32Regs:$a)),
  2555. (CVT_f16_s32 Int32Regs:$a, CvtRN)>;
  2556. def : Pat<(f16 (sint_to_fp Int64Regs:$a)),
  2557. (CVT_f16_s64 Int64Regs:$a, CvtRN)>;
  2558. // uint -> f16
  2559. def : Pat<(f16 (uint_to_fp Int1Regs:$a)),
  2560. (CVT_f16_u32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
  2561. def : Pat<(f16 (uint_to_fp Int16Regs:$a)),
  2562. (CVT_f16_u16 Int16Regs:$a, CvtRN)>;
  2563. def : Pat<(f16 (uint_to_fp Int32Regs:$a)),
  2564. (CVT_f16_u32 Int32Regs:$a, CvtRN)>;
  2565. def : Pat<(f16 (uint_to_fp Int64Regs:$a)),
  2566. (CVT_f16_u64 Int64Regs:$a, CvtRN)>;
  2567. // sint -> f32
  2568. def : Pat<(f32 (sint_to_fp Int1Regs:$a)),
  2569. (CVT_f32_s32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
  2570. def : Pat<(f32 (sint_to_fp Int16Regs:$a)),
  2571. (CVT_f32_s16 Int16Regs:$a, CvtRN)>;
  2572. def : Pat<(f32 (sint_to_fp Int32Regs:$a)),
  2573. (CVT_f32_s32 Int32Regs:$a, CvtRN)>;
  2574. def : Pat<(f32 (sint_to_fp Int64Regs:$a)),
  2575. (CVT_f32_s64 Int64Regs:$a, CvtRN)>;
  2576. // uint -> f32
  2577. def : Pat<(f32 (uint_to_fp Int1Regs:$a)),
  2578. (CVT_f32_u32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
  2579. def : Pat<(f32 (uint_to_fp Int16Regs:$a)),
  2580. (CVT_f32_u16 Int16Regs:$a, CvtRN)>;
  2581. def : Pat<(f32 (uint_to_fp Int32Regs:$a)),
  2582. (CVT_f32_u32 Int32Regs:$a, CvtRN)>;
  2583. def : Pat<(f32 (uint_to_fp Int64Regs:$a)),
  2584. (CVT_f32_u64 Int64Regs:$a, CvtRN)>;
  2585. // sint -> f64
  2586. def : Pat<(f64 (sint_to_fp Int1Regs:$a)),
  2587. (CVT_f64_s32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
  2588. def : Pat<(f64 (sint_to_fp Int16Regs:$a)),
  2589. (CVT_f64_s16 Int16Regs:$a, CvtRN)>;
  2590. def : Pat<(f64 (sint_to_fp Int32Regs:$a)),
  2591. (CVT_f64_s32 Int32Regs:$a, CvtRN)>;
  2592. def : Pat<(f64 (sint_to_fp Int64Regs:$a)),
  2593. (CVT_f64_s64 Int64Regs:$a, CvtRN)>;
  2594. // uint -> f64
  2595. def : Pat<(f64 (uint_to_fp Int1Regs:$a)),
  2596. (CVT_f64_u32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
  2597. def : Pat<(f64 (uint_to_fp Int16Regs:$a)),
  2598. (CVT_f64_u16 Int16Regs:$a, CvtRN)>;
  2599. def : Pat<(f64 (uint_to_fp Int32Regs:$a)),
  2600. (CVT_f64_u32 Int32Regs:$a, CvtRN)>;
  2601. def : Pat<(f64 (uint_to_fp Int64Regs:$a)),
  2602. (CVT_f64_u64 Int64Regs:$a, CvtRN)>;
  2603. // f16 -> sint
  2604. def : Pat<(i1 (fp_to_sint (f16 Float16Regs:$a))),
  2605. (SETP_b16ri (BITCONVERT_16_F2I Float16Regs:$a), 0, CmpEQ)>;
  2606. def : Pat<(i16 (fp_to_sint (f16 Float16Regs:$a))),
  2607. (CVT_s16_f16 (f16 Float16Regs:$a), CvtRZI)>;
  2608. def : Pat<(i32 (fp_to_sint (f16 Float16Regs:$a))),
  2609. (CVT_s32_f16 (f16 Float16Regs:$a), CvtRZI)>;
  2610. def : Pat<(i64 (fp_to_sint (f16 Float16Regs:$a))),
  2611. (CVT_s64_f16 Float16Regs:$a, CvtRZI)>;
  2612. // f16 -> uint
  2613. def : Pat<(i1 (fp_to_uint (f16 Float16Regs:$a))),
  2614. (SETP_b16ri (BITCONVERT_16_F2I Float16Regs:$a), 0, CmpEQ)>;
  2615. def : Pat<(i16 (fp_to_uint (f16 Float16Regs:$a))),
  2616. (CVT_u16_f16 Float16Regs:$a, CvtRZI)>;
  2617. def : Pat<(i32 (fp_to_uint (f16 Float16Regs:$a))),
  2618. (CVT_u32_f16 Float16Regs:$a, CvtRZI)>;
  2619. def : Pat<(i64 (fp_to_uint (f16 Float16Regs:$a))),
  2620. (CVT_u64_f16 Float16Regs:$a, CvtRZI)>;
  2621. // f32 -> sint
  2622. def : Pat<(i1 (fp_to_sint Float32Regs:$a)),
  2623. (SETP_b32ri (BITCONVERT_32_F2I Float32Regs:$a), 0, CmpEQ)>;
  2624. def : Pat<(i16 (fp_to_sint Float32Regs:$a)),
  2625. (CVT_s16_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
  2626. def : Pat<(i16 (fp_to_sint Float32Regs:$a)),
  2627. (CVT_s16_f32 Float32Regs:$a, CvtRZI)>;
  2628. def : Pat<(i32 (fp_to_sint Float32Regs:$a)),
  2629. (CVT_s32_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
  2630. def : Pat<(i32 (fp_to_sint Float32Regs:$a)),
  2631. (CVT_s32_f32 Float32Regs:$a, CvtRZI)>;
  2632. def : Pat<(i64 (fp_to_sint Float32Regs:$a)),
  2633. (CVT_s64_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
  2634. def : Pat<(i64 (fp_to_sint Float32Regs:$a)),
  2635. (CVT_s64_f32 Float32Regs:$a, CvtRZI)>;
  2636. // f32 -> uint
  2637. def : Pat<(i1 (fp_to_uint Float32Regs:$a)),
  2638. (SETP_b32ri (BITCONVERT_32_F2I Float32Regs:$a), 0, CmpEQ)>;
  2639. def : Pat<(i16 (fp_to_uint Float32Regs:$a)),
  2640. (CVT_u16_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
  2641. def : Pat<(i16 (fp_to_uint Float32Regs:$a)),
  2642. (CVT_u16_f32 Float32Regs:$a, CvtRZI)>;
  2643. def : Pat<(i32 (fp_to_uint Float32Regs:$a)),
  2644. (CVT_u32_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
  2645. def : Pat<(i32 (fp_to_uint Float32Regs:$a)),
  2646. (CVT_u32_f32 Float32Regs:$a, CvtRZI)>;
  2647. def : Pat<(i64 (fp_to_uint Float32Regs:$a)),
  2648. (CVT_u64_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
  2649. def : Pat<(i64 (fp_to_uint Float32Regs:$a)),
  2650. (CVT_u64_f32 Float32Regs:$a, CvtRZI)>;
  2651. // f64 -> sint
  2652. def : Pat<(i1 (fp_to_sint Float64Regs:$a)),
  2653. (SETP_b64ri (BITCONVERT_64_F2I Float64Regs:$a), 0, CmpEQ)>;
  2654. def : Pat<(i16 (fp_to_sint Float64Regs:$a)),
  2655. (CVT_s16_f64 Float64Regs:$a, CvtRZI)>;
  2656. def : Pat<(i32 (fp_to_sint Float64Regs:$a)),
  2657. (CVT_s32_f64 Float64Regs:$a, CvtRZI)>;
  2658. def : Pat<(i64 (fp_to_sint Float64Regs:$a)),
  2659. (CVT_s64_f64 Float64Regs:$a, CvtRZI)>;
  2660. // f64 -> uint
  2661. def : Pat<(i1 (fp_to_uint Float64Regs:$a)),
  2662. (SETP_b64ri (BITCONVERT_64_F2I Float64Regs:$a), 0, CmpEQ)>;
  2663. def : Pat<(i16 (fp_to_uint Float64Regs:$a)),
  2664. (CVT_u16_f64 Float64Regs:$a, CvtRZI)>;
  2665. def : Pat<(i32 (fp_to_uint Float64Regs:$a)),
  2666. (CVT_u32_f64 Float64Regs:$a, CvtRZI)>;
  2667. def : Pat<(i64 (fp_to_uint Float64Regs:$a)),
  2668. (CVT_u64_f64 Float64Regs:$a, CvtRZI)>;
  2669. // sext i1
  2670. def : Pat<(i16 (sext Int1Regs:$a)),
  2671. (SELP_s16ii -1, 0, Int1Regs:$a)>;
  2672. def : Pat<(i32 (sext Int1Regs:$a)),
  2673. (SELP_s32ii -1, 0, Int1Regs:$a)>;
  2674. def : Pat<(i64 (sext Int1Regs:$a)),
  2675. (SELP_s64ii -1, 0, Int1Regs:$a)>;
  2676. // zext i1
  2677. def : Pat<(i16 (zext Int1Regs:$a)),
  2678. (SELP_u16ii 1, 0, Int1Regs:$a)>;
  2679. def : Pat<(i32 (zext Int1Regs:$a)),
  2680. (SELP_u32ii 1, 0, Int1Regs:$a)>;
  2681. def : Pat<(i64 (zext Int1Regs:$a)),
  2682. (SELP_u64ii 1, 0, Int1Regs:$a)>;
  2683. // anyext i1
  2684. def : Pat<(i16 (anyext Int1Regs:$a)),
  2685. (SELP_u16ii -1, 0, Int1Regs:$a)>;
  2686. def : Pat<(i32 (anyext Int1Regs:$a)),
  2687. (SELP_u32ii -1, 0, Int1Regs:$a)>;
  2688. def : Pat<(i64 (anyext Int1Regs:$a)),
  2689. (SELP_u64ii -1, 0, Int1Regs:$a)>;
  2690. // sext i16
  2691. def : Pat<(i32 (sext Int16Regs:$a)),
  2692. (CVT_s32_s16 Int16Regs:$a, CvtNONE)>;
  2693. def : Pat<(i64 (sext Int16Regs:$a)),
  2694. (CVT_s64_s16 Int16Regs:$a, CvtNONE)>;
  2695. // zext i16
  2696. def : Pat<(i32 (zext Int16Regs:$a)),
  2697. (CVT_u32_u16 Int16Regs:$a, CvtNONE)>;
  2698. def : Pat<(i64 (zext Int16Regs:$a)),
  2699. (CVT_u64_u16 Int16Regs:$a, CvtNONE)>;
  2700. // anyext i16
  2701. def : Pat<(i32 (anyext Int16Regs:$a)),
  2702. (CVT_u32_u16 Int16Regs:$a, CvtNONE)>;
  2703. def : Pat<(i64 (anyext Int16Regs:$a)),
  2704. (CVT_u64_u16 Int16Regs:$a, CvtNONE)>;
  2705. // sext i32
  2706. def : Pat<(i64 (sext Int32Regs:$a)),
  2707. (CVT_s64_s32 Int32Regs:$a, CvtNONE)>;
  2708. // zext i32
  2709. def : Pat<(i64 (zext Int32Regs:$a)),
  2710. (CVT_u64_u32 Int32Regs:$a, CvtNONE)>;
  2711. // anyext i32
  2712. def : Pat<(i64 (anyext Int32Regs:$a)),
  2713. (CVT_u64_u32 Int32Regs:$a, CvtNONE)>;
  2714. // truncate i64
  2715. def : Pat<(i32 (trunc Int64Regs:$a)),
  2716. (CVT_u32_u64 Int64Regs:$a, CvtNONE)>;
  2717. def : Pat<(i16 (trunc Int64Regs:$a)),
  2718. (CVT_u16_u64 Int64Regs:$a, CvtNONE)>;
  2719. def : Pat<(i1 (trunc Int64Regs:$a)),
  2720. (SETP_b64ri (ANDb64ri Int64Regs:$a, 1), 1, CmpEQ)>;
  2721. // truncate i32
  2722. def : Pat<(i16 (trunc Int32Regs:$a)),
  2723. (CVT_u16_u32 Int32Regs:$a, CvtNONE)>;
  2724. def : Pat<(i1 (trunc Int32Regs:$a)),
  2725. (SETP_b32ri (ANDb32ri Int32Regs:$a, 1), 1, CmpEQ)>;
  2726. // truncate i16
  2727. def : Pat<(i1 (trunc Int16Regs:$a)),
  2728. (SETP_b16ri (ANDb16ri Int16Regs:$a, 1), 1, CmpEQ)>;
  2729. // sext_inreg
  2730. def : Pat<(sext_inreg Int16Regs:$a, i8), (CVT_INREG_s16_s8 Int16Regs:$a)>;
  2731. def : Pat<(sext_inreg Int32Regs:$a, i8), (CVT_INREG_s32_s8 Int32Regs:$a)>;
  2732. def : Pat<(sext_inreg Int32Regs:$a, i16), (CVT_INREG_s32_s16 Int32Regs:$a)>;
  2733. def : Pat<(sext_inreg Int64Regs:$a, i8), (CVT_INREG_s64_s8 Int64Regs:$a)>;
  2734. def : Pat<(sext_inreg Int64Regs:$a, i16), (CVT_INREG_s64_s16 Int64Regs:$a)>;
  2735. def : Pat<(sext_inreg Int64Regs:$a, i32), (CVT_INREG_s64_s32 Int64Regs:$a)>;
  2736. // Select instructions with 32-bit predicates
  2737. def : Pat<(select Int32Regs:$pred, Int16Regs:$a, Int16Regs:$b),
  2738. (SELP_b16rr Int16Regs:$a, Int16Regs:$b,
  2739. (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
  2740. def : Pat<(select Int32Regs:$pred, Int32Regs:$a, Int32Regs:$b),
  2741. (SELP_b32rr Int32Regs:$a, Int32Regs:$b,
  2742. (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
  2743. def : Pat<(select Int32Regs:$pred, Int64Regs:$a, Int64Regs:$b),
  2744. (SELP_b64rr Int64Regs:$a, Int64Regs:$b,
  2745. (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
  2746. def : Pat<(select Int32Regs:$pred, (f16 Float16Regs:$a), (f16 Float16Regs:$b)),
  2747. (SELP_f16rr Float16Regs:$a, Float16Regs:$b,
  2748. (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
  2749. def : Pat<(select Int32Regs:$pred, Float32Regs:$a, Float32Regs:$b),
  2750. (SELP_f32rr Float32Regs:$a, Float32Regs:$b,
  2751. (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
  2752. def : Pat<(select Int32Regs:$pred, Float64Regs:$a, Float64Regs:$b),
  2753. (SELP_f64rr Float64Regs:$a, Float64Regs:$b,
  2754. (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
  2755. let hasSideEffects = false in {
  2756. // pack a set of smaller int registers to a larger int register
  2757. def V4I16toI64 : NVPTXInst<(outs Int64Regs:$d),
  2758. (ins Int16Regs:$s1, Int16Regs:$s2,
  2759. Int16Regs:$s3, Int16Regs:$s4),
  2760. "mov.b64 \t$d, {{$s1, $s2, $s3, $s4}};", []>;
  2761. def V2I16toI32 : NVPTXInst<(outs Int32Regs:$d),
  2762. (ins Int16Regs:$s1, Int16Regs:$s2),
  2763. "mov.b32 \t$d, {{$s1, $s2}};", []>;
  2764. def V2I32toI64 : NVPTXInst<(outs Int64Regs:$d),
  2765. (ins Int32Regs:$s1, Int32Regs:$s2),
  2766. "mov.b64 \t$d, {{$s1, $s2}};", []>;
  2767. def V2F32toF64 : NVPTXInst<(outs Float64Regs:$d),
  2768. (ins Float32Regs:$s1, Float32Regs:$s2),
  2769. "mov.b64 \t$d, {{$s1, $s2}};", []>;
  2770. // unpack a larger int register to a set of smaller int registers
  2771. def I64toV4I16 : NVPTXInst<(outs Int16Regs:$d1, Int16Regs:$d2,
  2772. Int16Regs:$d3, Int16Regs:$d4),
  2773. (ins Int64Regs:$s),
  2774. "mov.b64 \t{{$d1, $d2, $d3, $d4}}, $s;", []>;
  2775. def I32toV2I16 : NVPTXInst<(outs Int16Regs:$d1, Int16Regs:$d2),
  2776. (ins Int32Regs:$s),
  2777. "mov.b32 \t{{$d1, $d2}}, $s;", []>;
  2778. def I64toV2I32 : NVPTXInst<(outs Int32Regs:$d1, Int32Regs:$d2),
  2779. (ins Int64Regs:$s),
  2780. "mov.b64 \t{{$d1, $d2}}, $s;", []>;
  2781. def F64toV2F32 : NVPTXInst<(outs Float32Regs:$d1, Float32Regs:$d2),
  2782. (ins Float64Regs:$s),
  2783. "mov.b64 \t{{$d1, $d2}}, $s;", []>;
  2784. }
  2785. let hasSideEffects = false in {
  2786. // Extract element of f16x2 register. PTX does not provide any way
  2787. // to access elements of f16x2 vector directly, so we need to
  2788. // extract it using a temporary register.
  2789. def F16x2toF16_0 : NVPTXInst<(outs Float16Regs:$dst),
  2790. (ins Float16x2Regs:$src),
  2791. "{{ .reg .b16 \t%tmp_hi;\n\t"
  2792. " mov.b32 \t{$dst, %tmp_hi}, $src; }}",
  2793. [(set Float16Regs:$dst,
  2794. (extractelt (v2f16 Float16x2Regs:$src), 0))]>;
  2795. def F16x2toF16_1 : NVPTXInst<(outs Float16Regs:$dst),
  2796. (ins Float16x2Regs:$src),
  2797. "{{ .reg .b16 \t%tmp_lo;\n\t"
  2798. " mov.b32 \t{%tmp_lo, $dst}, $src; }}",
  2799. [(set Float16Regs:$dst,
  2800. (extractelt (v2f16 Float16x2Regs:$src), 1))]>;
  2801. // Coalesce two f16 registers into f16x2
  2802. def BuildF16x2 : NVPTXInst<(outs Float16x2Regs:$dst),
  2803. (ins Float16Regs:$a, Float16Regs:$b),
  2804. "mov.b32 \t$dst, {{$a, $b}};",
  2805. [(set (v2f16 Float16x2Regs:$dst),
  2806. (build_vector (f16 Float16Regs:$a), (f16 Float16Regs:$b)))]>;
  2807. // Directly initializing underlying the b32 register is one less SASS
  2808. // instruction than than vector-packing move.
  2809. def BuildF16x2i : NVPTXInst<(outs Float16x2Regs:$dst), (ins i32imm:$src),
  2810. "mov.b32 \t$dst, $src;",
  2811. []>;
  2812. // Split f16x2 into two f16 registers.
  2813. def SplitF16x2 : NVPTXInst<(outs Float16Regs:$lo, Float16Regs:$hi),
  2814. (ins Float16x2Regs:$src),
  2815. "mov.b32 \t{{$lo, $hi}}, $src;",
  2816. []>;
  2817. // Split an i32 into two f16
  2818. def SplitI32toF16x2 : NVPTXInst<(outs Float16Regs:$lo, Float16Regs:$hi),
  2819. (ins Int32Regs:$src),
  2820. "mov.b32 \t{{$lo, $hi}}, $src;",
  2821. []>;
  2822. }
  2823. // Count leading zeros
  2824. let hasSideEffects = false in {
  2825. def CLZr32 : NVPTXInst<(outs Int32Regs:$d), (ins Int32Regs:$a),
  2826. "clz.b32 \t$d, $a;", []>;
  2827. def CLZr64 : NVPTXInst<(outs Int32Regs:$d), (ins Int64Regs:$a),
  2828. "clz.b64 \t$d, $a;", []>;
  2829. }
  2830. // 32-bit has a direct PTX instruction
  2831. def : Pat<(ctlz Int32Regs:$a), (CLZr32 Int32Regs:$a)>;
  2832. // The return type of the ctlz ISD node is the same as its input, but the PTX
  2833. // ctz instruction always returns a 32-bit value. For ctlz.i64, convert the
  2834. // ptx value to 64 bits to match the ISD node's semantics, unless we know we're
  2835. // truncating back down to 32 bits.
  2836. def : Pat<(i64 (ctlz Int64Regs:$a)), (CVT_u64_u32 (CLZr64 Int64Regs:$a), CvtNONE)>;
  2837. def : Pat<(i32 (trunc (ctlz Int64Regs:$a))), (CLZr64 Int64Regs:$a)>;
  2838. // For 16-bit ctlz, we zero-extend to 32-bit, perform the count, then trunc the
  2839. // result back to 16-bits if necessary. We also need to subtract 16 because
  2840. // the high-order 16 zeros were counted.
  2841. //
  2842. // TODO: NVPTX has a mov.b32 b32reg, {imm, b16reg} instruction, which we could
  2843. // use to save one SASS instruction (on sm_35 anyway):
  2844. //
  2845. // mov.b32 $tmp, {0xffff, $a}
  2846. // ctlz.b32 $result, $tmp
  2847. //
  2848. // That is, instead of zero-extending the input to 32 bits, we'd "one-extend"
  2849. // and then ctlz that value. This way we don't have to subtract 16 from the
  2850. // result. Unfortunately today we don't have a way to generate
  2851. // "mov b32reg, {b16imm, b16reg}", so we don't do this optimization.
  2852. def : Pat<(i16 (ctlz Int16Regs:$a)),
  2853. (SUBi16ri (CVT_u16_u32
  2854. (CLZr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE)), CvtNONE), 16)>;
  2855. def : Pat<(i32 (zext (i16 (ctlz Int16Regs:$a)))),
  2856. (SUBi32ri (CLZr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE)), 16)>;
  2857. // Population count
  2858. let hasSideEffects = false in {
  2859. def POPCr32 : NVPTXInst<(outs Int32Regs:$d), (ins Int32Regs:$a),
  2860. "popc.b32 \t$d, $a;", []>;
  2861. def POPCr64 : NVPTXInst<(outs Int32Regs:$d), (ins Int64Regs:$a),
  2862. "popc.b64 \t$d, $a;", []>;
  2863. }
  2864. // 32-bit has a direct PTX instruction
  2865. def : Pat<(ctpop Int32Regs:$a), (POPCr32 Int32Regs:$a)>;
  2866. // For 64-bit, the result in PTX is actually 32-bit so we zero-extend to 64-bit
  2867. // to match the LLVM semantics. Just as with ctlz.i64, we provide a second
  2868. // pattern that avoids the type conversion if we're truncating the result to
  2869. // i32 anyway.
  2870. def : Pat<(ctpop Int64Regs:$a), (CVT_u64_u32 (POPCr64 Int64Regs:$a), CvtNONE)>;
  2871. def : Pat<(i32 (trunc (ctpop Int64Regs:$a))), (POPCr64 Int64Regs:$a)>;
  2872. // For 16-bit, we zero-extend to 32-bit, then trunc the result back to 16-bits.
  2873. // If we know that we're storing into an i32, we can avoid the final trunc.
  2874. def : Pat<(ctpop Int16Regs:$a),
  2875. (CVT_u16_u32 (POPCr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE)), CvtNONE)>;
  2876. def : Pat<(i32 (zext (i16 (ctpop Int16Regs:$a)))),
  2877. (POPCr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE))>;
  2878. // fpround f32 -> f16
  2879. def : Pat<(f16 (fpround Float32Regs:$a)),
  2880. (CVT_f16_f32 Float32Regs:$a, CvtRN)>;
  2881. // fpround f64 -> f16
  2882. def : Pat<(f16 (fpround Float64Regs:$a)),
  2883. (CVT_f16_f64 Float64Regs:$a, CvtRN)>;
  2884. // fpround f64 -> f32
  2885. def : Pat<(f32 (fpround Float64Regs:$a)),
  2886. (CVT_f32_f64 Float64Regs:$a, CvtRN_FTZ)>, Requires<[doF32FTZ]>;
  2887. def : Pat<(f32 (fpround Float64Regs:$a)),
  2888. (CVT_f32_f64 Float64Regs:$a, CvtRN)>;
  2889. // fpextend f16 -> f32
  2890. def : Pat<(f32 (fpextend (f16 Float16Regs:$a))),
  2891. (CVT_f32_f16 Float16Regs:$a, CvtNONE_FTZ)>, Requires<[doF32FTZ]>;
  2892. def : Pat<(f32 (fpextend (f16 Float16Regs:$a))),
  2893. (CVT_f32_f16 Float16Regs:$a, CvtNONE)>;
  2894. // fpextend f16 -> f64
  2895. def : Pat<(f64 (fpextend (f16 Float16Regs:$a))),
  2896. (CVT_f64_f16 Float16Regs:$a, CvtNONE)>;
  2897. // fpextend f32 -> f64
  2898. def : Pat<(f64 (fpextend Float32Regs:$a)),
  2899. (CVT_f64_f32 Float32Regs:$a, CvtNONE_FTZ)>, Requires<[doF32FTZ]>;
  2900. def : Pat<(f64 (fpextend Float32Regs:$a)),
  2901. (CVT_f64_f32 Float32Regs:$a, CvtNONE)>;
  2902. def retflag : SDNode<"NVPTXISD::RET_FLAG", SDTNone,
  2903. [SDNPHasChain, SDNPOptInGlue]>;
  2904. // fceil, ffloor, froundeven, ftrunc.
  2905. multiclass CVT_ROUND<SDNode OpNode, PatLeaf Mode, PatLeaf ModeFTZ> {
  2906. def : Pat<(OpNode (f16 Float16Regs:$a)),
  2907. (CVT_f16_f16 Float16Regs:$a, Mode)>;
  2908. def : Pat<(OpNode Float32Regs:$a),
  2909. (CVT_f32_f32 Float32Regs:$a, ModeFTZ)>, Requires<[doF32FTZ]>;
  2910. def : Pat<(OpNode Float32Regs:$a),
  2911. (CVT_f32_f32 Float32Regs:$a, Mode)>, Requires<[doNoF32FTZ]>;
  2912. def : Pat<(OpNode Float64Regs:$a),
  2913. (CVT_f64_f64 Float64Regs:$a, Mode)>;
  2914. }
  2915. defm : CVT_ROUND<fceil, CvtRPI, CvtRPI_FTZ>;
  2916. defm : CVT_ROUND<ffloor, CvtRMI, CvtRMI_FTZ>;
  2917. defm : CVT_ROUND<froundeven, CvtRNI, CvtRNI_FTZ>;
  2918. defm : CVT_ROUND<ftrunc, CvtRZI, CvtRZI_FTZ>;
  2919. // nearbyint and rint are implemented as rounding to nearest even. This isn't
  2920. // strictly correct, because it causes us to ignore the rounding mode. But it
  2921. // matches what CUDA's "libm" does.
  2922. defm : CVT_ROUND<fnearbyint, CvtRNI, CvtRNI_FTZ>;
  2923. defm : CVT_ROUND<frint, CvtRNI, CvtRNI_FTZ>;
  2924. //-----------------------------------
  2925. // Control-flow
  2926. //-----------------------------------
  2927. let isTerminator=1 in {
  2928. let isReturn=1, isBarrier=1 in
  2929. def Return : NVPTXInst<(outs), (ins), "ret;", [(retflag)]>;
  2930. let isBranch=1 in
  2931. def CBranch : NVPTXInst<(outs), (ins Int1Regs:$a, brtarget:$target),
  2932. "@$a bra \t$target;",
  2933. [(brcond Int1Regs:$a, bb:$target)]>;
  2934. let isBranch=1 in
  2935. def CBranchOther : NVPTXInst<(outs), (ins Int1Regs:$a, brtarget:$target),
  2936. "@!$a bra \t$target;", []>;
  2937. let isBranch=1, isBarrier=1 in
  2938. def GOTO : NVPTXInst<(outs), (ins brtarget:$target),
  2939. "bra.uni \t$target;", [(br bb:$target)]>;
  2940. }
  2941. def : Pat<(brcond Int32Regs:$a, bb:$target),
  2942. (CBranch (SETP_u32ri Int32Regs:$a, 0, CmpNE), bb:$target)>;
  2943. // SelectionDAGBuilder::visitSWitchCase() will invert the condition of a
  2944. // conditional branch if the target block is the next block so that the code
  2945. // can fall through to the target block. The invertion is done by 'xor
  2946. // condition, 1', which will be translated to (setne condition, -1). Since ptx
  2947. // supports '@!pred bra target', we should use it.
  2948. def : Pat<(brcond (i1 (setne Int1Regs:$a, -1)), bb:$target),
  2949. (CBranchOther Int1Regs:$a, bb:$target)>;
  2950. // Call
  2951. def SDT_NVPTXCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
  2952. SDTCisVT<1, i32>]>;
  2953. def SDT_NVPTXCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
  2954. def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_NVPTXCallSeqStart,
  2955. [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
  2956. def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_NVPTXCallSeqEnd,
  2957. [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
  2958. SDNPSideEffect]>;
  2959. def SDT_NVPTXCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
  2960. def call : SDNode<"NVPTXISD::CALL", SDT_NVPTXCall,
  2961. [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
  2962. def calltarget : Operand<i32>;
  2963. let isCall=1 in {
  2964. def CALL : NVPTXInst<(outs), (ins calltarget:$dst), "call \t$dst, (1);", []>;
  2965. }
  2966. def : Pat<(call tglobaladdr:$dst), (CALL tglobaladdr:$dst)>;
  2967. def : Pat<(call texternalsym:$dst), (CALL texternalsym:$dst)>;
  2968. // Pseudo instructions.
  2969. class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
  2970. : NVPTXInst<outs, ins, asmstr, pattern>;
  2971. def Callseq_Start :
  2972. NVPTXInst<(outs), (ins i32imm:$amt1, i32imm:$amt2),
  2973. "\\{ // callseq $amt1, $amt2\n"
  2974. "\t.reg .b32 temp_param_reg;",
  2975. [(callseq_start timm:$amt1, timm:$amt2)]>;
  2976. def Callseq_End :
  2977. NVPTXInst<(outs), (ins i32imm:$amt1, i32imm:$amt2),
  2978. "\\} // callseq $amt1",
  2979. [(callseq_end timm:$amt1, timm:$amt2)]>;
  2980. // trap instruction
  2981. def trapinst : NVPTXInst<(outs), (ins), "trap;", [(trap)]>;
  2982. // Call prototype wrapper
  2983. def SDTCallPrototype : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
  2984. def CallPrototype :
  2985. SDNode<"NVPTXISD::CallPrototype", SDTCallPrototype,
  2986. [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
  2987. def ProtoIdent : Operand<i32> {
  2988. let PrintMethod = "printProtoIdent";
  2989. }
  2990. def CALL_PROTOTYPE :
  2991. NVPTXInst<(outs), (ins ProtoIdent:$ident),
  2992. "$ident", [(CallPrototype (i32 texternalsym:$ident))]>;
  2993. include "NVPTXIntrinsics.td"
  2994. //-----------------------------------
  2995. // Notes
  2996. //-----------------------------------
  2997. // BSWAP is currently expanded. The following is a more efficient
  2998. // - for < sm_20, use vector scalar mov, as tesla support native 16-bit register
  2999. // - for sm_20, use pmpt (use vector scalar mov to get the pack and
  3000. // unpack). sm_20 supports native 32-bit register, but not native 16-bit
  3001. // register.