GenericOpcodes.td 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414
  1. //===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- 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 the generic opcodes used with GlobalISel.
  10. // After instruction selection, these opcodes should not appear.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //------------------------------------------------------------------------------
  14. // Unary ops.
  15. //------------------------------------------------------------------------------
  16. class GenericInstruction : StandardPseudoInstruction {
  17. let isPreISelOpcode = true;
  18. }
  19. // Provide a variant of an instruction with the same operands, but
  20. // different instruction flags. This is intended to provide a
  21. // convenient way to define strict floating point variants of ordinary
  22. // floating point instructions.
  23. class ConstrainedIntruction<GenericInstruction baseInst> :
  24. GenericInstruction {
  25. let OutOperandList = baseInst.OutOperandList;
  26. let InOperandList = baseInst.InOperandList;
  27. let isCommutable = baseInst.isCommutable;
  28. // TODO: Do we need a better way to mark reads from FP mode than
  29. // hasSideEffects?
  30. let hasSideEffects = true;
  31. let mayRaiseFPException = true;
  32. }
  33. // Extend the underlying scalar type of an operation, leaving the high bits
  34. // unspecified.
  35. def G_ANYEXT : GenericInstruction {
  36. let OutOperandList = (outs type0:$dst);
  37. let InOperandList = (ins type1:$src);
  38. let hasSideEffects = false;
  39. }
  40. // Sign extend the underlying scalar type of an operation, copying the sign bit
  41. // into the newly-created space.
  42. def G_SEXT : GenericInstruction {
  43. let OutOperandList = (outs type0:$dst);
  44. let InOperandList = (ins type1:$src);
  45. let hasSideEffects = false;
  46. }
  47. // Sign extend the a value from an arbitrary bit position, copying the sign bit
  48. // into all bits above it. This is equivalent to a shl + ashr pair with an
  49. // appropriate shift amount. $sz is an immediate (MachineOperand::isImm()
  50. // returns true) to allow targets to have some bitwidths legal and others
  51. // lowered. This opcode is particularly useful if the target has sign-extension
  52. // instructions that are cheaper than the constituent shifts as the optimizer is
  53. // able to make decisions on whether it's better to hang on to the G_SEXT_INREG
  54. // or to lower it and optimize the individual shifts.
  55. def G_SEXT_INREG : GenericInstruction {
  56. let OutOperandList = (outs type0:$dst);
  57. let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
  58. let hasSideEffects = false;
  59. }
  60. // Zero extend the underlying scalar type of an operation, putting zero bits
  61. // into the newly-created space.
  62. def G_ZEXT : GenericInstruction {
  63. let OutOperandList = (outs type0:$dst);
  64. let InOperandList = (ins type1:$src);
  65. let hasSideEffects = false;
  66. }
  67. // Truncate the underlying scalar type of an operation. This is equivalent to
  68. // G_EXTRACT for scalar types, but acts elementwise on vectors.
  69. def G_TRUNC : GenericInstruction {
  70. let OutOperandList = (outs type0:$dst);
  71. let InOperandList = (ins type1:$src);
  72. let hasSideEffects = false;
  73. }
  74. def G_IMPLICIT_DEF : GenericInstruction {
  75. let OutOperandList = (outs type0:$dst);
  76. let InOperandList = (ins);
  77. let hasSideEffects = false;
  78. }
  79. def G_PHI : GenericInstruction {
  80. let OutOperandList = (outs type0:$dst);
  81. let InOperandList = (ins variable_ops);
  82. let hasSideEffects = false;
  83. }
  84. def G_FRAME_INDEX : GenericInstruction {
  85. let OutOperandList = (outs type0:$dst);
  86. let InOperandList = (ins unknown:$src2);
  87. let hasSideEffects = false;
  88. }
  89. def G_GLOBAL_VALUE : GenericInstruction {
  90. let OutOperandList = (outs type0:$dst);
  91. let InOperandList = (ins unknown:$src);
  92. let hasSideEffects = false;
  93. }
  94. def G_INTTOPTR : GenericInstruction {
  95. let OutOperandList = (outs type0:$dst);
  96. let InOperandList = (ins type1:$src);
  97. let hasSideEffects = false;
  98. }
  99. def G_PTRTOINT : GenericInstruction {
  100. let OutOperandList = (outs type0:$dst);
  101. let InOperandList = (ins type1:$src);
  102. let hasSideEffects = false;
  103. }
  104. def G_BITCAST : GenericInstruction {
  105. let OutOperandList = (outs type0:$dst);
  106. let InOperandList = (ins type1:$src);
  107. let hasSideEffects = false;
  108. }
  109. // Only supports scalar result types
  110. def G_CONSTANT : GenericInstruction {
  111. let OutOperandList = (outs type0:$dst);
  112. let InOperandList = (ins unknown:$imm);
  113. let hasSideEffects = false;
  114. }
  115. // Only supports scalar result types
  116. def G_FCONSTANT : GenericInstruction {
  117. let OutOperandList = (outs type0:$dst);
  118. let InOperandList = (ins unknown:$imm);
  119. let hasSideEffects = false;
  120. }
  121. def G_VASTART : GenericInstruction {
  122. let OutOperandList = (outs);
  123. let InOperandList = (ins type0:$list);
  124. let hasSideEffects = false;
  125. let mayStore = true;
  126. }
  127. def G_VAARG : GenericInstruction {
  128. let OutOperandList = (outs type0:$val);
  129. let InOperandList = (ins type1:$list, unknown:$align);
  130. let hasSideEffects = false;
  131. let mayLoad = true;
  132. let mayStore = true;
  133. }
  134. def G_CTLZ : GenericInstruction {
  135. let OutOperandList = (outs type0:$dst);
  136. let InOperandList = (ins type1:$src);
  137. let hasSideEffects = false;
  138. }
  139. def G_CTLZ_ZERO_UNDEF : GenericInstruction {
  140. let OutOperandList = (outs type0:$dst);
  141. let InOperandList = (ins type1:$src);
  142. let hasSideEffects = false;
  143. }
  144. def G_CTTZ : GenericInstruction {
  145. let OutOperandList = (outs type0:$dst);
  146. let InOperandList = (ins type1:$src);
  147. let hasSideEffects = false;
  148. }
  149. def G_CTTZ_ZERO_UNDEF : GenericInstruction {
  150. let OutOperandList = (outs type0:$dst);
  151. let InOperandList = (ins type1:$src);
  152. let hasSideEffects = false;
  153. }
  154. def G_CTPOP : GenericInstruction {
  155. let OutOperandList = (outs type0:$dst);
  156. let InOperandList = (ins type1:$src);
  157. let hasSideEffects = false;
  158. }
  159. def G_BSWAP : GenericInstruction {
  160. let OutOperandList = (outs type0:$dst);
  161. let InOperandList = (ins type0:$src);
  162. let hasSideEffects = false;
  163. }
  164. def G_BITREVERSE : GenericInstruction {
  165. let OutOperandList = (outs type0:$dst);
  166. let InOperandList = (ins type0:$src);
  167. let hasSideEffects = false;
  168. }
  169. def G_ADDRSPACE_CAST : GenericInstruction {
  170. let OutOperandList = (outs type0:$dst);
  171. let InOperandList = (ins type1:$src);
  172. let hasSideEffects = false;
  173. }
  174. def G_BLOCK_ADDR : GenericInstruction {
  175. let OutOperandList = (outs type0:$dst);
  176. let InOperandList = (ins unknown:$ba);
  177. let hasSideEffects = false;
  178. }
  179. def G_JUMP_TABLE : GenericInstruction {
  180. let OutOperandList = (outs type0:$dst);
  181. let InOperandList = (ins unknown:$jti);
  182. let hasSideEffects = false;
  183. }
  184. def G_DYN_STACKALLOC : GenericInstruction {
  185. let OutOperandList = (outs ptype0:$dst);
  186. let InOperandList = (ins type1:$size, i32imm:$align);
  187. let hasSideEffects = true;
  188. }
  189. def G_FREEZE : GenericInstruction {
  190. let OutOperandList = (outs type0:$dst);
  191. let InOperandList = (ins type0:$src);
  192. let hasSideEffects = false;
  193. }
  194. //------------------------------------------------------------------------------
  195. // Binary ops.
  196. //------------------------------------------------------------------------------
  197. // Generic addition.
  198. def G_ADD : GenericInstruction {
  199. let OutOperandList = (outs type0:$dst);
  200. let InOperandList = (ins type0:$src1, type0:$src2);
  201. let hasSideEffects = false;
  202. let isCommutable = true;
  203. }
  204. // Generic subtraction.
  205. def G_SUB : GenericInstruction {
  206. let OutOperandList = (outs type0:$dst);
  207. let InOperandList = (ins type0:$src1, type0:$src2);
  208. let hasSideEffects = false;
  209. let isCommutable = false;
  210. }
  211. // Generic multiplication.
  212. def G_MUL : GenericInstruction {
  213. let OutOperandList = (outs type0:$dst);
  214. let InOperandList = (ins type0:$src1, type0:$src2);
  215. let hasSideEffects = false;
  216. let isCommutable = true;
  217. }
  218. // Generic signed division.
  219. def G_SDIV : GenericInstruction {
  220. let OutOperandList = (outs type0:$dst);
  221. let InOperandList = (ins type0:$src1, type0:$src2);
  222. let hasSideEffects = false;
  223. let isCommutable = false;
  224. }
  225. // Generic unsigned division.
  226. def G_UDIV : GenericInstruction {
  227. let OutOperandList = (outs type0:$dst);
  228. let InOperandList = (ins type0:$src1, type0:$src2);
  229. let hasSideEffects = false;
  230. let isCommutable = false;
  231. }
  232. // Generic signed remainder.
  233. def G_SREM : GenericInstruction {
  234. let OutOperandList = (outs type0:$dst);
  235. let InOperandList = (ins type0:$src1, type0:$src2);
  236. let hasSideEffects = false;
  237. let isCommutable = false;
  238. }
  239. // Generic unsigned remainder.
  240. def G_UREM : GenericInstruction {
  241. let OutOperandList = (outs type0:$dst);
  242. let InOperandList = (ins type0:$src1, type0:$src2);
  243. let hasSideEffects = false;
  244. let isCommutable = false;
  245. }
  246. // Generic signed division and remainder.
  247. def G_SDIVREM : GenericInstruction {
  248. let OutOperandList = (outs type0:$div, type0:$rem);
  249. let InOperandList = (ins type0:$src1, type0:$src2);
  250. let hasSideEffects = false;
  251. let isCommutable = false;
  252. }
  253. // Generic unsigned division and remainder.
  254. def G_UDIVREM : GenericInstruction {
  255. let OutOperandList = (outs type0:$div, type0:$rem);
  256. let InOperandList = (ins type0:$src1, type0:$src2);
  257. let hasSideEffects = false;
  258. let isCommutable = false;
  259. }
  260. // Generic bitwise and.
  261. def G_AND : GenericInstruction {
  262. let OutOperandList = (outs type0:$dst);
  263. let InOperandList = (ins type0:$src1, type0:$src2);
  264. let hasSideEffects = false;
  265. let isCommutable = true;
  266. }
  267. // Generic bitwise or.
  268. def G_OR : GenericInstruction {
  269. let OutOperandList = (outs type0:$dst);
  270. let InOperandList = (ins type0:$src1, type0:$src2);
  271. let hasSideEffects = false;
  272. let isCommutable = true;
  273. }
  274. // Generic bitwise xor.
  275. def G_XOR : GenericInstruction {
  276. let OutOperandList = (outs type0:$dst);
  277. let InOperandList = (ins type0:$src1, type0:$src2);
  278. let hasSideEffects = false;
  279. let isCommutable = true;
  280. }
  281. // Generic left-shift.
  282. def G_SHL : GenericInstruction {
  283. let OutOperandList = (outs type0:$dst);
  284. let InOperandList = (ins type0:$src1, type1:$src2);
  285. let hasSideEffects = false;
  286. }
  287. // Generic logical right-shift.
  288. def G_LSHR : GenericInstruction {
  289. let OutOperandList = (outs type0:$dst);
  290. let InOperandList = (ins type0:$src1, type1:$src2);
  291. let hasSideEffects = false;
  292. }
  293. // Generic arithmetic right-shift.
  294. def G_ASHR : GenericInstruction {
  295. let OutOperandList = (outs type0:$dst);
  296. let InOperandList = (ins type0:$src1, type1:$src2);
  297. let hasSideEffects = false;
  298. }
  299. /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
  300. /// fshl(X,Y,Z): (X << (Z % bitwidth)) | (Y >> (bitwidth - (Z % bitwidth)))
  301. def G_FSHL : GenericInstruction {
  302. let OutOperandList = (outs type0:$dst);
  303. let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
  304. let hasSideEffects = false;
  305. }
  306. /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
  307. /// fshr(X,Y,Z): (X << (bitwidth - (Z % bitwidth))) | (Y >> (Z % bitwidth))
  308. def G_FSHR : GenericInstruction {
  309. let OutOperandList = (outs type0:$dst);
  310. let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
  311. let hasSideEffects = false;
  312. }
  313. /// Rotate bits right.
  314. def G_ROTR : GenericInstruction {
  315. let OutOperandList = (outs type0:$dst);
  316. let InOperandList = (ins type0:$src1, type1:$src2);
  317. let hasSideEffects = false;
  318. }
  319. /// Rotate bits left.
  320. def G_ROTL : GenericInstruction {
  321. let OutOperandList = (outs type0:$dst);
  322. let InOperandList = (ins type0:$src1, type1:$src2);
  323. let hasSideEffects = false;
  324. }
  325. // Generic integer comparison.
  326. def G_ICMP : GenericInstruction {
  327. let OutOperandList = (outs type0:$dst);
  328. let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
  329. let hasSideEffects = false;
  330. }
  331. // Generic floating-point comparison.
  332. def G_FCMP : GenericInstruction {
  333. let OutOperandList = (outs type0:$dst);
  334. let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
  335. let hasSideEffects = false;
  336. }
  337. // Generic select
  338. def G_SELECT : GenericInstruction {
  339. let OutOperandList = (outs type0:$dst);
  340. let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
  341. let hasSideEffects = false;
  342. }
  343. // Generic pointer offset.
  344. def G_PTR_ADD : GenericInstruction {
  345. let OutOperandList = (outs type0:$dst);
  346. let InOperandList = (ins type0:$src1, type1:$src2);
  347. let hasSideEffects = false;
  348. }
  349. // Generic pointer mask. type1 should be an integer with the same
  350. // bitwidth as the pointer type.
  351. def G_PTRMASK : GenericInstruction {
  352. let OutOperandList = (outs ptype0:$dst);
  353. let InOperandList = (ins ptype0:$src, type1:$bits);
  354. let hasSideEffects = false;
  355. }
  356. // Generic signed integer minimum.
  357. def G_SMIN : GenericInstruction {
  358. let OutOperandList = (outs type0:$dst);
  359. let InOperandList = (ins type0:$src1, type0:$src2);
  360. let hasSideEffects = false;
  361. let isCommutable = true;
  362. }
  363. // Generic signed integer maximum.
  364. def G_SMAX : GenericInstruction {
  365. let OutOperandList = (outs type0:$dst);
  366. let InOperandList = (ins type0:$src1, type0:$src2);
  367. let hasSideEffects = false;
  368. let isCommutable = true;
  369. }
  370. // Generic unsigned integer minimum.
  371. def G_UMIN : GenericInstruction {
  372. let OutOperandList = (outs type0:$dst);
  373. let InOperandList = (ins type0:$src1, type0:$src2);
  374. let hasSideEffects = false;
  375. let isCommutable = true;
  376. }
  377. // Generic unsigned integer maximum.
  378. def G_UMAX : GenericInstruction {
  379. let OutOperandList = (outs type0:$dst);
  380. let InOperandList = (ins type0:$src1, type0:$src2);
  381. let hasSideEffects = false;
  382. let isCommutable = true;
  383. }
  384. // Generic integer absolute value.
  385. def G_ABS : GenericInstruction {
  386. let OutOperandList = (outs type0:$dst);
  387. let InOperandList = (ins type0:$src);
  388. let hasSideEffects = false;
  389. }
  390. //------------------------------------------------------------------------------
  391. // Overflow ops
  392. //------------------------------------------------------------------------------
  393. // Generic unsigned addition producing a carry flag.
  394. def G_UADDO : GenericInstruction {
  395. let OutOperandList = (outs type0:$dst, type1:$carry_out);
  396. let InOperandList = (ins type0:$src1, type0:$src2);
  397. let hasSideEffects = false;
  398. let isCommutable = true;
  399. }
  400. // Generic unsigned addition consuming and producing a carry flag.
  401. def G_UADDE : GenericInstruction {
  402. let OutOperandList = (outs type0:$dst, type1:$carry_out);
  403. let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
  404. let hasSideEffects = false;
  405. }
  406. // Generic signed addition producing a carry flag.
  407. def G_SADDO : GenericInstruction {
  408. let OutOperandList = (outs type0:$dst, type1:$carry_out);
  409. let InOperandList = (ins type0:$src1, type0:$src2);
  410. let hasSideEffects = false;
  411. let isCommutable = true;
  412. }
  413. // Generic signed addition consuming and producing a carry flag.
  414. def G_SADDE : GenericInstruction {
  415. let OutOperandList = (outs type0:$dst, type1:$carry_out);
  416. let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
  417. let hasSideEffects = false;
  418. }
  419. // Generic unsigned subtraction producing a carry flag.
  420. def G_USUBO : GenericInstruction {
  421. let OutOperandList = (outs type0:$dst, type1:$carry_out);
  422. let InOperandList = (ins type0:$src1, type0:$src2);
  423. let hasSideEffects = false;
  424. }
  425. // Generic unsigned subtraction consuming and producing a carry flag.
  426. def G_USUBE : GenericInstruction {
  427. let OutOperandList = (outs type0:$dst, type1:$carry_out);
  428. let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
  429. let hasSideEffects = false;
  430. }
  431. // Generic signed subtraction producing a carry flag.
  432. def G_SSUBO : GenericInstruction {
  433. let OutOperandList = (outs type0:$dst, type1:$carry_out);
  434. let InOperandList = (ins type0:$src1, type0:$src2);
  435. let hasSideEffects = false;
  436. }
  437. // Generic signed subtraction consuming and producing a carry flag.
  438. def G_SSUBE : GenericInstruction {
  439. let OutOperandList = (outs type0:$dst, type1:$carry_out);
  440. let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
  441. let hasSideEffects = false;
  442. }
  443. // Generic unsigned multiplication producing a carry flag.
  444. def G_UMULO : GenericInstruction {
  445. let OutOperandList = (outs type0:$dst, type1:$carry_out);
  446. let InOperandList = (ins type0:$src1, type0:$src2);
  447. let hasSideEffects = false;
  448. let isCommutable = true;
  449. }
  450. // Generic signed multiplication producing a carry flag.
  451. def G_SMULO : GenericInstruction {
  452. let OutOperandList = (outs type0:$dst, type1:$carry_out);
  453. let InOperandList = (ins type0:$src1, type0:$src2);
  454. let hasSideEffects = false;
  455. let isCommutable = true;
  456. }
  457. // Multiply two numbers at twice the incoming bit width (unsigned) and return
  458. // the high half of the result.
  459. def G_UMULH : GenericInstruction {
  460. let OutOperandList = (outs type0:$dst);
  461. let InOperandList = (ins type0:$src1, type0:$src2);
  462. let hasSideEffects = false;
  463. let isCommutable = true;
  464. }
  465. // Multiply two numbers at twice the incoming bit width (signed) and return
  466. // the high half of the result.
  467. def G_SMULH : GenericInstruction {
  468. let OutOperandList = (outs type0:$dst);
  469. let InOperandList = (ins type0:$src1, type0:$src2);
  470. let hasSideEffects = false;
  471. let isCommutable = true;
  472. }
  473. //------------------------------------------------------------------------------
  474. // Saturating ops
  475. //------------------------------------------------------------------------------
  476. // Generic saturating unsigned addition.
  477. def G_UADDSAT : GenericInstruction {
  478. let OutOperandList = (outs type0:$dst);
  479. let InOperandList = (ins type0:$src1, type0:$src2);
  480. let hasSideEffects = false;
  481. let isCommutable = true;
  482. }
  483. // Generic saturating signed addition.
  484. def G_SADDSAT : GenericInstruction {
  485. let OutOperandList = (outs type0:$dst);
  486. let InOperandList = (ins type0:$src1, type0:$src2);
  487. let hasSideEffects = false;
  488. let isCommutable = true;
  489. }
  490. // Generic saturating unsigned subtraction.
  491. def G_USUBSAT : GenericInstruction {
  492. let OutOperandList = (outs type0:$dst);
  493. let InOperandList = (ins type0:$src1, type0:$src2);
  494. let hasSideEffects = false;
  495. let isCommutable = false;
  496. }
  497. // Generic saturating signed subtraction.
  498. def G_SSUBSAT : GenericInstruction {
  499. let OutOperandList = (outs type0:$dst);
  500. let InOperandList = (ins type0:$src1, type0:$src2);
  501. let hasSideEffects = false;
  502. let isCommutable = false;
  503. }
  504. // Generic saturating unsigned left shift.
  505. def G_USHLSAT : GenericInstruction {
  506. let OutOperandList = (outs type0:$dst);
  507. let InOperandList = (ins type0:$src1, type1:$src2);
  508. let hasSideEffects = false;
  509. let isCommutable = false;
  510. }
  511. // Generic saturating signed left shift.
  512. def G_SSHLSAT : GenericInstruction {
  513. let OutOperandList = (outs type0:$dst);
  514. let InOperandList = (ins type0:$src1, type1:$src2);
  515. let hasSideEffects = false;
  516. let isCommutable = false;
  517. }
  518. /// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point
  519. /// multiplication on 2 integers with the same width and scale. SCALE
  520. /// represents the scale of both operands as fixed point numbers. This
  521. /// SCALE parameter must be a constant integer. A scale of zero is
  522. /// effectively performing multiplication on 2 integers.
  523. def G_SMULFIX : GenericInstruction {
  524. let OutOperandList = (outs type0:$dst);
  525. let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
  526. let hasSideEffects = false;
  527. let isCommutable = true;
  528. }
  529. def G_UMULFIX : GenericInstruction {
  530. let OutOperandList = (outs type0:$dst);
  531. let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
  532. let hasSideEffects = false;
  533. let isCommutable = true;
  534. }
  535. /// Same as the corresponding unsaturated fixed point instructions, but the
  536. /// result is clamped between the min and max values representable by the
  537. /// bits of the first 2 operands.
  538. def G_SMULFIXSAT : GenericInstruction {
  539. let OutOperandList = (outs type0:$dst);
  540. let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
  541. let hasSideEffects = false;
  542. let isCommutable = true;
  543. }
  544. def G_UMULFIXSAT : GenericInstruction {
  545. let OutOperandList = (outs type0:$dst);
  546. let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
  547. let hasSideEffects = false;
  548. let isCommutable = true;
  549. }
  550. /// RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on
  551. /// 2 integers with the same width and scale. SCALE represents the scale
  552. /// of both operands as fixed point numbers. This SCALE parameter must be a
  553. /// constant integer.
  554. def G_SDIVFIX : GenericInstruction {
  555. let OutOperandList = (outs type0:$dst);
  556. let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
  557. let hasSideEffects = false;
  558. let isCommutable = false;
  559. }
  560. def G_UDIVFIX : GenericInstruction {
  561. let OutOperandList = (outs type0:$dst);
  562. let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
  563. let hasSideEffects = false;
  564. let isCommutable = false;
  565. }
  566. /// Same as the corresponding unsaturated fixed point instructions,
  567. /// but the result is clamped between the min and max values
  568. /// representable by the bits of the first 2 operands.
  569. def G_SDIVFIXSAT : GenericInstruction {
  570. let OutOperandList = (outs type0:$dst);
  571. let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
  572. let hasSideEffects = false;
  573. let isCommutable = false;
  574. }
  575. def G_UDIVFIXSAT : GenericInstruction {
  576. let OutOperandList = (outs type0:$dst);
  577. let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
  578. let hasSideEffects = false;
  579. let isCommutable = false;
  580. }
  581. //------------------------------------------------------------------------------
  582. // Floating Point Unary Ops.
  583. //------------------------------------------------------------------------------
  584. def G_FNEG : GenericInstruction {
  585. let OutOperandList = (outs type0:$dst);
  586. let InOperandList = (ins type0:$src);
  587. let hasSideEffects = false;
  588. }
  589. def G_FPEXT : GenericInstruction {
  590. let OutOperandList = (outs type0:$dst);
  591. let InOperandList = (ins type1:$src);
  592. let hasSideEffects = false;
  593. }
  594. def G_FPTRUNC : GenericInstruction {
  595. let OutOperandList = (outs type0:$dst);
  596. let InOperandList = (ins type1:$src);
  597. let hasSideEffects = false;
  598. }
  599. def G_FPTOSI : GenericInstruction {
  600. let OutOperandList = (outs type0:$dst);
  601. let InOperandList = (ins type1:$src);
  602. let hasSideEffects = false;
  603. }
  604. def G_FPTOUI : GenericInstruction {
  605. let OutOperandList = (outs type0:$dst);
  606. let InOperandList = (ins type1:$src);
  607. let hasSideEffects = false;
  608. }
  609. def G_SITOFP : GenericInstruction {
  610. let OutOperandList = (outs type0:$dst);
  611. let InOperandList = (ins type1:$src);
  612. let hasSideEffects = false;
  613. }
  614. def G_UITOFP : GenericInstruction {
  615. let OutOperandList = (outs type0:$dst);
  616. let InOperandList = (ins type1:$src);
  617. let hasSideEffects = false;
  618. }
  619. def G_FABS : GenericInstruction {
  620. let OutOperandList = (outs type0:$dst);
  621. let InOperandList = (ins type0:$src);
  622. let hasSideEffects = false;
  623. }
  624. def G_FCOPYSIGN : GenericInstruction {
  625. let OutOperandList = (outs type0:$dst);
  626. let InOperandList = (ins type0:$src0, type1:$src1);
  627. let hasSideEffects = false;
  628. }
  629. def G_FCANONICALIZE : GenericInstruction {
  630. let OutOperandList = (outs type0:$dst);
  631. let InOperandList = (ins type0:$src);
  632. let hasSideEffects = false;
  633. }
  634. // FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
  635. // values.
  636. //
  637. // In the case where a single input is a NaN (either signaling or quiet),
  638. // the non-NaN input is returned.
  639. //
  640. // The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
  641. def G_FMINNUM : GenericInstruction {
  642. let OutOperandList = (outs type0:$dst);
  643. let InOperandList = (ins type0:$src1, type0:$src2);
  644. let hasSideEffects = false;
  645. let isCommutable = true;
  646. }
  647. def G_FMAXNUM : GenericInstruction {
  648. let OutOperandList = (outs type0:$dst);
  649. let InOperandList = (ins type0:$src1, type0:$src2);
  650. let hasSideEffects = false;
  651. let isCommutable = true;
  652. }
  653. // FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on
  654. // two values, following the IEEE-754 2008 definition. This differs from
  655. // FMINNUM/FMAXNUM in the handling of signaling NaNs. If one input is a
  656. // signaling NaN, returns a quiet NaN.
  657. def G_FMINNUM_IEEE : GenericInstruction {
  658. let OutOperandList = (outs type0:$dst);
  659. let InOperandList = (ins type0:$src1, type0:$src2);
  660. let hasSideEffects = false;
  661. let isCommutable = true;
  662. }
  663. def G_FMAXNUM_IEEE : GenericInstruction {
  664. let OutOperandList = (outs type0:$dst);
  665. let InOperandList = (ins type0:$src1, type0:$src2);
  666. let hasSideEffects = false;
  667. let isCommutable = true;
  668. }
  669. // FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0
  670. // as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008
  671. // semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2018 draft semantics.
  672. def G_FMINIMUM : GenericInstruction {
  673. let OutOperandList = (outs type0:$dst);
  674. let InOperandList = (ins type0:$src1, type0:$src2);
  675. let hasSideEffects = false;
  676. let isCommutable = true;
  677. }
  678. def G_FMAXIMUM : GenericInstruction {
  679. let OutOperandList = (outs type0:$dst);
  680. let InOperandList = (ins type0:$src1, type0:$src2);
  681. let hasSideEffects = false;
  682. let isCommutable = true;
  683. }
  684. //------------------------------------------------------------------------------
  685. // Floating Point Binary ops.
  686. //------------------------------------------------------------------------------
  687. // Generic FP addition.
  688. def G_FADD : GenericInstruction {
  689. let OutOperandList = (outs type0:$dst);
  690. let InOperandList = (ins type0:$src1, type0:$src2);
  691. let hasSideEffects = false;
  692. let isCommutable = true;
  693. }
  694. // Generic FP subtraction.
  695. def G_FSUB : GenericInstruction {
  696. let OutOperandList = (outs type0:$dst);
  697. let InOperandList = (ins type0:$src1, type0:$src2);
  698. let hasSideEffects = false;
  699. let isCommutable = false;
  700. }
  701. // Generic FP multiplication.
  702. def G_FMUL : GenericInstruction {
  703. let OutOperandList = (outs type0:$dst);
  704. let InOperandList = (ins type0:$src1, type0:$src2);
  705. let hasSideEffects = false;
  706. let isCommutable = true;
  707. }
  708. // Generic fused multiply-add instruction.
  709. // Behaves like llvm fma intrinsic ie src1 * src2 + src3
  710. def G_FMA : GenericInstruction {
  711. let OutOperandList = (outs type0:$dst);
  712. let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
  713. let hasSideEffects = false;
  714. let isCommutable = false;
  715. }
  716. /// Generic FP multiply and add. Perform a * b + c, while getting the
  717. /// same result as the separately rounded operations, unlike G_FMA.
  718. def G_FMAD : GenericInstruction {
  719. let OutOperandList = (outs type0:$dst);
  720. let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
  721. let hasSideEffects = false;
  722. let isCommutable = false;
  723. }
  724. // Generic FP division.
  725. def G_FDIV : GenericInstruction {
  726. let OutOperandList = (outs type0:$dst);
  727. let InOperandList = (ins type0:$src1, type0:$src2);
  728. let hasSideEffects = false;
  729. }
  730. // Generic FP remainder.
  731. def G_FREM : GenericInstruction {
  732. let OutOperandList = (outs type0:$dst);
  733. let InOperandList = (ins type0:$src1, type0:$src2);
  734. let hasSideEffects = false;
  735. }
  736. // Floating point exponentiation.
  737. def G_FPOW : GenericInstruction {
  738. let OutOperandList = (outs type0:$dst);
  739. let InOperandList = (ins type0:$src1, type0:$src2);
  740. let hasSideEffects = false;
  741. }
  742. // Floating point exponentiation, with an integer power.
  743. def G_FPOWI : GenericInstruction {
  744. let OutOperandList = (outs type0:$dst);
  745. let InOperandList = (ins type0:$src0, type1:$src1);
  746. let hasSideEffects = false;
  747. }
  748. // Floating point base-e exponential of a value.
  749. def G_FEXP : GenericInstruction {
  750. let OutOperandList = (outs type0:$dst);
  751. let InOperandList = (ins type0:$src1);
  752. let hasSideEffects = false;
  753. }
  754. // Floating point base-2 exponential of a value.
  755. def G_FEXP2 : GenericInstruction {
  756. let OutOperandList = (outs type0:$dst);
  757. let InOperandList = (ins type0:$src1);
  758. let hasSideEffects = false;
  759. }
  760. // Floating point base-e logarithm of a value.
  761. def G_FLOG : GenericInstruction {
  762. let OutOperandList = (outs type0:$dst);
  763. let InOperandList = (ins type0:$src1);
  764. let hasSideEffects = false;
  765. }
  766. // Floating point base-2 logarithm of a value.
  767. def G_FLOG2 : GenericInstruction {
  768. let OutOperandList = (outs type0:$dst);
  769. let InOperandList = (ins type0:$src1);
  770. let hasSideEffects = false;
  771. }
  772. // Floating point base-10 logarithm of a value.
  773. def G_FLOG10 : GenericInstruction {
  774. let OutOperandList = (outs type0:$dst);
  775. let InOperandList = (ins type0:$src1);
  776. let hasSideEffects = false;
  777. }
  778. // Floating point ceiling of a value.
  779. def G_FCEIL : GenericInstruction {
  780. let OutOperandList = (outs type0:$dst);
  781. let InOperandList = (ins type0:$src1);
  782. let hasSideEffects = false;
  783. }
  784. // Floating point cosine of a value.
  785. def G_FCOS : GenericInstruction {
  786. let OutOperandList = (outs type0:$dst);
  787. let InOperandList = (ins type0:$src1);
  788. let hasSideEffects = false;
  789. }
  790. // Floating point sine of a value.
  791. def G_FSIN : GenericInstruction {
  792. let OutOperandList = (outs type0:$dst);
  793. let InOperandList = (ins type0:$src1);
  794. let hasSideEffects = false;
  795. }
  796. // Floating point square root of a value.
  797. // This returns NaN for negative nonzero values.
  798. // NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's
  799. // libm-conformant.
  800. def G_FSQRT : GenericInstruction {
  801. let OutOperandList = (outs type0:$dst);
  802. let InOperandList = (ins type0:$src1);
  803. let hasSideEffects = false;
  804. }
  805. // Floating point floor of a value.
  806. def G_FFLOOR : GenericInstruction {
  807. let OutOperandList = (outs type0:$dst);
  808. let InOperandList = (ins type0:$src1);
  809. let hasSideEffects = false;
  810. }
  811. // Floating point round to next integer.
  812. def G_FRINT : GenericInstruction {
  813. let OutOperandList = (outs type0:$dst);
  814. let InOperandList = (ins type0:$src1);
  815. let hasSideEffects = false;
  816. }
  817. // Floating point round to the nearest integer.
  818. def G_FNEARBYINT : GenericInstruction {
  819. let OutOperandList = (outs type0:$dst);
  820. let InOperandList = (ins type0:$src1);
  821. let hasSideEffects = false;
  822. }
  823. //------------------------------------------------------------------------------
  824. // Opcodes for LLVM Intrinsics
  825. //------------------------------------------------------------------------------
  826. def G_INTRINSIC_TRUNC : GenericInstruction {
  827. let OutOperandList = (outs type0:$dst);
  828. let InOperandList = (ins type0:$src1);
  829. let hasSideEffects = false;
  830. }
  831. def G_INTRINSIC_ROUND : GenericInstruction {
  832. let OutOperandList = (outs type0:$dst);
  833. let InOperandList = (ins type0:$src1);
  834. let hasSideEffects = false;
  835. }
  836. def G_INTRINSIC_LRINT : GenericInstruction {
  837. let OutOperandList = (outs type0:$dst);
  838. let InOperandList = (ins type1:$src);
  839. let hasSideEffects = false;
  840. }
  841. def G_INTRINSIC_ROUNDEVEN : GenericInstruction {
  842. let OutOperandList = (outs type0:$dst);
  843. let InOperandList = (ins type0:$src1);
  844. let hasSideEffects = false;
  845. }
  846. def G_READCYCLECOUNTER : GenericInstruction {
  847. let OutOperandList = (outs type0:$dst);
  848. let InOperandList = (ins);
  849. let hasSideEffects = true;
  850. }
  851. //------------------------------------------------------------------------------
  852. // Memory ops
  853. //------------------------------------------------------------------------------
  854. // Generic load. Expects a MachineMemOperand in addition to explicit
  855. // operands. If the result size is larger than the memory size, the
  856. // high bits are undefined. If the result is a vector type and larger
  857. // than the memory size, the high elements are undefined (i.e. this is
  858. // not a per-element, vector anyextload)
  859. def G_LOAD : GenericInstruction {
  860. let OutOperandList = (outs type0:$dst);
  861. let InOperandList = (ins ptype1:$addr);
  862. let hasSideEffects = false;
  863. let mayLoad = true;
  864. }
  865. // Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
  866. def G_SEXTLOAD : GenericInstruction {
  867. let OutOperandList = (outs type0:$dst);
  868. let InOperandList = (ins ptype1:$addr);
  869. let hasSideEffects = false;
  870. let mayLoad = true;
  871. }
  872. // Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
  873. def G_ZEXTLOAD : GenericInstruction {
  874. let OutOperandList = (outs type0:$dst);
  875. let InOperandList = (ins ptype1:$addr);
  876. let hasSideEffects = false;
  877. let mayLoad = true;
  878. }
  879. // Generic indexed load. Combines a GEP with a load. $newaddr is set to $base + $offset.
  880. // If $am is 0 (post-indexed), then the value is loaded from $base; if $am is 1 (pre-indexed)
  881. // then the value is loaded from $newaddr.
  882. def G_INDEXED_LOAD : GenericInstruction {
  883. let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
  884. let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
  885. let hasSideEffects = false;
  886. let mayLoad = true;
  887. }
  888. // Same as G_INDEXED_LOAD except that the load performed is sign-extending, as with G_SEXTLOAD.
  889. def G_INDEXED_SEXTLOAD : GenericInstruction {
  890. let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
  891. let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
  892. let hasSideEffects = false;
  893. let mayLoad = true;
  894. }
  895. // Same as G_INDEXED_LOAD except that the load performed is zero-extending, as with G_ZEXTLOAD.
  896. def G_INDEXED_ZEXTLOAD : GenericInstruction {
  897. let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
  898. let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
  899. let hasSideEffects = false;
  900. let mayLoad = true;
  901. }
  902. // Generic store. Expects a MachineMemOperand in addition to explicit operands.
  903. def G_STORE : GenericInstruction {
  904. let OutOperandList = (outs);
  905. let InOperandList = (ins type0:$src, ptype1:$addr);
  906. let hasSideEffects = false;
  907. let mayStore = true;
  908. }
  909. // Combines a store with a GEP. See description of G_INDEXED_LOAD for indexing behaviour.
  910. def G_INDEXED_STORE : GenericInstruction {
  911. let OutOperandList = (outs ptype0:$newaddr);
  912. let InOperandList = (ins type1:$src, ptype0:$base, ptype2:$offset,
  913. unknown:$am);
  914. let hasSideEffects = false;
  915. let mayStore = true;
  916. }
  917. // Generic atomic cmpxchg with internal success check. Expects a
  918. // MachineMemOperand in addition to explicit operands.
  919. def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
  920. let OutOperandList = (outs type0:$oldval, type1:$success);
  921. let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
  922. let hasSideEffects = false;
  923. let mayLoad = true;
  924. let mayStore = true;
  925. }
  926. // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
  927. // operands.
  928. def G_ATOMIC_CMPXCHG : GenericInstruction {
  929. let OutOperandList = (outs type0:$oldval);
  930. let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
  931. let hasSideEffects = false;
  932. let mayLoad = true;
  933. let mayStore = true;
  934. }
  935. // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
  936. // operands.
  937. class G_ATOMICRMW_OP : GenericInstruction {
  938. let OutOperandList = (outs type0:$oldval);
  939. let InOperandList = (ins ptype1:$addr, type0:$val);
  940. let hasSideEffects = false;
  941. let mayLoad = true;
  942. let mayStore = true;
  943. }
  944. def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
  945. def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
  946. def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
  947. def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
  948. def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
  949. def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
  950. def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
  951. def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
  952. def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
  953. def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
  954. def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
  955. def G_ATOMICRMW_FADD : G_ATOMICRMW_OP;
  956. def G_ATOMICRMW_FSUB : G_ATOMICRMW_OP;
  957. def G_FENCE : GenericInstruction {
  958. let OutOperandList = (outs);
  959. let InOperandList = (ins i32imm:$ordering, i32imm:$scope);
  960. let hasSideEffects = true;
  961. }
  962. //------------------------------------------------------------------------------
  963. // Variadic ops
  964. //------------------------------------------------------------------------------
  965. // Extract a register of the specified size, starting from the block given by
  966. // index. This will almost certainly be mapped to sub-register COPYs after
  967. // register banks have been selected.
  968. def G_EXTRACT : GenericInstruction {
  969. let OutOperandList = (outs type0:$res);
  970. let InOperandList = (ins type1:$src, untyped_imm_0:$offset);
  971. let hasSideEffects = false;
  972. }
  973. // Extract multiple registers specified size, starting from blocks given by
  974. // indexes. This will almost certainly be mapped to sub-register COPYs after
  975. // register banks have been selected.
  976. // The output operands are always ordered from lowest bits to highest:
  977. // %bits_0_7:(s8), %bits_8_15:(s8),
  978. // %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
  979. def G_UNMERGE_VALUES : GenericInstruction {
  980. let OutOperandList = (outs type0:$dst0, variable_ops);
  981. let InOperandList = (ins type1:$src);
  982. let hasSideEffects = false;
  983. }
  984. // Insert a smaller register into a larger one at the specified bit-index.
  985. def G_INSERT : GenericInstruction {
  986. let OutOperandList = (outs type0:$dst);
  987. let InOperandList = (ins type0:$src, type1:$op, untyped_imm_0:$offset);
  988. let hasSideEffects = false;
  989. }
  990. // Concatenate multiple registers of the same size into a wider register.
  991. // The input operands are always ordered from lowest bits to highest:
  992. // %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
  993. // %bits_16_23:(s8), %bits_24_31:(s8)
  994. def G_MERGE_VALUES : GenericInstruction {
  995. let OutOperandList = (outs type0:$dst);
  996. let InOperandList = (ins type1:$src0, variable_ops);
  997. let hasSideEffects = false;
  998. }
  999. /// Create a vector from multiple scalar registers. No implicit
  1000. /// conversion is performed (i.e. the result element type must be the
  1001. /// same as all source operands)
  1002. def G_BUILD_VECTOR : GenericInstruction {
  1003. let OutOperandList = (outs type0:$dst);
  1004. let InOperandList = (ins type1:$src0, variable_ops);
  1005. let hasSideEffects = false;
  1006. }
  1007. /// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the
  1008. /// destination vector elt type.
  1009. def G_BUILD_VECTOR_TRUNC : GenericInstruction {
  1010. let OutOperandList = (outs type0:$dst);
  1011. let InOperandList = (ins type1:$src0, variable_ops);
  1012. let hasSideEffects = false;
  1013. }
  1014. /// Create a vector by concatenating vectors together.
  1015. def G_CONCAT_VECTORS : GenericInstruction {
  1016. let OutOperandList = (outs type0:$dst);
  1017. let InOperandList = (ins type1:$src0, variable_ops);
  1018. let hasSideEffects = false;
  1019. }
  1020. // Intrinsic without side effects.
  1021. def G_INTRINSIC : GenericInstruction {
  1022. let OutOperandList = (outs);
  1023. let InOperandList = (ins unknown:$intrin, variable_ops);
  1024. let hasSideEffects = false;
  1025. // Conservatively assume this is convergent. If there turnes out to
  1026. // be a need, there should be separate convergent intrinsic opcodes.
  1027. let isConvergent = 1;
  1028. }
  1029. // Intrinsic with side effects.
  1030. def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
  1031. let OutOperandList = (outs);
  1032. let InOperandList = (ins unknown:$intrin, variable_ops);
  1033. let hasSideEffects = true;
  1034. let mayLoad = true;
  1035. let mayStore = true;
  1036. // Conservatively assume this is convergent. If there turnes out to
  1037. // be a need, there should be separate convergent intrinsic opcodes.
  1038. let isConvergent = true;
  1039. }
  1040. //------------------------------------------------------------------------------
  1041. // Branches.
  1042. //------------------------------------------------------------------------------
  1043. // Generic unconditional branch.
  1044. def G_BR : GenericInstruction {
  1045. let OutOperandList = (outs);
  1046. let InOperandList = (ins unknown:$src1);
  1047. let hasSideEffects = false;
  1048. let isBranch = true;
  1049. let isTerminator = true;
  1050. let isBarrier = true;
  1051. }
  1052. // Generic conditional branch.
  1053. def G_BRCOND : GenericInstruction {
  1054. let OutOperandList = (outs);
  1055. let InOperandList = (ins type0:$tst, unknown:$truebb);
  1056. let hasSideEffects = false;
  1057. let isBranch = true;
  1058. let isTerminator = true;
  1059. }
  1060. // Generic indirect branch.
  1061. def G_BRINDIRECT : GenericInstruction {
  1062. let OutOperandList = (outs);
  1063. let InOperandList = (ins type0:$src1);
  1064. let hasSideEffects = false;
  1065. let isBranch = true;
  1066. let isTerminator = true;
  1067. let isBarrier = true;
  1068. let isIndirectBranch = true;
  1069. }
  1070. // Generic branch to jump table entry
  1071. def G_BRJT : GenericInstruction {
  1072. let OutOperandList = (outs);
  1073. let InOperandList = (ins ptype0:$tbl, unknown:$jti, type1:$idx);
  1074. let hasSideEffects = false;
  1075. let isBranch = true;
  1076. let isTerminator = true;
  1077. let isBarrier = true;
  1078. let isIndirectBranch = true;
  1079. }
  1080. def G_READ_REGISTER : GenericInstruction {
  1081. let OutOperandList = (outs type0:$dst);
  1082. let InOperandList = (ins unknown:$register);
  1083. let hasSideEffects = true;
  1084. // Assume convergent. It's probably not worth the effort of somehow
  1085. // modeling convergent and nonconvergent register accesses.
  1086. let isConvergent = true;
  1087. }
  1088. def G_WRITE_REGISTER : GenericInstruction {
  1089. let OutOperandList = (outs);
  1090. let InOperandList = (ins unknown:$register, type0:$value);
  1091. let hasSideEffects = true;
  1092. // Assume convergent. It's probably not worth the effort of somehow
  1093. // modeling convergent and nonconvergent register accesses.
  1094. let isConvergent = true;
  1095. }
  1096. //------------------------------------------------------------------------------
  1097. // Vector ops
  1098. //------------------------------------------------------------------------------
  1099. // Generic insertelement.
  1100. def G_INSERT_VECTOR_ELT : GenericInstruction {
  1101. let OutOperandList = (outs type0:$dst);
  1102. let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
  1103. let hasSideEffects = false;
  1104. }
  1105. // Generic extractelement.
  1106. def G_EXTRACT_VECTOR_ELT : GenericInstruction {
  1107. let OutOperandList = (outs type0:$dst);
  1108. let InOperandList = (ins type1:$src, type2:$idx);
  1109. let hasSideEffects = false;
  1110. }
  1111. // Generic shufflevector.
  1112. //
  1113. // The mask operand should be an IR Constant which exactly matches the
  1114. // corresponding mask for the IR shufflevector instruction.
  1115. def G_SHUFFLE_VECTOR: GenericInstruction {
  1116. let OutOperandList = (outs type0:$dst);
  1117. let InOperandList = (ins type1:$v1, type1:$v2, unknown:$mask);
  1118. let hasSideEffects = false;
  1119. }
  1120. //------------------------------------------------------------------------------
  1121. // Vector reductions
  1122. //------------------------------------------------------------------------------
  1123. class VectorReduction : GenericInstruction {
  1124. let OutOperandList = (outs type0:$dst);
  1125. let InOperandList = (ins type1:$v);
  1126. let hasSideEffects = false;
  1127. }
  1128. def G_VECREDUCE_SEQ_FADD : GenericInstruction {
  1129. let OutOperandList = (outs type0:$dst);
  1130. let InOperandList = (ins type1:$acc, type2:$v);
  1131. let hasSideEffects = false;
  1132. }
  1133. def G_VECREDUCE_SEQ_FMUL : GenericInstruction {
  1134. let OutOperandList = (outs type0:$dst);
  1135. let InOperandList = (ins type1:$acc, type2:$v);
  1136. let hasSideEffects = false;
  1137. }
  1138. def G_VECREDUCE_FADD : VectorReduction;
  1139. def G_VECREDUCE_FMUL : VectorReduction;
  1140. def G_VECREDUCE_FMAX : VectorReduction;
  1141. def G_VECREDUCE_FMIN : VectorReduction;
  1142. def G_VECREDUCE_ADD : VectorReduction;
  1143. def G_VECREDUCE_MUL : VectorReduction;
  1144. def G_VECREDUCE_AND : VectorReduction;
  1145. def G_VECREDUCE_OR : VectorReduction;
  1146. def G_VECREDUCE_XOR : VectorReduction;
  1147. def G_VECREDUCE_SMAX : VectorReduction;
  1148. def G_VECREDUCE_SMIN : VectorReduction;
  1149. def G_VECREDUCE_UMAX : VectorReduction;
  1150. def G_VECREDUCE_UMIN : VectorReduction;
  1151. //------------------------------------------------------------------------------
  1152. // Constrained floating point ops
  1153. //------------------------------------------------------------------------------
  1154. def G_STRICT_FADD : ConstrainedIntruction<G_FADD>;
  1155. def G_STRICT_FSUB : ConstrainedIntruction<G_FSUB>;
  1156. def G_STRICT_FMUL : ConstrainedIntruction<G_FMUL>;
  1157. def G_STRICT_FDIV : ConstrainedIntruction<G_FDIV>;
  1158. def G_STRICT_FREM : ConstrainedIntruction<G_FREM>;
  1159. def G_STRICT_FMA : ConstrainedIntruction<G_FMA>;
  1160. def G_STRICT_FSQRT : ConstrainedIntruction<G_FSQRT>;
  1161. //------------------------------------------------------------------------------
  1162. // Memory intrinsics
  1163. //------------------------------------------------------------------------------
  1164. def G_MEMCPY : GenericInstruction {
  1165. let OutOperandList = (outs);
  1166. let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
  1167. let hasSideEffects = false;
  1168. let mayLoad = true;
  1169. let mayStore = true;
  1170. }
  1171. def G_MEMMOVE : GenericInstruction {
  1172. let OutOperandList = (outs);
  1173. let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
  1174. let hasSideEffects = false;
  1175. let mayLoad = true;
  1176. let mayStore = true;
  1177. }
  1178. def G_MEMSET : GenericInstruction {
  1179. let OutOperandList = (outs);
  1180. let InOperandList = (ins ptype0:$dst_addr, type1:$value, type2:$size, untyped_imm_0:$tailcall);
  1181. let hasSideEffects = false;
  1182. let mayStore = true;
  1183. }
  1184. def G_BZERO : GenericInstruction {
  1185. let OutOperandList = (outs);
  1186. let InOperandList = (ins ptype0:$dst_addr, type1:$size, untyped_imm_0:$tailcall);
  1187. let hasSideEffects = false;
  1188. let mayStore = true;
  1189. }
  1190. //------------------------------------------------------------------------------
  1191. // Bitfield extraction.
  1192. //------------------------------------------------------------------------------
  1193. // Generic signed bitfield extraction.
  1194. def G_SBFX : GenericInstruction {
  1195. let OutOperandList = (outs type0:$dst);
  1196. let InOperandList = (ins type0:$src, type1:$lsb, type1:$width);
  1197. let hasSideEffects = false;
  1198. }
  1199. // Generic unsigned bitfield extraction.
  1200. def G_UBFX : GenericInstruction {
  1201. let OutOperandList = (outs type0:$dst);
  1202. let InOperandList = (ins type0:$src, type1:$lsb, type1:$width);
  1203. let hasSideEffects = false;
  1204. }
  1205. //------------------------------------------------------------------------------
  1206. // Optimization hints
  1207. //------------------------------------------------------------------------------
  1208. // Asserts that an operation has already been zero-extended from a specific
  1209. // type.
  1210. def G_ASSERT_ZEXT : GenericInstruction {
  1211. let OutOperandList = (outs type0:$dst);
  1212. let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
  1213. let hasSideEffects = false;
  1214. }
  1215. // Asserts that an operation has already been sign-extended from a specific
  1216. // type.
  1217. def G_ASSERT_SEXT : GenericInstruction {
  1218. let OutOperandList = (outs type0:$dst);
  1219. let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
  1220. let hasSideEffects = false;
  1221. }