/3rd_party/llvm/lib/Target/CellSPU/SPUOperands.td

https://code.google.com/p/softart/ · Unknown · 664 lines · 540 code · 124 blank · 0 comment · 0 complexity · b17aae02a9d2aff1bf9e794c6ba3c9f9 MD5 · raw file

  1. //===-- SPUOperands.td - Cell SPU Instruction Operands -----*- tablegen -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. // Cell SPU Instruction Operands:
  10. //===----------------------------------------------------------------------===//
  11. // TO_IMM32 - Convert an i8/i16 to i32.
  12. def TO_IMM32 : SDNodeXForm<imm, [{
  13. return getI32Imm(N->getZExtValue());
  14. }]>;
  15. // TO_IMM16 - Convert an i8/i32 to i16.
  16. def TO_IMM16 : SDNodeXForm<imm, [{
  17. return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i16);
  18. }]>;
  19. def LO16 : SDNodeXForm<imm, [{
  20. unsigned val = N->getZExtValue();
  21. // Transformation function: get the low 16 bits.
  22. return getI32Imm(val & 0xffff);
  23. }]>;
  24. def LO16_vec : SDNodeXForm<scalar_to_vector, [{
  25. SDValue OpVal(0, 0);
  26. // Transformation function: get the low 16 bit immediate from a build_vector
  27. // node.
  28. assert(N->getOpcode() == ISD::BUILD_VECTOR
  29. && "LO16_vec got something other than a BUILD_VECTOR");
  30. // Get first constant operand...
  31. for (unsigned i = 0, e = N->getNumOperands();
  32. OpVal.getNode() == 0 && i != e; ++i) {
  33. if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
  34. if (OpVal.getNode() == 0)
  35. OpVal = N->getOperand(i);
  36. }
  37. assert(OpVal.getNode() != 0 && "LO16_vec did not locate a <defined> node");
  38. ConstantSDNode *CN = cast<ConstantSDNode>(OpVal);
  39. return getI32Imm((unsigned)CN->getZExtValue() & 0xffff);
  40. }]>;
  41. // Transform an immediate, returning the high 16 bits shifted down:
  42. def HI16 : SDNodeXForm<imm, [{
  43. return getI32Imm((unsigned)N->getZExtValue() >> 16);
  44. }]>;
  45. // Transformation function: shift the high 16 bit immediate from a build_vector
  46. // node into the low 16 bits, and return a 16-bit constant.
  47. def HI16_vec : SDNodeXForm<scalar_to_vector, [{
  48. SDValue OpVal(0, 0);
  49. assert(N->getOpcode() == ISD::BUILD_VECTOR
  50. && "HI16_vec got something other than a BUILD_VECTOR");
  51. // Get first constant operand...
  52. for (unsigned i = 0, e = N->getNumOperands();
  53. OpVal.getNode() == 0 && i != e; ++i) {
  54. if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
  55. if (OpVal.getNode() == 0)
  56. OpVal = N->getOperand(i);
  57. }
  58. assert(OpVal.getNode() != 0 && "HI16_vec did not locate a <defined> node");
  59. ConstantSDNode *CN = cast<ConstantSDNode>(OpVal);
  60. return getI32Imm((unsigned)CN->getZExtValue() >> 16);
  61. }]>;
  62. // simm7 predicate - True if the immediate fits in an 7-bit signed
  63. // field.
  64. def simm7: PatLeaf<(imm), [{
  65. int sextVal = int(N->getSExtValue());
  66. return (sextVal >= -64 && sextVal <= 63);
  67. }]>;
  68. // uimm7 predicate - True if the immediate fits in an 7-bit unsigned
  69. // field.
  70. def uimm7: PatLeaf<(imm), [{
  71. return (N->getZExtValue() <= 0x7f);
  72. }]>;
  73. // immSExt8 predicate - True if the immediate fits in an 8-bit sign extended
  74. // field.
  75. def immSExt8 : PatLeaf<(imm), [{
  76. int Value = int(N->getSExtValue());
  77. return (Value >= -(1 << 8) && Value <= (1 << 8) - 1);
  78. }]>;
  79. // immU8: immediate, unsigned 8-bit quantity
  80. def immU8 : PatLeaf<(imm), [{
  81. return (N->getZExtValue() <= 0xff);
  82. }]>;
  83. // i32ImmSExt10 predicate - True if the i32 immediate fits in a 10-bit sign
  84. // extended field. Used by RI10Form instructions like 'ldq'.
  85. def i32ImmSExt10 : PatLeaf<(imm), [{
  86. return isI32IntS10Immediate(N);
  87. }]>;
  88. // i32ImmUns10 predicate - True if the i32 immediate fits in a 10-bit unsigned
  89. // field. Used by RI10Form instructions like 'ldq'.
  90. def i32ImmUns10 : PatLeaf<(imm), [{
  91. return isI32IntU10Immediate(N);
  92. }]>;
  93. // i16ImmSExt10 predicate - True if the i16 immediate fits in a 10-bit sign
  94. // extended field. Used by RI10Form instructions like 'ldq'.
  95. def i16ImmSExt10 : PatLeaf<(imm), [{
  96. return isI16IntS10Immediate(N);
  97. }]>;
  98. // i16ImmUns10 predicate - True if the i16 immediate fits into a 10-bit unsigned
  99. // value. Used by RI10Form instructions.
  100. def i16ImmUns10 : PatLeaf<(imm), [{
  101. return isI16IntU10Immediate(N);
  102. }]>;
  103. def immSExt16 : PatLeaf<(imm), [{
  104. // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended
  105. // field.
  106. short Ignored;
  107. return isIntS16Immediate(N, Ignored);
  108. }]>;
  109. def immZExt16 : PatLeaf<(imm), [{
  110. // immZExt16 predicate - True if the immediate fits in a 16-bit zero extended
  111. // field.
  112. return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
  113. }], LO16>;
  114. def immU16 : PatLeaf<(imm), [{
  115. // immU16 predicate- True if the immediate fits into a 16-bit unsigned field.
  116. return (uint64_t)N->getZExtValue() == (N->getZExtValue() & 0xffff);
  117. }]>;
  118. def imm18 : PatLeaf<(imm), [{
  119. // imm18 predicate: True if the immediate fits into an 18-bit unsigned field.
  120. int Value = (int) N->getZExtValue();
  121. return isUInt<18>(Value);
  122. }]>;
  123. def lo16 : PatLeaf<(imm), [{
  124. // lo16 predicate - returns true if the immediate has all zeros in the
  125. // low order bits and is a 32-bit constant:
  126. if (N->getValueType(0) == MVT::i32) {
  127. uint32_t val = N->getZExtValue();
  128. return ((val & 0x0000ffff) == val);
  129. }
  130. return false;
  131. }], LO16>;
  132. def hi16 : PatLeaf<(imm), [{
  133. // hi16 predicate - returns true if the immediate has all zeros in the
  134. // low order bits and is a 32-bit constant:
  135. if (N->getValueType(0) == MVT::i32) {
  136. uint32_t val = uint32_t(N->getZExtValue());
  137. return ((val & 0xffff0000) == val);
  138. } else if (N->getValueType(0) == MVT::i64) {
  139. uint64_t val = N->getZExtValue();
  140. return ((val & 0xffff0000ULL) == val);
  141. }
  142. return false;
  143. }], HI16>;
  144. def bitshift : PatLeaf<(imm), [{
  145. // bitshift predicate - returns true if 0 < imm <= 7 for SHLQBII
  146. // (shift left quadword by bits immediate)
  147. int64_t Val = N->getZExtValue();
  148. return (Val > 0 && Val <= 7);
  149. }]>;
  150. //===----------------------------------------------------------------------===//
  151. // Floating point operands:
  152. //===----------------------------------------------------------------------===//
  153. // Transform a float, returning the high 16 bits shifted down, as if
  154. // the float was really an unsigned integer:
  155. def HI16_f32 : SDNodeXForm<fpimm, [{
  156. float fval = N->getValueAPF().convertToFloat();
  157. return getI32Imm(FloatToBits(fval) >> 16);
  158. }]>;
  159. // Transformation function on floats: get the low 16 bits as if the float was
  160. // an unsigned integer.
  161. def LO16_f32 : SDNodeXForm<fpimm, [{
  162. float fval = N->getValueAPF().convertToFloat();
  163. return getI32Imm(FloatToBits(fval) & 0xffff);
  164. }]>;
  165. def FPimm_sext16 : SDNodeXForm<fpimm, [{
  166. float fval = N->getValueAPF().convertToFloat();
  167. return getI32Imm((int) ((FloatToBits(fval) << 16) >> 16));
  168. }]>;
  169. def FPimm_u18 : SDNodeXForm<fpimm, [{
  170. float fval = N->getValueAPF().convertToFloat();
  171. return getI32Imm(FloatToBits(fval) & ((1 << 18) - 1));
  172. }]>;
  173. def fpimmSExt16 : PatLeaf<(fpimm), [{
  174. short Ignored;
  175. return isFPS16Immediate(N, Ignored);
  176. }], FPimm_sext16>;
  177. // Does the SFP constant only have upp 16 bits set?
  178. def hi16_f32 : PatLeaf<(fpimm), [{
  179. if (N->getValueType(0) == MVT::f32) {
  180. uint32_t val = FloatToBits(N->getValueAPF().convertToFloat());
  181. return ((val & 0xffff0000) == val);
  182. }
  183. return false;
  184. }], HI16_f32>;
  185. // Does the SFP constant fit into 18 bits?
  186. def fpimm18 : PatLeaf<(fpimm), [{
  187. if (N->getValueType(0) == MVT::f32) {
  188. uint32_t Value = FloatToBits(N->getValueAPF().convertToFloat());
  189. return isUInt<18>(Value);
  190. }
  191. return false;
  192. }], FPimm_u18>;
  193. //===----------------------------------------------------------------------===//
  194. // 64-bit operands (TODO):
  195. //===----------------------------------------------------------------------===//
  196. //===----------------------------------------------------------------------===//
  197. // build_vector operands:
  198. //===----------------------------------------------------------------------===//
  199. // v16i8SExt8Imm_xform function: convert build_vector to 8-bit sign extended
  200. // immediate constant load for v16i8 vectors. N.B.: The incoming constant has
  201. // to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a).
  202. def v16i8SExt8Imm_xform: SDNodeXForm<build_vector, [{
  203. return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8);
  204. }]>;
  205. // v16i8SExt8Imm: Predicate test for 8-bit sign extended immediate constant
  206. // load, works in conjunction with its transform function. N.B.: This relies the
  207. // incoming constant being a 16-bit quantity, where the upper and lower bytes
  208. // are EXACTLY the same (e.g., 0x2a2a)
  209. def v16i8SExt8Imm: PatLeaf<(build_vector), [{
  210. return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).getNode() != 0;
  211. }], v16i8SExt8Imm_xform>;
  212. // v16i8U8Imm_xform function: convert build_vector to unsigned 8-bit
  213. // immediate constant load for v16i8 vectors. N.B.: The incoming constant has
  214. // to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a).
  215. def v16i8U8Imm_xform: SDNodeXForm<build_vector, [{
  216. return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8);
  217. }]>;
  218. // v16i8U8Imm: Predicate test for unsigned 8-bit immediate constant
  219. // load, works in conjunction with its transform function. N.B.: This relies the
  220. // incoming constant being a 16-bit quantity, where the upper and lower bytes
  221. // are EXACTLY the same (e.g., 0x2a2a)
  222. def v16i8U8Imm: PatLeaf<(build_vector), [{
  223. return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).getNode() != 0;
  224. }], v16i8U8Imm_xform>;
  225. // v8i16SExt8Imm_xform function: convert build_vector to 8-bit sign extended
  226. // immediate constant load for v8i16 vectors.
  227. def v8i16SExt8Imm_xform: SDNodeXForm<build_vector, [{
  228. return SPU::get_vec_i8imm(N, *CurDAG, MVT::i16);
  229. }]>;
  230. // v8i16SExt8Imm: Predicate test for 8-bit sign extended immediate constant
  231. // load, works in conjunction with its transform function.
  232. def v8i16SExt8Imm: PatLeaf<(build_vector), [{
  233. return SPU::get_vec_i8imm(N, *CurDAG, MVT::i16).getNode() != 0;
  234. }], v8i16SExt8Imm_xform>;
  235. // v8i16SExt10Imm_xform function: convert build_vector to 16-bit sign extended
  236. // immediate constant load for v8i16 vectors.
  237. def v8i16SExt10Imm_xform: SDNodeXForm<build_vector, [{
  238. return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16);
  239. }]>;
  240. // v8i16SExt10Imm: Predicate test for 16-bit sign extended immediate constant
  241. // load, works in conjunction with its transform function.
  242. def v8i16SExt10Imm: PatLeaf<(build_vector), [{
  243. return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16).getNode() != 0;
  244. }], v8i16SExt10Imm_xform>;
  245. // v8i16Uns10Imm_xform function: convert build_vector to 16-bit unsigned
  246. // immediate constant load for v8i16 vectors.
  247. def v8i16Uns10Imm_xform: SDNodeXForm<build_vector, [{
  248. return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16);
  249. }]>;
  250. // v8i16Uns10Imm: Predicate test for 16-bit unsigned immediate constant
  251. // load, works in conjunction with its transform function.
  252. def v8i16Uns10Imm: PatLeaf<(build_vector), [{
  253. return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16).getNode() != 0;
  254. }], v8i16Uns10Imm_xform>;
  255. // v8i16SExt16Imm_xform function: convert build_vector to 16-bit sign extended
  256. // immediate constant load for v8i16 vectors.
  257. def v8i16Uns16Imm_xform: SDNodeXForm<build_vector, [{
  258. return SPU::get_vec_i16imm(N, *CurDAG, MVT::i16);
  259. }]>;
  260. // v8i16SExt16Imm: Predicate test for 16-bit sign extended immediate constant
  261. // load, works in conjunction with its transform function.
  262. def v8i16SExt16Imm: PatLeaf<(build_vector), [{
  263. return SPU::get_vec_i16imm(N, *CurDAG, MVT::i16).getNode() != 0;
  264. }], v8i16Uns16Imm_xform>;
  265. // v4i32SExt10Imm_xform function: convert build_vector to 10-bit sign extended
  266. // immediate constant load for v4i32 vectors.
  267. def v4i32SExt10Imm_xform: SDNodeXForm<build_vector, [{
  268. return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32);
  269. }]>;
  270. // v4i32SExt10Imm: Predicate test for 10-bit sign extended immediate constant
  271. // load, works in conjunction with its transform function.
  272. def v4i32SExt10Imm: PatLeaf<(build_vector), [{
  273. return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32).getNode() != 0;
  274. }], v4i32SExt10Imm_xform>;
  275. // v4i32Uns10Imm_xform function: convert build_vector to 10-bit unsigned
  276. // immediate constant load for v4i32 vectors.
  277. def v4i32Uns10Imm_xform: SDNodeXForm<build_vector, [{
  278. return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32);
  279. }]>;
  280. // v4i32Uns10Imm: Predicate test for 10-bit unsigned immediate constant
  281. // load, works in conjunction with its transform function.
  282. def v4i32Uns10Imm: PatLeaf<(build_vector), [{
  283. return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32).getNode() != 0;
  284. }], v4i32Uns10Imm_xform>;
  285. // v4i32SExt16Imm_xform function: convert build_vector to 16-bit sign extended
  286. // immediate constant load for v4i32 vectors.
  287. def v4i32SExt16Imm_xform: SDNodeXForm<build_vector, [{
  288. return SPU::get_vec_i16imm(N, *CurDAG, MVT::i32);
  289. }]>;
  290. // v4i32SExt16Imm: Predicate test for 16-bit sign extended immediate constant
  291. // load, works in conjunction with its transform function.
  292. def v4i32SExt16Imm: PatLeaf<(build_vector), [{
  293. return SPU::get_vec_i16imm(N, *CurDAG, MVT::i32).getNode() != 0;
  294. }], v4i32SExt16Imm_xform>;
  295. // v4i32Uns18Imm_xform function: convert build_vector to 18-bit unsigned
  296. // immediate constant load for v4i32 vectors.
  297. def v4i32Uns18Imm_xform: SDNodeXForm<build_vector, [{
  298. return SPU::get_vec_u18imm(N, *CurDAG, MVT::i32);
  299. }]>;
  300. // v4i32Uns18Imm: Predicate test for 18-bit unsigned immediate constant load,
  301. // works in conjunction with its transform function.
  302. def v4i32Uns18Imm: PatLeaf<(build_vector), [{
  303. return SPU::get_vec_u18imm(N, *CurDAG, MVT::i32).getNode() != 0;
  304. }], v4i32Uns18Imm_xform>;
  305. // ILHUvec_get_imm xform function: convert build_vector to ILHUvec imm constant
  306. // load.
  307. def ILHUvec_get_imm: SDNodeXForm<build_vector, [{
  308. return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i32);
  309. }]>;
  310. /// immILHUvec: Predicate test for a ILHU constant vector.
  311. def immILHUvec: PatLeaf<(build_vector), [{
  312. return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i32).getNode() != 0;
  313. }], ILHUvec_get_imm>;
  314. // Catch-all for any other i32 vector constants
  315. def v4i32_get_imm: SDNodeXForm<build_vector, [{
  316. return SPU::get_v4i32_imm(N, *CurDAG);
  317. }]>;
  318. def v4i32Imm: PatLeaf<(build_vector), [{
  319. return SPU::get_v4i32_imm(N, *CurDAG).getNode() != 0;
  320. }], v4i32_get_imm>;
  321. // v2i64SExt10Imm_xform function: convert build_vector to 10-bit sign extended
  322. // immediate constant load for v2i64 vectors.
  323. def v2i64SExt10Imm_xform: SDNodeXForm<build_vector, [{
  324. return SPU::get_vec_i10imm(N, *CurDAG, MVT::i64);
  325. }]>;
  326. // v2i64SExt10Imm: Predicate test for 10-bit sign extended immediate constant
  327. // load, works in conjunction with its transform function.
  328. def v2i64SExt10Imm: PatLeaf<(build_vector), [{
  329. return SPU::get_vec_i10imm(N, *CurDAG, MVT::i64).getNode() != 0;
  330. }], v2i64SExt10Imm_xform>;
  331. // v2i64SExt16Imm_xform function: convert build_vector to 16-bit sign extended
  332. // immediate constant load for v2i64 vectors.
  333. def v2i64SExt16Imm_xform: SDNodeXForm<build_vector, [{
  334. return SPU::get_vec_i16imm(N, *CurDAG, MVT::i64);
  335. }]>;
  336. // v2i64SExt16Imm: Predicate test for 16-bit sign extended immediate constant
  337. // load, works in conjunction with its transform function.
  338. def v2i64SExt16Imm: PatLeaf<(build_vector), [{
  339. return SPU::get_vec_i16imm(N, *CurDAG, MVT::i64).getNode() != 0;
  340. }], v2i64SExt16Imm_xform>;
  341. // v2i64Uns18Imm_xform function: convert build_vector to 18-bit unsigned
  342. // immediate constant load for v2i64 vectors.
  343. def v2i64Uns18Imm_xform: SDNodeXForm<build_vector, [{
  344. return SPU::get_vec_u18imm(N, *CurDAG, MVT::i64);
  345. }]>;
  346. // v2i64Uns18Imm: Predicate test for 18-bit unsigned immediate constant load,
  347. // works in conjunction with its transform function.
  348. def v2i64Uns18Imm: PatLeaf<(build_vector), [{
  349. return SPU::get_vec_u18imm(N, *CurDAG, MVT::i64).getNode() != 0;
  350. }], v2i64Uns18Imm_xform>;
  351. /// immILHUvec: Predicate test for a ILHU constant vector.
  352. def immILHUvec_i64: PatLeaf<(build_vector), [{
  353. return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i64).getNode() != 0;
  354. }], ILHUvec_get_imm>;
  355. // Catch-all for any other i32 vector constants
  356. def v2i64_get_imm: SDNodeXForm<build_vector, [{
  357. return SPU::get_v2i64_imm(N, *CurDAG);
  358. }]>;
  359. def v2i64Imm: PatLeaf<(build_vector), [{
  360. return SPU::get_v2i64_imm(N, *CurDAG).getNode() != 0;
  361. }], v2i64_get_imm>;
  362. //===----------------------------------------------------------------------===//
  363. // Operand Definitions.
  364. def s7imm: Operand<i8> {
  365. let PrintMethod = "printS7ImmOperand";
  366. }
  367. def s7imm_i8: Operand<i8> {
  368. let PrintMethod = "printS7ImmOperand";
  369. }
  370. def u7imm: Operand<i16> {
  371. let PrintMethod = "printU7ImmOperand";
  372. }
  373. def u7imm_i8: Operand<i8> {
  374. let PrintMethod = "printU7ImmOperand";
  375. }
  376. def u7imm_i32: Operand<i32> {
  377. let PrintMethod = "printU7ImmOperand";
  378. }
  379. // Halfword, signed 10-bit constant
  380. def s10imm : Operand<i16> {
  381. let PrintMethod = "printS10ImmOperand";
  382. }
  383. def s10imm_i8: Operand<i8> {
  384. let PrintMethod = "printS10ImmOperand";
  385. }
  386. def s10imm_i32: Operand<i32> {
  387. let PrintMethod = "printS10ImmOperand";
  388. }
  389. def s10imm_i64: Operand<i64> {
  390. let PrintMethod = "printS10ImmOperand";
  391. }
  392. // Unsigned 10-bit integers:
  393. def u10imm: Operand<i16> {
  394. let PrintMethod = "printU10ImmOperand";
  395. }
  396. def u10imm_i8: Operand<i8> {
  397. let PrintMethod = "printU10ImmOperand";
  398. }
  399. def u10imm_i32: Operand<i32> {
  400. let PrintMethod = "printU10ImmOperand";
  401. }
  402. def s16imm : Operand<i16> {
  403. let PrintMethod = "printS16ImmOperand";
  404. }
  405. def s16imm_i8: Operand<i8> {
  406. let PrintMethod = "printS16ImmOperand";
  407. }
  408. def s16imm_i32: Operand<i32> {
  409. let PrintMethod = "printS16ImmOperand";
  410. }
  411. def s16imm_i64: Operand<i64> {
  412. let PrintMethod = "printS16ImmOperand";
  413. }
  414. def s16imm_f32: Operand<f32> {
  415. let PrintMethod = "printS16ImmOperand";
  416. }
  417. def s16imm_f64: Operand<f64> {
  418. let PrintMethod = "printS16ImmOperand";
  419. }
  420. def u16imm_i64 : Operand<i64> {
  421. let PrintMethod = "printU16ImmOperand";
  422. }
  423. def u16imm_i32 : Operand<i32> {
  424. let PrintMethod = "printU16ImmOperand";
  425. }
  426. def u16imm : Operand<i16> {
  427. let PrintMethod = "printU16ImmOperand";
  428. }
  429. def f16imm : Operand<f32> {
  430. let PrintMethod = "printU16ImmOperand";
  431. }
  432. def s18imm : Operand<i32> {
  433. let PrintMethod = "printS18ImmOperand";
  434. }
  435. def u18imm : Operand<i32> {
  436. let PrintMethod = "printU18ImmOperand";
  437. }
  438. def u18imm_i64 : Operand<i64> {
  439. let PrintMethod = "printU18ImmOperand";
  440. }
  441. def f18imm : Operand<f32> {
  442. let PrintMethod = "printU18ImmOperand";
  443. }
  444. def f18imm_f64 : Operand<f64> {
  445. let PrintMethod = "printU18ImmOperand";
  446. }
  447. // Negated 7-bit halfword rotate immediate operands
  448. def rothNeg7imm : Operand<i32> {
  449. let PrintMethod = "printROTHNeg7Imm";
  450. }
  451. def rothNeg7imm_i16 : Operand<i16> {
  452. let PrintMethod = "printROTHNeg7Imm";
  453. }
  454. // Negated 7-bit word rotate immediate operands
  455. def rotNeg7imm : Operand<i32> {
  456. let PrintMethod = "printROTNeg7Imm";
  457. }
  458. def rotNeg7imm_i16 : Operand<i16> {
  459. let PrintMethod = "printROTNeg7Imm";
  460. }
  461. def rotNeg7imm_i8 : Operand<i8> {
  462. let PrintMethod = "printROTNeg7Imm";
  463. }
  464. def target : Operand<OtherVT> {
  465. let PrintMethod = "printBranchOperand";
  466. }
  467. // Absolute address call target
  468. def calltarget : Operand<iPTR> {
  469. let PrintMethod = "printCallOperand";
  470. let MIOperandInfo = (ops u18imm:$calldest);
  471. }
  472. // PC relative call target
  473. def relcalltarget : Operand<iPTR> {
  474. let PrintMethod = "printPCRelativeOperand";
  475. let MIOperandInfo = (ops s16imm:$calldest);
  476. }
  477. // Branch targets:
  478. def brtarget : Operand<OtherVT> {
  479. let PrintMethod = "printPCRelativeOperand";
  480. }
  481. // Hint for branch target
  482. def hbrtarget : Operand<OtherVT> {
  483. let PrintMethod = "printHBROperand";
  484. }
  485. // Indirect call target
  486. def indcalltarget : Operand<iPTR> {
  487. let PrintMethod = "printCallOperand";
  488. let MIOperandInfo = (ops ptr_rc:$calldest);
  489. }
  490. def symbolHi: Operand<i32> {
  491. let PrintMethod = "printSymbolHi";
  492. }
  493. def symbolLo: Operand<i32> {
  494. let PrintMethod = "printSymbolLo";
  495. }
  496. def symbolLSA: Operand<i32> {
  497. let PrintMethod = "printSymbolLSA";
  498. }
  499. // Shuffle address memory operaand [s7imm(reg) d-format]
  500. def shufaddr : Operand<iPTR> {
  501. let PrintMethod = "printShufAddr";
  502. let MIOperandInfo = (ops s7imm:$imm, ptr_rc:$reg);
  503. }
  504. // memory s10imm(reg) operand
  505. def dformaddr : Operand<iPTR> {
  506. let PrintMethod = "printDFormAddr";
  507. let MIOperandInfo = (ops s10imm:$imm, ptr_rc:$reg);
  508. }
  509. // 256K local store address
  510. // N.B.: The tblgen code generator expects to have two operands, an offset
  511. // and a pointer. Of these, only the immediate is actually used.
  512. def addr256k : Operand<iPTR> {
  513. let PrintMethod = "printAddr256K";
  514. let MIOperandInfo = (ops s16imm:$imm, ptr_rc:$reg);
  515. }
  516. // memory s18imm(reg) operand
  517. def memri18 : Operand<iPTR> {
  518. let PrintMethod = "printMemRegImmS18";
  519. let MIOperandInfo = (ops s18imm:$imm, ptr_rc:$reg);
  520. }
  521. // memory register + register operand
  522. def memrr : Operand<iPTR> {
  523. let PrintMethod = "printMemRegReg";
  524. let MIOperandInfo = (ops ptr_rc:$reg_a, ptr_rc:$reg_b);
  525. }
  526. // Define SPU-specific addressing modes: These come in three basic
  527. // flavors:
  528. //
  529. // D-form : [r+I10] (10-bit signed offset + reg)
  530. // X-form : [r+r] (reg+reg)
  531. // A-form : abs (256K LSA offset)
  532. // D-form(2): [r+I7] (7-bit signed offset + reg)
  533. def dform_addr : ComplexPattern<iPTR, 2, "SelectDFormAddr",
  534. [], [SDNPWantRoot]>;
  535. def xform_addr : ComplexPattern<iPTR, 2, "SelectXFormAddr",
  536. [], [SDNPWantRoot]>;
  537. def aform_addr : ComplexPattern<iPTR, 2, "SelectAFormAddr",
  538. [], [SDNPWantRoot]>;
  539. def dform2_addr : ComplexPattern<iPTR, 2, "SelectDForm2Addr",
  540. [], [SDNPWantRoot]>;