IntrinsicsRISCV.td 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. //===- IntrinsicsRISCV.td - Defines RISCV intrinsics -------*- tablegen -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines all of the RISCV-specific intrinsics.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. //===----------------------------------------------------------------------===//
  13. // Atomics
  14. // Atomic Intrinsics have multiple versions for different access widths, which
  15. // all follow one of the following signatures (depending on how many arguments
  16. // they require). We carefully instantiate only specific versions of these for
  17. // specific integer widths, rather than using `llvm_anyint_ty`.
  18. //
  19. // In fact, as these intrinsics take `llvm_anyptr_ty`, the given names are the
  20. // canonical names, and the intrinsics used in the code will have a name
  21. // suffixed with the pointer type they are specialised for (denoted `<p>` in the
  22. // names below), in order to avoid type conflicts.
  23. let TargetPrefix = "riscv" in {
  24. // T @llvm.<name>.T.<p>(any*, T, T, T imm);
  25. class MaskedAtomicRMWFourArg<LLVMType itype>
  26. : Intrinsic<[itype], [llvm_anyptr_ty, itype, itype, itype],
  27. [IntrArgMemOnly, NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<3>>]>;
  28. // T @llvm.<name>.T.<p>(any*, T, T, T, T imm);
  29. class MaskedAtomicRMWFiveArg<LLVMType itype>
  30. : Intrinsic<[itype], [llvm_anyptr_ty, itype, itype, itype, itype],
  31. [IntrArgMemOnly, NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<4>>]>;
  32. // We define 32-bit and 64-bit variants of the above, where T stands for i32
  33. // or i64 respectively:
  34. multiclass MaskedAtomicRMWFourArgIntrinsics {
  35. // i32 @llvm.<name>.i32.<p>(any*, i32, i32, i32 imm);
  36. def _i32 : MaskedAtomicRMWFourArg<llvm_i32_ty>;
  37. // i64 @llvm.<name>.i32.<p>(any*, i64, i64, i64 imm);
  38. def _i64 : MaskedAtomicRMWFourArg<llvm_i64_ty>;
  39. }
  40. multiclass MaskedAtomicRMWFiveArgIntrinsics {
  41. // i32 @llvm.<name>.i32.<p>(any*, i32, i32, i32, i32 imm);
  42. def _i32 : MaskedAtomicRMWFiveArg<llvm_i32_ty>;
  43. // i64 @llvm.<name>.i64.<p>(any*, i64, i64, i64, i64 imm);
  44. def _i64 : MaskedAtomicRMWFiveArg<llvm_i64_ty>;
  45. }
  46. // @llvm.riscv.masked.atomicrmw.*.{i32,i64}.<p>(...)
  47. defm int_riscv_masked_atomicrmw_xchg : MaskedAtomicRMWFourArgIntrinsics;
  48. defm int_riscv_masked_atomicrmw_add : MaskedAtomicRMWFourArgIntrinsics;
  49. defm int_riscv_masked_atomicrmw_sub : MaskedAtomicRMWFourArgIntrinsics;
  50. defm int_riscv_masked_atomicrmw_nand : MaskedAtomicRMWFourArgIntrinsics;
  51. // Signed min and max need an extra operand to do sign extension with.
  52. defm int_riscv_masked_atomicrmw_max : MaskedAtomicRMWFiveArgIntrinsics;
  53. defm int_riscv_masked_atomicrmw_min : MaskedAtomicRMWFiveArgIntrinsics;
  54. // Unsigned min and max don't need the extra operand.
  55. defm int_riscv_masked_atomicrmw_umax : MaskedAtomicRMWFourArgIntrinsics;
  56. defm int_riscv_masked_atomicrmw_umin : MaskedAtomicRMWFourArgIntrinsics;
  57. // @llvm.riscv.masked.cmpxchg.{i32,i64}.<p>(...)
  58. defm int_riscv_masked_cmpxchg : MaskedAtomicRMWFiveArgIntrinsics;
  59. } // TargetPrefix = "riscv"
  60. //===----------------------------------------------------------------------===//
  61. // Bitmanip (Bit Manipulation) Extension
  62. let TargetPrefix = "riscv" in {
  63. class BitManipGPRIntrinsics
  64. : Intrinsic<[llvm_any_ty],
  65. [LLVMMatchType<0>],
  66. [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
  67. class BitManipGPRGPRIntrinsics
  68. : Intrinsic<[llvm_any_ty],
  69. [LLVMMatchType<0>, LLVMMatchType<0>],
  70. [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
  71. // Zbb
  72. def int_riscv_orc_b : BitManipGPRIntrinsics;
  73. // Zbc
  74. def int_riscv_clmul : BitManipGPRGPRIntrinsics;
  75. def int_riscv_clmulh : BitManipGPRGPRIntrinsics;
  76. def int_riscv_clmulr : BitManipGPRGPRIntrinsics;
  77. // Zbe
  78. def int_riscv_bcompress : BitManipGPRGPRIntrinsics;
  79. def int_riscv_bdecompress : BitManipGPRGPRIntrinsics;
  80. // Zbp
  81. def int_riscv_grev : BitManipGPRGPRIntrinsics;
  82. def int_riscv_gorc : BitManipGPRGPRIntrinsics;
  83. def int_riscv_shfl : BitManipGPRGPRIntrinsics;
  84. def int_riscv_unshfl : BitManipGPRGPRIntrinsics;
  85. def int_riscv_xperm_n : BitManipGPRGPRIntrinsics;
  86. def int_riscv_xperm_b : BitManipGPRGPRIntrinsics;
  87. def int_riscv_xperm_h : BitManipGPRGPRIntrinsics;
  88. def int_riscv_xperm_w : BitManipGPRGPRIntrinsics;
  89. // Zbr
  90. def int_riscv_crc32_b : BitManipGPRIntrinsics;
  91. def int_riscv_crc32_h : BitManipGPRIntrinsics;
  92. def int_riscv_crc32_w : BitManipGPRIntrinsics;
  93. def int_riscv_crc32_d : BitManipGPRIntrinsics;
  94. def int_riscv_crc32c_b : BitManipGPRIntrinsics;
  95. def int_riscv_crc32c_h : BitManipGPRIntrinsics;
  96. def int_riscv_crc32c_w : BitManipGPRIntrinsics;
  97. def int_riscv_crc32c_d : BitManipGPRIntrinsics;
  98. } // TargetPrefix = "riscv"
  99. //===----------------------------------------------------------------------===//
  100. // Vectors
  101. class RISCVVIntrinsic {
  102. // These intrinsics may accept illegal integer values in their llvm_any_ty
  103. // operand, so they have to be extended. If set to zero then the intrinsic
  104. // does not have any operand that must be extended.
  105. Intrinsic IntrinsicID = !cast<Intrinsic>(NAME);
  106. bits<4> SplatOperand = 0;
  107. }
  108. let TargetPrefix = "riscv" in {
  109. // We use anyint here but we only support XLen.
  110. def int_riscv_vsetvli : Intrinsic<[llvm_anyint_ty],
  111. /* AVL */ [LLVMMatchType<0>,
  112. /* VSEW */ LLVMMatchType<0>,
  113. /* VLMUL */ LLVMMatchType<0>],
  114. [IntrNoMem, IntrHasSideEffects,
  115. ImmArg<ArgIndex<1>>,
  116. ImmArg<ArgIndex<2>>]>;
  117. def int_riscv_vsetvlimax : Intrinsic<[llvm_anyint_ty],
  118. /* VSEW */ [LLVMMatchType<0>,
  119. /* VLMUL */ LLVMMatchType<0>],
  120. [IntrNoMem, IntrHasSideEffects,
  121. ImmArg<ArgIndex<0>>,
  122. ImmArg<ArgIndex<1>>]>;
  123. // For unit stride load
  124. // Input: (pointer, vl)
  125. class RISCVUSLoad
  126. : Intrinsic<[llvm_anyvector_ty],
  127. [LLVMPointerType<LLVMMatchType<0>>,
  128. llvm_anyint_ty],
  129. [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
  130. // For unit stride fault-only-first load
  131. // Input: (pointer, vl)
  132. // Output: (data, vl)
  133. // NOTE: We model this with default memory properties since we model writing
  134. // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
  135. class RISCVUSLoadFF
  136. : Intrinsic<[llvm_anyvector_ty, llvm_anyint_ty],
  137. [LLVMPointerType<LLVMMatchType<0>>, LLVMMatchType<1>],
  138. [NoCapture<ArgIndex<0>>]>,
  139. RISCVVIntrinsic;
  140. // For unit stride load with mask
  141. // Input: (maskedoff, pointer, mask, vl)
  142. class RISCVUSLoadMask
  143. : Intrinsic<[llvm_anyvector_ty ],
  144. [LLVMMatchType<0>,
  145. LLVMPointerType<LLVMMatchType<0>>,
  146. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  147. llvm_anyint_ty],
  148. [NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic;
  149. // For unit stride fault-only-first load with mask
  150. // Input: (maskedoff, pointer, mask, vl)
  151. // Output: (data, vl)
  152. // NOTE: We model this with default memory properties since we model writing
  153. // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
  154. class RISCVUSLoadFFMask
  155. : Intrinsic<[llvm_anyvector_ty, llvm_anyint_ty],
  156. [LLVMMatchType<0>,
  157. LLVMPointerType<LLVMMatchType<0>>,
  158. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  159. LLVMMatchType<1>],
  160. [NoCapture<ArgIndex<1>>]>, RISCVVIntrinsic;
  161. // For strided load
  162. // Input: (pointer, stride, vl)
  163. class RISCVSLoad
  164. : Intrinsic<[llvm_anyvector_ty],
  165. [LLVMPointerType<LLVMMatchType<0>>,
  166. llvm_anyint_ty, LLVMMatchType<1>],
  167. [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
  168. // For strided load with mask
  169. // Input: (maskedoff, pointer, stride, mask, vl)
  170. class RISCVSLoadMask
  171. : Intrinsic<[llvm_anyvector_ty ],
  172. [LLVMMatchType<0>,
  173. LLVMPointerType<LLVMMatchType<0>>, llvm_anyint_ty,
  174. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<1>],
  175. [NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic;
  176. // For indexed load
  177. // Input: (pointer, index, vl)
  178. class RISCVILoad
  179. : Intrinsic<[llvm_anyvector_ty],
  180. [LLVMPointerType<LLVMMatchType<0>>,
  181. llvm_anyvector_ty, llvm_anyint_ty],
  182. [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
  183. // For indexed load with mask
  184. // Input: (maskedoff, pointer, index, mask, vl)
  185. class RISCVILoadMask
  186. : Intrinsic<[llvm_anyvector_ty ],
  187. [LLVMMatchType<0>,
  188. LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty,
  189. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  190. [NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic;
  191. // For unit stride store
  192. // Input: (vector_in, pointer, vl)
  193. class RISCVUSStore
  194. : Intrinsic<[],
  195. [llvm_anyvector_ty,
  196. LLVMPointerType<LLVMMatchType<0>>,
  197. llvm_anyint_ty],
  198. [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
  199. // For unit stride store with mask
  200. // Input: (vector_in, pointer, mask, vl)
  201. class RISCVUSStoreMask
  202. : Intrinsic<[],
  203. [llvm_anyvector_ty,
  204. LLVMPointerType<LLVMMatchType<0>>,
  205. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  206. llvm_anyint_ty],
  207. [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
  208. // For strided store
  209. // Input: (vector_in, pointer, stride, vl)
  210. class RISCVSStore
  211. : Intrinsic<[],
  212. [llvm_anyvector_ty,
  213. LLVMPointerType<LLVMMatchType<0>>,
  214. llvm_anyint_ty, LLVMMatchType<1>],
  215. [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
  216. // For stride store with mask
  217. // Input: (vector_in, pointer, stirde, mask, vl)
  218. class RISCVSStoreMask
  219. : Intrinsic<[],
  220. [llvm_anyvector_ty,
  221. LLVMPointerType<LLVMMatchType<0>>, llvm_anyint_ty,
  222. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<1>],
  223. [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
  224. // For indexed store
  225. // Input: (vector_in, pointer, index, vl)
  226. class RISCVIStore
  227. : Intrinsic<[],
  228. [llvm_anyvector_ty,
  229. LLVMPointerType<LLVMMatchType<0>>,
  230. llvm_anyint_ty, llvm_anyint_ty],
  231. [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
  232. // For indexed store with mask
  233. // Input: (vector_in, pointer, index, mask, vl)
  234. class RISCVIStoreMask
  235. : Intrinsic<[],
  236. [llvm_anyvector_ty,
  237. LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty,
  238. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  239. [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
  240. // For destination vector type is the same as source vector.
  241. // Input: (vector_in, vl)
  242. class RISCVUnaryAANoMask
  243. : Intrinsic<[llvm_anyvector_ty],
  244. [LLVMMatchType<0>, llvm_anyint_ty],
  245. [IntrNoMem]>, RISCVVIntrinsic;
  246. // For destination vector type is the same as first source vector (with mask).
  247. // Input: (vector_in, mask, vl)
  248. class RISCVUnaryAAMask
  249. : Intrinsic<[llvm_anyvector_ty],
  250. [LLVMMatchType<0>, LLVMMatchType<0>,
  251. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  252. [IntrNoMem]>, RISCVVIntrinsic;
  253. // For destination vector type is the same as first and second source vector.
  254. // Input: (vector_in, vector_in, vl)
  255. class RISCVBinaryAAANoMask
  256. : Intrinsic<[llvm_anyvector_ty],
  257. [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty],
  258. [IntrNoMem]>, RISCVVIntrinsic;
  259. // For destination vector type is the same as first and second source vector.
  260. // Input: (vector_in, int_vector_in, vl)
  261. class RISCVRGatherVVNoMask
  262. : Intrinsic<[llvm_anyvector_ty],
  263. [LLVMMatchType<0>, LLVMVectorOfBitcastsToInt<0>, llvm_anyint_ty],
  264. [IntrNoMem]>, RISCVVIntrinsic;
  265. // For destination vector type is the same as first and second source vector.
  266. // Input: (vector_in, vector_in, int_vector_in, vl)
  267. class RISCVRGatherVVMask
  268. : Intrinsic<[llvm_anyvector_ty],
  269. [LLVMMatchType<0>, LLVMMatchType<0>, LLVMVectorOfBitcastsToInt<0>,
  270. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  271. [IntrNoMem]>, RISCVVIntrinsic;
  272. // Input: (vector_in, int16_vector_in, vl)
  273. class RISCVRGatherEI16VVNoMask
  274. : Intrinsic<[llvm_anyvector_ty],
  275. [LLVMMatchType<0>, LLVMScalarOrSameVectorWidth<0, llvm_i16_ty>,
  276. llvm_anyint_ty],
  277. [IntrNoMem]>, RISCVVIntrinsic;
  278. // For destination vector type is the same as first and second source vector.
  279. // Input: (vector_in, vector_in, int16_vector_in, vl)
  280. class RISCVRGatherEI16VVMask
  281. : Intrinsic<[llvm_anyvector_ty],
  282. [LLVMMatchType<0>, LLVMMatchType<0>,
  283. LLVMScalarOrSameVectorWidth<0, llvm_i16_ty>,
  284. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  285. [IntrNoMem]>, RISCVVIntrinsic;
  286. // For destination vector type is the same as first source vector, and the
  287. // second operand is XLen.
  288. // Input: (vector_in, xlen_in, vl)
  289. class RISCVGatherVXNoMask
  290. : Intrinsic<[llvm_anyvector_ty],
  291. [LLVMMatchType<0>, llvm_anyint_ty, LLVMMatchType<1>],
  292. [IntrNoMem]>, RISCVVIntrinsic {
  293. }
  294. // For destination vector type is the same as first source vector (with mask).
  295. // Second operand is XLen.
  296. // Input: (maskedoff, vector_in, xlen_in, mask, vl)
  297. class RISCVGatherVXMask
  298. : Intrinsic<[llvm_anyvector_ty],
  299. [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty,
  300. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<1>],
  301. [IntrNoMem]>, RISCVVIntrinsic {
  302. }
  303. // For destination vector type is the same as first source vector.
  304. // Input: (vector_in, vector_in/scalar_in, vl)
  305. class RISCVBinaryAAXNoMask
  306. : Intrinsic<[llvm_anyvector_ty],
  307. [LLVMMatchType<0>, llvm_any_ty, llvm_anyint_ty],
  308. [IntrNoMem]>, RISCVVIntrinsic {
  309. let SplatOperand = 2;
  310. }
  311. // For destination vector type is the same as first source vector (with mask).
  312. // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
  313. class RISCVBinaryAAXMask
  314. : Intrinsic<[llvm_anyvector_ty],
  315. [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty,
  316. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  317. [IntrNoMem]>, RISCVVIntrinsic {
  318. let SplatOperand = 3;
  319. }
  320. // For destination vector type is the same as first source vector. The
  321. // second source operand must match the destination type or be an XLen scalar.
  322. // Input: (vector_in, vector_in/scalar_in, vl)
  323. class RISCVBinaryAAShiftNoMask
  324. : Intrinsic<[llvm_anyvector_ty],
  325. [LLVMMatchType<0>, llvm_any_ty, llvm_anyint_ty],
  326. [IntrNoMem]>, RISCVVIntrinsic;
  327. // For destination vector type is the same as first source vector (with mask).
  328. // The second source operand must match the destination type or be an XLen scalar.
  329. // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
  330. class RISCVBinaryAAShiftMask
  331. : Intrinsic<[llvm_anyvector_ty],
  332. [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty,
  333. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  334. [IntrNoMem]>, RISCVVIntrinsic;
  335. // For destination vector type is NOT the same as first source vector.
  336. // Input: (vector_in, vector_in/scalar_in, vl)
  337. class RISCVBinaryABXNoMask
  338. : Intrinsic<[llvm_anyvector_ty],
  339. [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
  340. [IntrNoMem]>, RISCVVIntrinsic {
  341. let SplatOperand = 2;
  342. }
  343. // For destination vector type is NOT the same as first source vector (with mask).
  344. // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
  345. class RISCVBinaryABXMask
  346. : Intrinsic<[llvm_anyvector_ty],
  347. [LLVMMatchType<0>, llvm_anyvector_ty, llvm_any_ty,
  348. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  349. [IntrNoMem]>, RISCVVIntrinsic {
  350. let SplatOperand = 3;
  351. }
  352. // For destination vector type is NOT the same as first source vector. The
  353. // second source operand must match the destination type or be an XLen scalar.
  354. // Input: (vector_in, vector_in/scalar_in, vl)
  355. class RISCVBinaryABShiftNoMask
  356. : Intrinsic<[llvm_anyvector_ty],
  357. [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
  358. [IntrNoMem]>, RISCVVIntrinsic;
  359. // For destination vector type is NOT the same as first source vector (with mask).
  360. // The second source operand must match the destination type or be an XLen scalar.
  361. // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
  362. class RISCVBinaryABShiftMask
  363. : Intrinsic<[llvm_anyvector_ty],
  364. [LLVMMatchType<0>, llvm_anyvector_ty, llvm_any_ty,
  365. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  366. [IntrNoMem]>, RISCVVIntrinsic;
  367. // For binary operations with V0 as input.
  368. // Input: (vector_in, vector_in/scalar_in, V0, vl)
  369. class RISCVBinaryWithV0
  370. : Intrinsic<[llvm_anyvector_ty],
  371. [LLVMMatchType<0>, llvm_any_ty,
  372. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  373. llvm_anyint_ty],
  374. [IntrNoMem]>, RISCVVIntrinsic {
  375. let SplatOperand = 2;
  376. }
  377. // For binary operations with mask type output and V0 as input.
  378. // Output: (mask type output)
  379. // Input: (vector_in, vector_in/scalar_in, V0, vl)
  380. class RISCVBinaryMOutWithV0
  381. :Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
  382. [llvm_anyvector_ty, llvm_any_ty,
  383. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  384. llvm_anyint_ty],
  385. [IntrNoMem]>, RISCVVIntrinsic {
  386. let SplatOperand = 2;
  387. }
  388. // For binary operations with mask type output.
  389. // Output: (mask type output)
  390. // Input: (vector_in, vector_in/scalar_in, vl)
  391. class RISCVBinaryMOut
  392. : Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
  393. [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
  394. [IntrNoMem]>, RISCVVIntrinsic {
  395. let SplatOperand = 2;
  396. }
  397. // For binary operations with mask type output without mask.
  398. // Output: (mask type output)
  399. // Input: (vector_in, vector_in/scalar_in, vl)
  400. class RISCVCompareNoMask
  401. : Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
  402. [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
  403. [IntrNoMem]>, RISCVVIntrinsic {
  404. let SplatOperand = 2;
  405. }
  406. // For binary operations with mask type output with mask.
  407. // Output: (mask type output)
  408. // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
  409. class RISCVCompareMask
  410. : Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
  411. [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  412. llvm_anyvector_ty, llvm_any_ty,
  413. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  414. [IntrNoMem]>, RISCVVIntrinsic {
  415. let SplatOperand = 3;
  416. }
  417. // For FP classify operations.
  418. // Output: (bit mask type output)
  419. // Input: (vector_in, vl)
  420. class RISCVClassifyNoMask
  421. : Intrinsic<[LLVMVectorOfBitcastsToInt<0>],
  422. [llvm_anyvector_ty, llvm_anyint_ty],
  423. [IntrNoMem]>, RISCVVIntrinsic;
  424. // For FP classify operations with mask.
  425. // Output: (bit mask type output)
  426. // Input: (maskedoff, vector_in, mask, vl)
  427. class RISCVClassifyMask
  428. : Intrinsic<[LLVMVectorOfBitcastsToInt<0>],
  429. [LLVMVectorOfBitcastsToInt<0>, llvm_anyvector_ty,
  430. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  431. [IntrNoMem]>, RISCVVIntrinsic;
  432. // For Saturating binary operations.
  433. // The destination vector type is the same as first source vector.
  434. // Input: (vector_in, vector_in/scalar_in, vl)
  435. class RISCVSaturatingBinaryAAXNoMask
  436. : Intrinsic<[llvm_anyvector_ty],
  437. [LLVMMatchType<0>, llvm_any_ty, llvm_anyint_ty],
  438. [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
  439. let SplatOperand = 2;
  440. }
  441. // For Saturating binary operations with mask.
  442. // The destination vector type is the same as first source vector.
  443. // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
  444. class RISCVSaturatingBinaryAAXMask
  445. : Intrinsic<[llvm_anyvector_ty],
  446. [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty,
  447. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  448. [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
  449. let SplatOperand = 3;
  450. }
  451. // For Saturating binary operations.
  452. // The destination vector type is the same as first source vector.
  453. // The second source operand matches the destination type or is an XLen scalar.
  454. // Input: (vector_in, vector_in/scalar_in, vl)
  455. class RISCVSaturatingBinaryAAShiftNoMask
  456. : Intrinsic<[llvm_anyvector_ty],
  457. [LLVMMatchType<0>, llvm_any_ty, llvm_anyint_ty],
  458. [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic;
  459. // For Saturating binary operations with mask.
  460. // The destination vector type is the same as first source vector.
  461. // The second source operand matches the destination type or is an XLen scalar.
  462. // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
  463. class RISCVSaturatingBinaryAAShiftMask
  464. : Intrinsic<[llvm_anyvector_ty],
  465. [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty,
  466. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  467. [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic;
  468. // For Saturating binary operations.
  469. // The destination vector type is NOT the same as first source vector.
  470. // The second source operand matches the destination type or is an XLen scalar.
  471. // Input: (vector_in, vector_in/scalar_in, vl)
  472. class RISCVSaturatingBinaryABShiftNoMask
  473. : Intrinsic<[llvm_anyvector_ty],
  474. [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
  475. [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic;
  476. // For Saturating binary operations with mask.
  477. // The destination vector type is NOT the same as first source vector (with mask).
  478. // The second source operand matches the destination type or is an XLen scalar.
  479. // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
  480. class RISCVSaturatingBinaryABShiftMask
  481. : Intrinsic<[llvm_anyvector_ty],
  482. [LLVMMatchType<0>, llvm_anyvector_ty, llvm_any_ty,
  483. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  484. [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic;
  485. class RISCVTernaryAAAXNoMask
  486. : Intrinsic<[llvm_anyvector_ty],
  487. [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty,
  488. LLVMMatchType<1>],
  489. [IntrNoMem]>, RISCVVIntrinsic;
  490. class RISCVTernaryAAAXMask
  491. : Intrinsic<[llvm_anyvector_ty],
  492. [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty,
  493. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<1>],
  494. [IntrNoMem]>, RISCVVIntrinsic;
  495. class RISCVTernaryAAXANoMask
  496. : Intrinsic<[llvm_anyvector_ty],
  497. [LLVMMatchType<0>, llvm_any_ty, LLVMMatchType<0>,
  498. llvm_anyint_ty],
  499. [IntrNoMem]>, RISCVVIntrinsic {
  500. let SplatOperand = 2;
  501. }
  502. class RISCVTernaryAAXAMask
  503. : Intrinsic<[llvm_anyvector_ty],
  504. [LLVMMatchType<0>, llvm_any_ty, LLVMMatchType<0>,
  505. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  506. [IntrNoMem]>, RISCVVIntrinsic {
  507. let SplatOperand = 2;
  508. }
  509. class RISCVTernaryWideNoMask
  510. : Intrinsic< [llvm_anyvector_ty],
  511. [LLVMMatchType<0>, llvm_any_ty, llvm_anyvector_ty,
  512. llvm_anyint_ty],
  513. [IntrNoMem] >, RISCVVIntrinsic {
  514. let SplatOperand = 2;
  515. }
  516. class RISCVTernaryWideMask
  517. : Intrinsic< [llvm_anyvector_ty],
  518. [LLVMMatchType<0>, llvm_any_ty, llvm_anyvector_ty,
  519. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  520. [IntrNoMem]>, RISCVVIntrinsic {
  521. let SplatOperand = 2;
  522. }
  523. // For Reduction ternary operations.
  524. // For destination vector type is the same as first and third source vector.
  525. // Input: (vector_in, vector_in, vector_in, vl)
  526. class RISCVReductionNoMask
  527. : Intrinsic<[llvm_anyvector_ty],
  528. [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>,
  529. llvm_anyint_ty],
  530. [IntrNoMem]>, RISCVVIntrinsic;
  531. // For Reduction ternary operations with mask.
  532. // For destination vector type is the same as first and third source vector.
  533. // The mask type come from second source vector.
  534. // Input: (maskedoff, vector_in, vector_in, vector_in, mask, vl)
  535. class RISCVReductionMask
  536. : Intrinsic<[llvm_anyvector_ty],
  537. [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>,
  538. LLVMScalarOrSameVectorWidth<1, llvm_i1_ty>, llvm_anyint_ty],
  539. [IntrNoMem]>, RISCVVIntrinsic;
  540. // For unary operations with scalar type output without mask
  541. // Output: (scalar type)
  542. // Input: (vector_in, vl)
  543. class RISCVMaskUnarySOutNoMask
  544. : Intrinsic<[LLVMMatchType<1>],
  545. [llvm_anyvector_ty, llvm_anyint_ty],
  546. [IntrNoMem]>, RISCVVIntrinsic;
  547. // For unary operations with scalar type output with mask
  548. // Output: (scalar type)
  549. // Input: (vector_in, mask, vl)
  550. class RISCVMaskUnarySOutMask
  551. : Intrinsic<[LLVMMatchType<1>],
  552. [llvm_anyvector_ty, LLVMMatchType<0>, llvm_anyint_ty],
  553. [IntrNoMem]>, RISCVVIntrinsic;
  554. // For destination vector type is NOT the same as source vector.
  555. // Input: (vector_in, vl)
  556. class RISCVUnaryABNoMask
  557. : Intrinsic<[llvm_anyvector_ty],
  558. [llvm_anyvector_ty, llvm_anyint_ty],
  559. [IntrNoMem]>, RISCVVIntrinsic;
  560. // For destination vector type is NOT the same as source vector (with mask).
  561. // Input: (maskedoff, vector_in, mask, vl)
  562. class RISCVUnaryABMask
  563. : Intrinsic<[llvm_anyvector_ty],
  564. [LLVMMatchType<0>, llvm_anyvector_ty,
  565. LLVMScalarOrSameVectorWidth<1, llvm_i1_ty>,
  566. llvm_anyint_ty],
  567. [IntrNoMem]>, RISCVVIntrinsic;
  568. // For unary operations with the same vector type in/out without mask
  569. // Output: (vector)
  570. // Input: (vector_in, vl)
  571. class RISCVUnaryNoMask
  572. : Intrinsic<[llvm_anyvector_ty],
  573. [LLVMMatchType<0>, llvm_anyint_ty],
  574. [IntrNoMem]>, RISCVVIntrinsic;
  575. // For mask unary operations with mask type in/out with mask
  576. // Output: (mask type output)
  577. // Input: (mask type maskedoff, mask type vector_in, mask, vl)
  578. class RISCVMaskUnaryMOutMask
  579. : Intrinsic<[llvm_anyint_ty],
  580. [LLVMMatchType<0>, LLVMMatchType<0>,
  581. LLVMMatchType<0>, llvm_anyint_ty],
  582. [IntrNoMem]>, RISCVVIntrinsic;
  583. // Output: (vector)
  584. // Input: (vl)
  585. class RISCVNullaryIntrinsic
  586. : Intrinsic<[llvm_anyvector_ty],
  587. [llvm_anyint_ty],
  588. [IntrNoMem]>, RISCVVIntrinsic;
  589. // For Conversion unary operations.
  590. // Input: (vector_in, vl)
  591. class RISCVConversionNoMask
  592. : Intrinsic<[llvm_anyvector_ty],
  593. [llvm_anyvector_ty, llvm_anyint_ty],
  594. [IntrNoMem]>, RISCVVIntrinsic;
  595. // For Conversion unary operations with mask.
  596. // Input: (maskedoff, vector_in, mask, vl)
  597. class RISCVConversionMask
  598. : Intrinsic<[llvm_anyvector_ty],
  599. [LLVMMatchType<0>, llvm_anyvector_ty,
  600. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  601. [IntrNoMem]>, RISCVVIntrinsic;
  602. // For atomic operations without mask
  603. // Input: (base, index, value, vl)
  604. class RISCVAMONoMask
  605. : Intrinsic<[llvm_anyvector_ty],
  606. [LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty, LLVMMatchType<0>,
  607. llvm_anyint_ty],
  608. [NoCapture<ArgIndex<0>>]>, RISCVVIntrinsic;
  609. // For atomic operations with mask
  610. // Input: (base, index, value, mask, vl)
  611. class RISCVAMOMask
  612. : Intrinsic<[llvm_anyvector_ty],
  613. [LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty, LLVMMatchType<0>,
  614. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
  615. [NoCapture<ArgIndex<0>>]>, RISCVVIntrinsic;
  616. // For unit stride segment load
  617. // Input: (pointer, vl)
  618. class RISCVUSSegLoad<int nf>
  619. : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
  620. !add(nf, -1))),
  621. [LLVMPointerToElt<0>, llvm_anyint_ty],
  622. [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
  623. // For unit stride segment load with mask
  624. // Input: (maskedoff, pointer, mask, vl)
  625. class RISCVUSSegLoadMask<int nf>
  626. : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
  627. !add(nf, -1))),
  628. !listconcat(!listsplat(LLVMMatchType<0>, nf),
  629. [LLVMPointerToElt<0>,
  630. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  631. llvm_anyint_ty]),
  632. [NoCapture<ArgIndex<nf>>, IntrReadMem]>, RISCVVIntrinsic;
  633. // For unit stride fault-only-first segment load
  634. // Input: (pointer, vl)
  635. // Output: (data, vl)
  636. // NOTE: We model this with default memory properties since we model writing
  637. // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
  638. class RISCVUSSegLoadFF<int nf>
  639. : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
  640. !add(nf, -1)), [llvm_anyint_ty]),
  641. [LLVMPointerToElt<0>, LLVMMatchType<1>],
  642. [NoCapture<ArgIndex<0>>]>, RISCVVIntrinsic;
  643. // For unit stride fault-only-first segment load with mask
  644. // Input: (maskedoff, pointer, mask, vl)
  645. // Output: (data, vl)
  646. // NOTE: We model this with default memory properties since we model writing
  647. // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
  648. class RISCVUSSegLoadFFMask<int nf>
  649. : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
  650. !add(nf, -1)), [llvm_anyint_ty]),
  651. !listconcat(!listsplat(LLVMMatchType<0>, nf),
  652. [LLVMPointerToElt<0>,
  653. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  654. LLVMMatchType<1>]),
  655. [NoCapture<ArgIndex<nf>>]>, RISCVVIntrinsic;
  656. // For stride segment load
  657. // Input: (pointer, offset, vl)
  658. class RISCVSSegLoad<int nf>
  659. : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
  660. !add(nf, -1))),
  661. [LLVMPointerToElt<0>, llvm_anyint_ty, LLVMMatchType<1>],
  662. [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
  663. // For stride segment load with mask
  664. // Input: (maskedoff, pointer, offset, mask, vl)
  665. class RISCVSSegLoadMask<int nf>
  666. : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
  667. !add(nf, -1))),
  668. !listconcat(!listsplat(LLVMMatchType<0>, nf),
  669. [LLVMPointerToElt<0>,
  670. llvm_anyint_ty,
  671. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  672. LLVMMatchType<1>]),
  673. [NoCapture<ArgIndex<nf>>, IntrReadMem]>, RISCVVIntrinsic;
  674. // For indexed segment load
  675. // Input: (pointer, index, vl)
  676. class RISCVISegLoad<int nf>
  677. : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
  678. !add(nf, -1))),
  679. [LLVMPointerToElt<0>, llvm_anyvector_ty, llvm_anyint_ty],
  680. [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
  681. // For indexed segment load with mask
  682. // Input: (maskedoff, pointer, index, mask, vl)
  683. class RISCVISegLoadMask<int nf>
  684. : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
  685. !add(nf, -1))),
  686. !listconcat(!listsplat(LLVMMatchType<0>, nf),
  687. [LLVMPointerToElt<0>,
  688. llvm_anyvector_ty,
  689. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  690. llvm_anyint_ty]),
  691. [NoCapture<ArgIndex<nf>>, IntrReadMem]>, RISCVVIntrinsic;
  692. // For unit stride segment store
  693. // Input: (value, pointer, vl)
  694. class RISCVUSSegStore<int nf>
  695. : Intrinsic<[],
  696. !listconcat([llvm_anyvector_ty],
  697. !listsplat(LLVMMatchType<0>, !add(nf, -1)),
  698. [LLVMPointerToElt<0>, llvm_anyint_ty]),
  699. [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
  700. // For unit stride segment store with mask
  701. // Input: (value, pointer, mask, vl)
  702. class RISCVUSSegStoreMask<int nf>
  703. : Intrinsic<[],
  704. !listconcat([llvm_anyvector_ty],
  705. !listsplat(LLVMMatchType<0>, !add(nf, -1)),
  706. [LLVMPointerToElt<0>,
  707. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  708. llvm_anyint_ty]),
  709. [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
  710. // For stride segment store
  711. // Input: (value, pointer, offset, vl)
  712. class RISCVSSegStore<int nf>
  713. : Intrinsic<[],
  714. !listconcat([llvm_anyvector_ty],
  715. !listsplat(LLVMMatchType<0>, !add(nf, -1)),
  716. [LLVMPointerToElt<0>, llvm_anyint_ty,
  717. LLVMMatchType<1>]),
  718. [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
  719. // For stride segment store with mask
  720. // Input: (value, pointer, offset, mask, vl)
  721. class RISCVSSegStoreMask<int nf>
  722. : Intrinsic<[],
  723. !listconcat([llvm_anyvector_ty],
  724. !listsplat(LLVMMatchType<0>, !add(nf, -1)),
  725. [LLVMPointerToElt<0>, llvm_anyint_ty,
  726. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  727. LLVMMatchType<1>]),
  728. [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
  729. // For indexed segment store
  730. // Input: (value, pointer, offset, vl)
  731. class RISCVISegStore<int nf>
  732. : Intrinsic<[],
  733. !listconcat([llvm_anyvector_ty],
  734. !listsplat(LLVMMatchType<0>, !add(nf, -1)),
  735. [LLVMPointerToElt<0>, llvm_anyvector_ty,
  736. llvm_anyint_ty]),
  737. [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
  738. // For indexed segment store with mask
  739. // Input: (value, pointer, offset, mask, vl)
  740. class RISCVISegStoreMask<int nf>
  741. : Intrinsic<[],
  742. !listconcat([llvm_anyvector_ty],
  743. !listsplat(LLVMMatchType<0>, !add(nf, -1)),
  744. [LLVMPointerToElt<0>, llvm_anyvector_ty,
  745. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  746. llvm_anyint_ty]),
  747. [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
  748. multiclass RISCVUSLoad {
  749. def "int_riscv_" # NAME : RISCVUSLoad;
  750. def "int_riscv_" # NAME # "_mask" : RISCVUSLoadMask;
  751. }
  752. multiclass RISCVUSLoadFF {
  753. def "int_riscv_" # NAME : RISCVUSLoadFF;
  754. def "int_riscv_" # NAME # "_mask" : RISCVUSLoadFFMask;
  755. }
  756. multiclass RISCVSLoad {
  757. def "int_riscv_" # NAME : RISCVSLoad;
  758. def "int_riscv_" # NAME # "_mask" : RISCVSLoadMask;
  759. }
  760. multiclass RISCVILoad {
  761. def "int_riscv_" # NAME : RISCVILoad;
  762. def "int_riscv_" # NAME # "_mask" : RISCVILoadMask;
  763. }
  764. multiclass RISCVUSStore {
  765. def "int_riscv_" # NAME : RISCVUSStore;
  766. def "int_riscv_" # NAME # "_mask" : RISCVUSStoreMask;
  767. }
  768. multiclass RISCVSStore {
  769. def "int_riscv_" # NAME : RISCVSStore;
  770. def "int_riscv_" # NAME # "_mask" : RISCVSStoreMask;
  771. }
  772. multiclass RISCVIStore {
  773. def "int_riscv_" # NAME : RISCVIStore;
  774. def "int_riscv_" # NAME # "_mask" : RISCVIStoreMask;
  775. }
  776. multiclass RISCVUnaryAA {
  777. def "int_riscv_" # NAME : RISCVUnaryAANoMask;
  778. def "int_riscv_" # NAME # "_mask" : RISCVUnaryAAMask;
  779. }
  780. multiclass RISCVUnaryAB {
  781. def "int_riscv_" # NAME : RISCVUnaryABNoMask;
  782. def "int_riscv_" # NAME # "_mask" : RISCVUnaryABMask;
  783. }
  784. // AAX means the destination type(A) is the same as the first source
  785. // type(A). X means any type for the second source operand.
  786. multiclass RISCVBinaryAAX {
  787. def "int_riscv_" # NAME : RISCVBinaryAAXNoMask;
  788. def "int_riscv_" # NAME # "_mask" : RISCVBinaryAAXMask;
  789. }
  790. // Like RISCVBinaryAAX, but the second operand is used a shift amount so it
  791. // must be a vector or an XLen scalar.
  792. multiclass RISCVBinaryAAShift {
  793. def "int_riscv_" # NAME : RISCVBinaryAAShiftNoMask;
  794. def "int_riscv_" # NAME # "_mask" : RISCVBinaryAAShiftMask;
  795. }
  796. multiclass RISCVRGatherVV {
  797. def "int_riscv_" # NAME : RISCVRGatherVVNoMask;
  798. def "int_riscv_" # NAME # "_mask" : RISCVRGatherVVMask;
  799. }
  800. multiclass RISCVRGatherVX {
  801. def "int_riscv_" # NAME : RISCVGatherVXNoMask;
  802. def "int_riscv_" # NAME # "_mask" : RISCVGatherVXMask;
  803. }
  804. multiclass RISCVRGatherEI16VV {
  805. def "int_riscv_" # NAME : RISCVRGatherEI16VVNoMask;
  806. def "int_riscv_" # NAME # "_mask" : RISCVRGatherEI16VVMask;
  807. }
  808. // ABX means the destination type(A) is different from the first source
  809. // type(B). X means any type for the second source operand.
  810. multiclass RISCVBinaryABX {
  811. def "int_riscv_" # NAME : RISCVBinaryABXNoMask;
  812. def "int_riscv_" # NAME # "_mask" : RISCVBinaryABXMask;
  813. }
  814. // Like RISCVBinaryABX, but the second operand is used a shift amount so it
  815. // must be a vector or an XLen scalar.
  816. multiclass RISCVBinaryABShift {
  817. def "int_riscv_" # NAME : RISCVBinaryABShiftNoMask;
  818. def "int_riscv_" # NAME # "_mask" : RISCVBinaryABShiftMask;
  819. }
  820. multiclass RISCVBinaryWithV0 {
  821. def "int_riscv_" # NAME : RISCVBinaryWithV0;
  822. }
  823. multiclass RISCVBinaryMaskOutWithV0 {
  824. def "int_riscv_" # NAME : RISCVBinaryMOutWithV0;
  825. }
  826. multiclass RISCVBinaryMaskOut {
  827. def "int_riscv_" # NAME : RISCVBinaryMOut;
  828. }
  829. multiclass RISCVSaturatingBinaryAAX {
  830. def "int_riscv_" # NAME : RISCVSaturatingBinaryAAXNoMask;
  831. def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryAAXMask;
  832. }
  833. multiclass RISCVSaturatingBinaryAAShift {
  834. def "int_riscv_" # NAME : RISCVSaturatingBinaryAAShiftNoMask;
  835. def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryAAShiftMask;
  836. }
  837. multiclass RISCVSaturatingBinaryABShift {
  838. def "int_riscv_" # NAME : RISCVSaturatingBinaryABShiftNoMask;
  839. def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryABShiftMask;
  840. }
  841. multiclass RISCVTernaryAAAX {
  842. def "int_riscv_" # NAME : RISCVTernaryAAAXNoMask;
  843. def "int_riscv_" # NAME # "_mask" : RISCVTernaryAAAXMask;
  844. }
  845. multiclass RISCVTernaryAAXA {
  846. def "int_riscv_" # NAME : RISCVTernaryAAXANoMask;
  847. def "int_riscv_" # NAME # "_mask" : RISCVTernaryAAXAMask;
  848. }
  849. multiclass RISCVCompare {
  850. def "int_riscv_" # NAME : RISCVCompareNoMask;
  851. def "int_riscv_" # NAME # "_mask" : RISCVCompareMask;
  852. }
  853. multiclass RISCVClassify {
  854. def "int_riscv_" # NAME : RISCVClassifyNoMask;
  855. def "int_riscv_" # NAME # "_mask" : RISCVClassifyMask;
  856. }
  857. multiclass RISCVTernaryWide {
  858. def "int_riscv_" # NAME : RISCVTernaryWideNoMask;
  859. def "int_riscv_" # NAME # "_mask" : RISCVTernaryWideMask;
  860. }
  861. multiclass RISCVReduction {
  862. def "int_riscv_" # NAME : RISCVReductionNoMask;
  863. def "int_riscv_" # NAME # "_mask" : RISCVReductionMask;
  864. }
  865. multiclass RISCVMaskUnarySOut {
  866. def "int_riscv_" # NAME : RISCVMaskUnarySOutNoMask;
  867. def "int_riscv_" # NAME # "_mask" : RISCVMaskUnarySOutMask;
  868. }
  869. multiclass RISCVMaskUnaryMOut {
  870. def "int_riscv_" # NAME : RISCVUnaryNoMask;
  871. def "int_riscv_" # NAME # "_mask" : RISCVMaskUnaryMOutMask;
  872. }
  873. multiclass RISCVConversion {
  874. def "int_riscv_" #NAME :RISCVConversionNoMask;
  875. def "int_riscv_" # NAME # "_mask" : RISCVConversionMask;
  876. }
  877. multiclass RISCVAMO {
  878. def "int_riscv_" # NAME : RISCVAMONoMask;
  879. def "int_riscv_" # NAME # "_mask" : RISCVAMOMask;
  880. }
  881. multiclass RISCVUSSegLoad<int nf> {
  882. def "int_riscv_" # NAME : RISCVUSSegLoad<nf>;
  883. def "int_riscv_" # NAME # "_mask" : RISCVUSSegLoadMask<nf>;
  884. }
  885. multiclass RISCVUSSegLoadFF<int nf> {
  886. def "int_riscv_" # NAME : RISCVUSSegLoadFF<nf>;
  887. def "int_riscv_" # NAME # "_mask" : RISCVUSSegLoadFFMask<nf>;
  888. }
  889. multiclass RISCVSSegLoad<int nf> {
  890. def "int_riscv_" # NAME : RISCVSSegLoad<nf>;
  891. def "int_riscv_" # NAME # "_mask" : RISCVSSegLoadMask<nf>;
  892. }
  893. multiclass RISCVISegLoad<int nf> {
  894. def "int_riscv_" # NAME : RISCVISegLoad<nf>;
  895. def "int_riscv_" # NAME # "_mask" : RISCVISegLoadMask<nf>;
  896. }
  897. multiclass RISCVUSSegStore<int nf> {
  898. def "int_riscv_" # NAME : RISCVUSSegStore<nf>;
  899. def "int_riscv_" # NAME # "_mask" : RISCVUSSegStoreMask<nf>;
  900. }
  901. multiclass RISCVSSegStore<int nf> {
  902. def "int_riscv_" # NAME : RISCVSSegStore<nf>;
  903. def "int_riscv_" # NAME # "_mask" : RISCVSSegStoreMask<nf>;
  904. }
  905. multiclass RISCVISegStore<int nf> {
  906. def "int_riscv_" # NAME : RISCVISegStore<nf>;
  907. def "int_riscv_" # NAME # "_mask" : RISCVISegStoreMask<nf>;
  908. }
  909. defm vle : RISCVUSLoad;
  910. defm vleff : RISCVUSLoadFF;
  911. defm vse : RISCVUSStore;
  912. defm vlse: RISCVSLoad;
  913. defm vsse: RISCVSStore;
  914. defm vluxei : RISCVILoad;
  915. defm vloxei : RISCVILoad;
  916. defm vsoxei : RISCVIStore;
  917. defm vsuxei : RISCVIStore;
  918. def int_riscv_vle1 : RISCVUSLoad;
  919. def int_riscv_vse1 : RISCVUSStore;
  920. defm vamoswap : RISCVAMO;
  921. defm vamoadd : RISCVAMO;
  922. defm vamoxor : RISCVAMO;
  923. defm vamoand : RISCVAMO;
  924. defm vamoor : RISCVAMO;
  925. defm vamomin : RISCVAMO;
  926. defm vamomax : RISCVAMO;
  927. defm vamominu : RISCVAMO;
  928. defm vamomaxu : RISCVAMO;
  929. defm vadd : RISCVBinaryAAX;
  930. defm vsub : RISCVBinaryAAX;
  931. defm vrsub : RISCVBinaryAAX;
  932. defm vwaddu : RISCVBinaryABX;
  933. defm vwadd : RISCVBinaryABX;
  934. defm vwaddu_w : RISCVBinaryAAX;
  935. defm vwadd_w : RISCVBinaryAAX;
  936. defm vwsubu : RISCVBinaryABX;
  937. defm vwsub : RISCVBinaryABX;
  938. defm vwsubu_w : RISCVBinaryAAX;
  939. defm vwsub_w : RISCVBinaryAAX;
  940. defm vzext : RISCVUnaryAB;
  941. defm vsext : RISCVUnaryAB;
  942. defm vadc : RISCVBinaryWithV0;
  943. defm vmadc_carry_in : RISCVBinaryMaskOutWithV0;
  944. defm vmadc : RISCVBinaryMaskOut;
  945. defm vsbc : RISCVBinaryWithV0;
  946. defm vmsbc_borrow_in : RISCVBinaryMaskOutWithV0;
  947. defm vmsbc : RISCVBinaryMaskOut;
  948. defm vand : RISCVBinaryAAX;
  949. defm vor : RISCVBinaryAAX;
  950. defm vxor : RISCVBinaryAAX;
  951. defm vsll : RISCVBinaryAAShift;
  952. defm vsrl : RISCVBinaryAAShift;
  953. defm vsra : RISCVBinaryAAShift;
  954. defm vnsrl : RISCVBinaryABShift;
  955. defm vnsra : RISCVBinaryABShift;
  956. defm vmseq : RISCVCompare;
  957. defm vmsne : RISCVCompare;
  958. defm vmsltu : RISCVCompare;
  959. defm vmslt : RISCVCompare;
  960. defm vmsleu : RISCVCompare;
  961. defm vmsle : RISCVCompare;
  962. defm vmsgtu : RISCVCompare;
  963. defm vmsgt : RISCVCompare;
  964. defm vmsgeu : RISCVCompare;
  965. defm vmsge : RISCVCompare;
  966. defm vminu : RISCVBinaryAAX;
  967. defm vmin : RISCVBinaryAAX;
  968. defm vmaxu : RISCVBinaryAAX;
  969. defm vmax : RISCVBinaryAAX;
  970. defm vmul : RISCVBinaryAAX;
  971. defm vmulh : RISCVBinaryAAX;
  972. defm vmulhu : RISCVBinaryAAX;
  973. defm vmulhsu : RISCVBinaryAAX;
  974. defm vdivu : RISCVBinaryAAX;
  975. defm vdiv : RISCVBinaryAAX;
  976. defm vremu : RISCVBinaryAAX;
  977. defm vrem : RISCVBinaryAAX;
  978. defm vwmul : RISCVBinaryABX;
  979. defm vwmulu : RISCVBinaryABX;
  980. defm vwmulsu : RISCVBinaryABX;
  981. defm vmacc : RISCVTernaryAAXA;
  982. defm vnmsac : RISCVTernaryAAXA;
  983. defm vmadd : RISCVTernaryAAXA;
  984. defm vnmsub : RISCVTernaryAAXA;
  985. defm vwmaccu : RISCVTernaryWide;
  986. defm vwmacc : RISCVTernaryWide;
  987. defm vwmaccus : RISCVTernaryWide;
  988. defm vwmaccsu : RISCVTernaryWide;
  989. defm vfadd : RISCVBinaryAAX;
  990. defm vfsub : RISCVBinaryAAX;
  991. defm vfrsub : RISCVBinaryAAX;
  992. defm vfwadd : RISCVBinaryABX;
  993. defm vfwsub : RISCVBinaryABX;
  994. defm vfwadd_w : RISCVBinaryAAX;
  995. defm vfwsub_w : RISCVBinaryAAX;
  996. defm vsaddu : RISCVSaturatingBinaryAAX;
  997. defm vsadd : RISCVSaturatingBinaryAAX;
  998. defm vssubu : RISCVSaturatingBinaryAAX;
  999. defm vssub : RISCVSaturatingBinaryAAX;
  1000. def int_riscv_vmerge : RISCVBinaryWithV0;
  1001. def int_riscv_vmv_v_v : Intrinsic<[llvm_anyvector_ty],
  1002. [LLVMMatchType<0>, llvm_anyint_ty],
  1003. [IntrNoMem]>, RISCVVIntrinsic;
  1004. def int_riscv_vmv_v_x : Intrinsic<[llvm_anyint_ty],
  1005. [LLVMVectorElementType<0>, llvm_anyint_ty],
  1006. [IntrNoMem]>, RISCVVIntrinsic;
  1007. def int_riscv_vfmv_v_f : Intrinsic<[llvm_anyfloat_ty],
  1008. [LLVMVectorElementType<0>, llvm_anyint_ty],
  1009. [IntrNoMem]>, RISCVVIntrinsic;
  1010. def int_riscv_vmv_x_s : Intrinsic<[LLVMVectorElementType<0>],
  1011. [llvm_anyint_ty],
  1012. [IntrNoMem]>, RISCVVIntrinsic;
  1013. def int_riscv_vmv_s_x : Intrinsic<[llvm_anyint_ty],
  1014. [LLVMMatchType<0>, LLVMVectorElementType<0>,
  1015. llvm_anyint_ty],
  1016. [IntrNoMem]>, RISCVVIntrinsic;
  1017. def int_riscv_vfmv_f_s : Intrinsic<[LLVMVectorElementType<0>],
  1018. [llvm_anyfloat_ty],
  1019. [IntrNoMem]>, RISCVVIntrinsic;
  1020. def int_riscv_vfmv_s_f : Intrinsic<[llvm_anyfloat_ty],
  1021. [LLVMMatchType<0>, LLVMVectorElementType<0>,
  1022. llvm_anyint_ty],
  1023. [IntrNoMem]>, RISCVVIntrinsic;
  1024. defm vfmul : RISCVBinaryAAX;
  1025. defm vfdiv : RISCVBinaryAAX;
  1026. defm vfrdiv : RISCVBinaryAAX;
  1027. defm vfwmul : RISCVBinaryABX;
  1028. defm vfmacc : RISCVTernaryAAXA;
  1029. defm vfnmacc : RISCVTernaryAAXA;
  1030. defm vfmsac : RISCVTernaryAAXA;
  1031. defm vfnmsac : RISCVTernaryAAXA;
  1032. defm vfmadd : RISCVTernaryAAXA;
  1033. defm vfnmadd : RISCVTernaryAAXA;
  1034. defm vfmsub : RISCVTernaryAAXA;
  1035. defm vfnmsub : RISCVTernaryAAXA;
  1036. defm vfwmacc : RISCVTernaryWide;
  1037. defm vfwnmacc : RISCVTernaryWide;
  1038. defm vfwmsac : RISCVTernaryWide;
  1039. defm vfwnmsac : RISCVTernaryWide;
  1040. defm vfsqrt : RISCVUnaryAA;
  1041. defm vfrsqrt7 : RISCVUnaryAA;
  1042. defm vfrec7 : RISCVUnaryAA;
  1043. defm vfmin : RISCVBinaryAAX;
  1044. defm vfmax : RISCVBinaryAAX;
  1045. defm vfsgnj : RISCVBinaryAAX;
  1046. defm vfsgnjn : RISCVBinaryAAX;
  1047. defm vfsgnjx : RISCVBinaryAAX;
  1048. defm vfclass : RISCVClassify;
  1049. defm vfmerge : RISCVBinaryWithV0;
  1050. defm vslideup : RISCVTernaryAAAX;
  1051. defm vslidedown : RISCVTernaryAAAX;
  1052. defm vslide1up : RISCVBinaryAAX;
  1053. defm vslide1down : RISCVBinaryAAX;
  1054. defm vfslide1up : RISCVBinaryAAX;
  1055. defm vfslide1down : RISCVBinaryAAX;
  1056. defm vrgather_vv : RISCVRGatherVV;
  1057. defm vrgather_vx : RISCVRGatherVX;
  1058. defm vrgatherei16_vv : RISCVRGatherEI16VV;
  1059. def "int_riscv_vcompress" : RISCVUnaryAAMask;
  1060. defm vaaddu : RISCVSaturatingBinaryAAX;
  1061. defm vaadd : RISCVSaturatingBinaryAAX;
  1062. defm vasubu : RISCVSaturatingBinaryAAX;
  1063. defm vasub : RISCVSaturatingBinaryAAX;
  1064. defm vsmul : RISCVSaturatingBinaryAAX;
  1065. defm vssrl : RISCVSaturatingBinaryAAShift;
  1066. defm vssra : RISCVSaturatingBinaryAAShift;
  1067. defm vnclipu : RISCVSaturatingBinaryABShift;
  1068. defm vnclip : RISCVSaturatingBinaryABShift;
  1069. defm vmfeq : RISCVCompare;
  1070. defm vmfne : RISCVCompare;
  1071. defm vmflt : RISCVCompare;
  1072. defm vmfle : RISCVCompare;
  1073. defm vmfgt : RISCVCompare;
  1074. defm vmfge : RISCVCompare;
  1075. defm vredsum : RISCVReduction;
  1076. defm vredand : RISCVReduction;
  1077. defm vredor : RISCVReduction;
  1078. defm vredxor : RISCVReduction;
  1079. defm vredminu : RISCVReduction;
  1080. defm vredmin : RISCVReduction;
  1081. defm vredmaxu : RISCVReduction;
  1082. defm vredmax : RISCVReduction;
  1083. defm vwredsumu : RISCVReduction;
  1084. defm vwredsum : RISCVReduction;
  1085. defm vfredosum : RISCVReduction;
  1086. defm vfredsum : RISCVReduction;
  1087. defm vfredmin : RISCVReduction;
  1088. defm vfredmax : RISCVReduction;
  1089. defm vfwredsum : RISCVReduction;
  1090. defm vfwredosum : RISCVReduction;
  1091. def int_riscv_vmand: RISCVBinaryAAANoMask;
  1092. def int_riscv_vmnand: RISCVBinaryAAANoMask;
  1093. def int_riscv_vmandnot: RISCVBinaryAAANoMask;
  1094. def int_riscv_vmxor: RISCVBinaryAAANoMask;
  1095. def int_riscv_vmor: RISCVBinaryAAANoMask;
  1096. def int_riscv_vmnor: RISCVBinaryAAANoMask;
  1097. def int_riscv_vmornot: RISCVBinaryAAANoMask;
  1098. def int_riscv_vmxnor: RISCVBinaryAAANoMask;
  1099. def int_riscv_vmclr : RISCVNullaryIntrinsic;
  1100. def int_riscv_vmset : RISCVNullaryIntrinsic;
  1101. defm vpopc : RISCVMaskUnarySOut;
  1102. defm vfirst : RISCVMaskUnarySOut;
  1103. defm vmsbf : RISCVMaskUnaryMOut;
  1104. defm vmsof : RISCVMaskUnaryMOut;
  1105. defm vmsif : RISCVMaskUnaryMOut;
  1106. defm vfcvt_xu_f_v : RISCVConversion;
  1107. defm vfcvt_x_f_v : RISCVConversion;
  1108. defm vfcvt_rtz_xu_f_v : RISCVConversion;
  1109. defm vfcvt_rtz_x_f_v : RISCVConversion;
  1110. defm vfcvt_f_xu_v : RISCVConversion;
  1111. defm vfcvt_f_x_v : RISCVConversion;
  1112. defm vfwcvt_f_xu_v : RISCVConversion;
  1113. defm vfwcvt_f_x_v : RISCVConversion;
  1114. defm vfwcvt_xu_f_v : RISCVConversion;
  1115. defm vfwcvt_x_f_v : RISCVConversion;
  1116. defm vfwcvt_rtz_xu_f_v : RISCVConversion;
  1117. defm vfwcvt_rtz_x_f_v : RISCVConversion;
  1118. defm vfwcvt_f_f_v : RISCVConversion;
  1119. defm vfncvt_f_xu_w : RISCVConversion;
  1120. defm vfncvt_f_x_w : RISCVConversion;
  1121. defm vfncvt_xu_f_w : RISCVConversion;
  1122. defm vfncvt_x_f_w : RISCVConversion;
  1123. defm vfncvt_rtz_xu_f_w : RISCVConversion;
  1124. defm vfncvt_rtz_x_f_w : RISCVConversion;
  1125. defm vfncvt_f_f_w : RISCVConversion;
  1126. defm vfncvt_rod_f_f_w : RISCVConversion;
  1127. // Output: (vector)
  1128. // Input: (mask type input, vl)
  1129. def int_riscv_viota : Intrinsic<[llvm_anyvector_ty],
  1130. [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  1131. llvm_anyint_ty],
  1132. [IntrNoMem]>, RISCVVIntrinsic;
  1133. // Output: (vector)
  1134. // Input: (maskedoff, mask type vector_in, mask, vl)
  1135. def int_riscv_viota_mask : Intrinsic<[llvm_anyvector_ty],
  1136. [LLVMMatchType<0>,
  1137. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  1138. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  1139. llvm_anyint_ty],
  1140. [IntrNoMem]>, RISCVVIntrinsic;
  1141. // Output: (vector)
  1142. // Input: (vl)
  1143. def int_riscv_vid : RISCVNullaryIntrinsic;
  1144. // Output: (vector)
  1145. // Input: (maskedoff, mask, vl)
  1146. def int_riscv_vid_mask : Intrinsic<[llvm_anyvector_ty],
  1147. [LLVMMatchType<0>,
  1148. LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
  1149. llvm_anyint_ty],
  1150. [IntrNoMem]>, RISCVVIntrinsic;
  1151. foreach nf = [2, 3, 4, 5, 6, 7, 8] in {
  1152. defm vlseg # nf : RISCVUSSegLoad<nf>;
  1153. defm vlseg # nf # ff : RISCVUSSegLoadFF<nf>;
  1154. defm vlsseg # nf : RISCVSSegLoad<nf>;
  1155. defm vloxseg # nf : RISCVISegLoad<nf>;
  1156. defm vluxseg # nf : RISCVISegLoad<nf>;
  1157. defm vsseg # nf : RISCVUSSegStore<nf>;
  1158. defm vssseg # nf : RISCVSSegStore<nf>;
  1159. defm vsoxseg # nf : RISCVISegStore<nf>;
  1160. defm vsuxseg # nf : RISCVISegStore<nf>;
  1161. }
  1162. } // TargetPrefix = "riscv"