ARMAddressingModes.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. //===-- ARMAddressingModes.h - ARM Addressing Modes -------------*- C++ -*-===//
  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 contains the ARM addressing mode implementation stuff.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMADDRESSINGMODES_H
  13. #define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMADDRESSINGMODES_H
  14. #include "llvm/ADT/APFloat.h"
  15. #include "llvm/ADT/APInt.h"
  16. #include "llvm/ADT/bit.h"
  17. #include "llvm/Support/ErrorHandling.h"
  18. #include "llvm/Support/MathExtras.h"
  19. #include <cassert>
  20. namespace llvm {
  21. /// ARM_AM - ARM Addressing Mode Stuff
  22. namespace ARM_AM {
  23. enum ShiftOpc {
  24. no_shift = 0,
  25. asr,
  26. lsl,
  27. lsr,
  28. ror,
  29. rrx,
  30. uxtw
  31. };
  32. enum AddrOpc {
  33. sub = 0,
  34. add
  35. };
  36. inline const char *getAddrOpcStr(AddrOpc Op) { return Op == sub ? "-" : ""; }
  37. inline const char *getShiftOpcStr(ShiftOpc Op) {
  38. switch (Op) {
  39. default: llvm_unreachable("Unknown shift opc!");
  40. case ARM_AM::asr: return "asr";
  41. case ARM_AM::lsl: return "lsl";
  42. case ARM_AM::lsr: return "lsr";
  43. case ARM_AM::ror: return "ror";
  44. case ARM_AM::rrx: return "rrx";
  45. case ARM_AM::uxtw: return "uxtw";
  46. }
  47. }
  48. inline unsigned getShiftOpcEncoding(ShiftOpc Op) {
  49. switch (Op) {
  50. default: llvm_unreachable("Unknown shift opc!");
  51. case ARM_AM::asr: return 2;
  52. case ARM_AM::lsl: return 0;
  53. case ARM_AM::lsr: return 1;
  54. case ARM_AM::ror: return 3;
  55. }
  56. }
  57. enum AMSubMode {
  58. bad_am_submode = 0,
  59. ia,
  60. ib,
  61. da,
  62. db
  63. };
  64. inline const char *getAMSubModeStr(AMSubMode Mode) {
  65. switch (Mode) {
  66. default: llvm_unreachable("Unknown addressing sub-mode!");
  67. case ARM_AM::ia: return "ia";
  68. case ARM_AM::ib: return "ib";
  69. case ARM_AM::da: return "da";
  70. case ARM_AM::db: return "db";
  71. }
  72. }
  73. /// rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
  74. ///
  75. inline unsigned rotr32(unsigned Val, unsigned Amt) {
  76. assert(Amt < 32 && "Invalid rotate amount");
  77. return (Val >> Amt) | (Val << ((32-Amt)&31));
  78. }
  79. /// rotl32 - Rotate a 32-bit unsigned value left by a specified # bits.
  80. ///
  81. inline unsigned rotl32(unsigned Val, unsigned Amt) {
  82. assert(Amt < 32 && "Invalid rotate amount");
  83. return (Val << Amt) | (Val >> ((32-Amt)&31));
  84. }
  85. //===--------------------------------------------------------------------===//
  86. // Addressing Mode #1: shift_operand with registers
  87. //===--------------------------------------------------------------------===//
  88. //
  89. // This 'addressing mode' is used for arithmetic instructions. It can
  90. // represent things like:
  91. // reg
  92. // reg [asr|lsl|lsr|ror|rrx] reg
  93. // reg [asr|lsl|lsr|ror|rrx] imm
  94. //
  95. // This is stored three operands [rega, regb, opc]. The first is the base
  96. // reg, the second is the shift amount (or reg0 if not present or imm). The
  97. // third operand encodes the shift opcode and the imm if a reg isn't present.
  98. //
  99. inline unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm) {
  100. return ShOp | (Imm << 3);
  101. }
  102. inline unsigned getSORegOffset(unsigned Op) { return Op >> 3; }
  103. inline ShiftOpc getSORegShOp(unsigned Op) { return (ShiftOpc)(Op & 7); }
  104. /// getSOImmValImm - Given an encoded imm field for the reg/imm form, return
  105. /// the 8-bit imm value.
  106. inline unsigned getSOImmValImm(unsigned Imm) { return Imm & 0xFF; }
  107. /// getSOImmValRot - Given an encoded imm field for the reg/imm form, return
  108. /// the rotate amount.
  109. inline unsigned getSOImmValRot(unsigned Imm) { return (Imm >> 8) * 2; }
  110. /// getSOImmValRotate - Try to handle Imm with an immediate shifter operand,
  111. /// computing the rotate amount to use. If this immediate value cannot be
  112. /// handled with a single shifter-op, determine a good rotate amount that will
  113. /// take a maximal chunk of bits out of the immediate.
  114. inline unsigned getSOImmValRotate(unsigned Imm) {
  115. // 8-bit (or less) immediates are trivially shifter_operands with a rotate
  116. // of zero.
  117. if ((Imm & ~255U) == 0) return 0;
  118. // Use CTZ to compute the rotate amount.
  119. unsigned TZ = countTrailingZeros(Imm);
  120. // Rotate amount must be even. Something like 0x200 must be rotated 8 bits,
  121. // not 9.
  122. unsigned RotAmt = TZ & ~1;
  123. // If we can handle this spread, return it.
  124. if ((rotr32(Imm, RotAmt) & ~255U) == 0)
  125. return (32-RotAmt)&31; // HW rotates right, not left.
  126. // For values like 0xF000000F, we should ignore the low 6 bits, then
  127. // retry the hunt.
  128. if (Imm & 63U) {
  129. unsigned TZ2 = countTrailingZeros(Imm & ~63U);
  130. unsigned RotAmt2 = TZ2 & ~1;
  131. if ((rotr32(Imm, RotAmt2) & ~255U) == 0)
  132. return (32-RotAmt2)&31; // HW rotates right, not left.
  133. }
  134. // Otherwise, we have no way to cover this span of bits with a single
  135. // shifter_op immediate. Return a chunk of bits that will be useful to
  136. // handle.
  137. return (32-RotAmt)&31; // HW rotates right, not left.
  138. }
  139. /// getSOImmVal - Given a 32-bit immediate, if it is something that can fit
  140. /// into an shifter_operand immediate operand, return the 12-bit encoding for
  141. /// it. If not, return -1.
  142. inline int getSOImmVal(unsigned Arg) {
  143. // 8-bit (or less) immediates are trivially shifter_operands with a rotate
  144. // of zero.
  145. if ((Arg & ~255U) == 0) return Arg;
  146. unsigned RotAmt = getSOImmValRotate(Arg);
  147. // If this cannot be handled with a single shifter_op, bail out.
  148. if (rotr32(~255U, RotAmt) & Arg)
  149. return -1;
  150. // Encode this correctly.
  151. return rotl32(Arg, RotAmt) | ((RotAmt>>1) << 8);
  152. }
  153. /// isSOImmTwoPartVal - Return true if the specified value can be obtained by
  154. /// or'ing together two SOImmVal's.
  155. inline bool isSOImmTwoPartVal(unsigned V) {
  156. // If this can be handled with a single shifter_op, bail out.
  157. V = rotr32(~255U, getSOImmValRotate(V)) & V;
  158. if (V == 0)
  159. return false;
  160. // If this can be handled with two shifter_op's, accept.
  161. V = rotr32(~255U, getSOImmValRotate(V)) & V;
  162. return V == 0;
  163. }
  164. /// getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal,
  165. /// return the first chunk of it.
  166. inline unsigned getSOImmTwoPartFirst(unsigned V) {
  167. return rotr32(255U, getSOImmValRotate(V)) & V;
  168. }
  169. /// getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal,
  170. /// return the second chunk of it.
  171. inline unsigned getSOImmTwoPartSecond(unsigned V) {
  172. // Mask out the first hunk.
  173. V = rotr32(~255U, getSOImmValRotate(V)) & V;
  174. // Take what's left.
  175. assert(V == (rotr32(255U, getSOImmValRotate(V)) & V));
  176. return V;
  177. }
  178. /// isSOImmTwoPartValNeg - Return true if the specified value can be obtained
  179. /// by two SOImmVal, that -V = First + Second.
  180. /// "R+V" can be optimized to (sub (sub R, First), Second).
  181. /// "R=V" can be optimized to (sub (mvn R, ~(-First)), Second).
  182. inline bool isSOImmTwoPartValNeg(unsigned V) {
  183. unsigned First;
  184. if (!isSOImmTwoPartVal(-V))
  185. return false;
  186. // Return false if ~(-First) is not a SoImmval.
  187. First = getSOImmTwoPartFirst(-V);
  188. First = ~(-First);
  189. return !(rotr32(~255U, getSOImmValRotate(First)) & First);
  190. }
  191. /// getThumbImmValShift - Try to handle Imm with a 8-bit immediate followed
  192. /// by a left shift. Returns the shift amount to use.
  193. inline unsigned getThumbImmValShift(unsigned Imm) {
  194. // 8-bit (or less) immediates are trivially immediate operand with a shift
  195. // of zero.
  196. if ((Imm & ~255U) == 0) return 0;
  197. // Use CTZ to compute the shift amount.
  198. return countTrailingZeros(Imm);
  199. }
  200. /// isThumbImmShiftedVal - Return true if the specified value can be obtained
  201. /// by left shifting a 8-bit immediate.
  202. inline bool isThumbImmShiftedVal(unsigned V) {
  203. // If this can be handled with
  204. V = (~255U << getThumbImmValShift(V)) & V;
  205. return V == 0;
  206. }
  207. /// getThumbImm16ValShift - Try to handle Imm with a 16-bit immediate followed
  208. /// by a left shift. Returns the shift amount to use.
  209. inline unsigned getThumbImm16ValShift(unsigned Imm) {
  210. // 16-bit (or less) immediates are trivially immediate operand with a shift
  211. // of zero.
  212. if ((Imm & ~65535U) == 0) return 0;
  213. // Use CTZ to compute the shift amount.
  214. return countTrailingZeros(Imm);
  215. }
  216. /// isThumbImm16ShiftedVal - Return true if the specified value can be
  217. /// obtained by left shifting a 16-bit immediate.
  218. inline bool isThumbImm16ShiftedVal(unsigned V) {
  219. // If this can be handled with
  220. V = (~65535U << getThumbImm16ValShift(V)) & V;
  221. return V == 0;
  222. }
  223. /// getThumbImmNonShiftedVal - If V is a value that satisfies
  224. /// isThumbImmShiftedVal, return the non-shiftd value.
  225. inline unsigned getThumbImmNonShiftedVal(unsigned V) {
  226. return V >> getThumbImmValShift(V);
  227. }
  228. /// getT2SOImmValSplat - Return the 12-bit encoded representation
  229. /// if the specified value can be obtained by splatting the low 8 bits
  230. /// into every other byte or every byte of a 32-bit value. i.e.,
  231. /// 00000000 00000000 00000000 abcdefgh control = 0
  232. /// 00000000 abcdefgh 00000000 abcdefgh control = 1
  233. /// abcdefgh 00000000 abcdefgh 00000000 control = 2
  234. /// abcdefgh abcdefgh abcdefgh abcdefgh control = 3
  235. /// Return -1 if none of the above apply.
  236. /// See ARM Reference Manual A6.3.2.
  237. inline int getT2SOImmValSplatVal(unsigned V) {
  238. unsigned u, Vs, Imm;
  239. // control = 0
  240. if ((V & 0xffffff00) == 0)
  241. return V;
  242. // If the value is zeroes in the first byte, just shift those off
  243. Vs = ((V & 0xff) == 0) ? V >> 8 : V;
  244. // Any passing value only has 8 bits of payload, splatted across the word
  245. Imm = Vs & 0xff;
  246. // Likewise, any passing values have the payload splatted into the 3rd byte
  247. u = Imm | (Imm << 16);
  248. // control = 1 or 2
  249. if (Vs == u)
  250. return (((Vs == V) ? 1 : 2) << 8) | Imm;
  251. // control = 3
  252. if (Vs == (u | (u << 8)))
  253. return (3 << 8) | Imm;
  254. return -1;
  255. }
  256. /// getT2SOImmValRotateVal - Return the 12-bit encoded representation if the
  257. /// specified value is a rotated 8-bit value. Return -1 if no rotation
  258. /// encoding is possible.
  259. /// See ARM Reference Manual A6.3.2.
  260. inline int getT2SOImmValRotateVal(unsigned V) {
  261. unsigned RotAmt = countLeadingZeros(V);
  262. if (RotAmt >= 24)
  263. return -1;
  264. // If 'Arg' can be handled with a single shifter_op return the value.
  265. if ((rotr32(0xff000000U, RotAmt) & V) == V)
  266. return (rotr32(V, 24 - RotAmt) & 0x7f) | ((RotAmt + 8) << 7);
  267. return -1;
  268. }
  269. /// getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit
  270. /// into a Thumb-2 shifter_operand immediate operand, return the 12-bit
  271. /// encoding for it. If not, return -1.
  272. /// See ARM Reference Manual A6.3.2.
  273. inline int getT2SOImmVal(unsigned Arg) {
  274. // If 'Arg' is an 8-bit splat, then get the encoded value.
  275. int Splat = getT2SOImmValSplatVal(Arg);
  276. if (Splat != -1)
  277. return Splat;
  278. // If 'Arg' can be handled with a single shifter_op return the value.
  279. int Rot = getT2SOImmValRotateVal(Arg);
  280. if (Rot != -1)
  281. return Rot;
  282. return -1;
  283. }
  284. inline unsigned getT2SOImmValRotate(unsigned V) {
  285. if ((V & ~255U) == 0) return 0;
  286. // Use CTZ to compute the rotate amount.
  287. unsigned RotAmt = countTrailingZeros(V);
  288. return (32 - RotAmt) & 31;
  289. }
  290. inline bool isT2SOImmTwoPartVal(unsigned Imm) {
  291. unsigned V = Imm;
  292. // Passing values can be any combination of splat values and shifter
  293. // values. If this can be handled with a single shifter or splat, bail
  294. // out. Those should be handled directly, not with a two-part val.
  295. if (getT2SOImmValSplatVal(V) != -1)
  296. return false;
  297. V = rotr32 (~255U, getT2SOImmValRotate(V)) & V;
  298. if (V == 0)
  299. return false;
  300. // If this can be handled as an immediate, accept.
  301. if (getT2SOImmVal(V) != -1) return true;
  302. // Likewise, try masking out a splat value first.
  303. V = Imm;
  304. if (getT2SOImmValSplatVal(V & 0xff00ff00U) != -1)
  305. V &= ~0xff00ff00U;
  306. else if (getT2SOImmValSplatVal(V & 0x00ff00ffU) != -1)
  307. V &= ~0x00ff00ffU;
  308. // If what's left can be handled as an immediate, accept.
  309. if (getT2SOImmVal(V) != -1) return true;
  310. // Otherwise, do not accept.
  311. return false;
  312. }
  313. inline unsigned getT2SOImmTwoPartFirst(unsigned Imm) {
  314. assert (isT2SOImmTwoPartVal(Imm) &&
  315. "Immedate cannot be encoded as two part immediate!");
  316. // Try a shifter operand as one part
  317. unsigned V = rotr32 (~255, getT2SOImmValRotate(Imm)) & Imm;
  318. // If the rest is encodable as an immediate, then return it.
  319. if (getT2SOImmVal(V) != -1) return V;
  320. // Try masking out a splat value first.
  321. if (getT2SOImmValSplatVal(Imm & 0xff00ff00U) != -1)
  322. return Imm & 0xff00ff00U;
  323. // The other splat is all that's left as an option.
  324. assert (getT2SOImmValSplatVal(Imm & 0x00ff00ffU) != -1);
  325. return Imm & 0x00ff00ffU;
  326. }
  327. inline unsigned getT2SOImmTwoPartSecond(unsigned Imm) {
  328. // Mask out the first hunk
  329. Imm ^= getT2SOImmTwoPartFirst(Imm);
  330. // Return what's left
  331. assert (getT2SOImmVal(Imm) != -1 &&
  332. "Unable to encode second part of T2 two part SO immediate");
  333. return Imm;
  334. }
  335. //===--------------------------------------------------------------------===//
  336. // Addressing Mode #2
  337. //===--------------------------------------------------------------------===//
  338. //
  339. // This is used for most simple load/store instructions.
  340. //
  341. // addrmode2 := reg +/- reg shop imm
  342. // addrmode2 := reg +/- imm12
  343. //
  344. // The first operand is always a Reg. The second operand is a reg if in
  345. // reg/reg form, otherwise it's reg#0. The third field encodes the operation
  346. // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The
  347. // fourth operand 16-17 encodes the index mode.
  348. //
  349. // If this addressing mode is a frame index (before prolog/epilog insertion
  350. // and code rewriting), this operand will have the form: FI#, reg0, <offs>
  351. // with no shift amount for the frame offset.
  352. //
  353. inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO,
  354. unsigned IdxMode = 0) {
  355. assert(Imm12 < (1 << 12) && "Imm too large!");
  356. bool isSub = Opc == sub;
  357. return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ;
  358. }
  359. inline unsigned getAM2Offset(unsigned AM2Opc) {
  360. return AM2Opc & ((1 << 12)-1);
  361. }
  362. inline AddrOpc getAM2Op(unsigned AM2Opc) {
  363. return ((AM2Opc >> 12) & 1) ? sub : add;
  364. }
  365. inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) {
  366. return (ShiftOpc)((AM2Opc >> 13) & 7);
  367. }
  368. inline unsigned getAM2IdxMode(unsigned AM2Opc) { return (AM2Opc >> 16); }
  369. //===--------------------------------------------------------------------===//
  370. // Addressing Mode #3
  371. //===--------------------------------------------------------------------===//
  372. //
  373. // This is used for sign-extending loads, and load/store-pair instructions.
  374. //
  375. // addrmode3 := reg +/- reg
  376. // addrmode3 := reg +/- imm8
  377. //
  378. // The first operand is always a Reg. The second operand is a reg if in
  379. // reg/reg form, otherwise it's reg#0. The third field encodes the operation
  380. // in bit 8, the immediate in bits 0-7. The fourth operand 9-10 encodes the
  381. // index mode.
  382. /// getAM3Opc - This function encodes the addrmode3 opc field.
  383. inline unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset,
  384. unsigned IdxMode = 0) {
  385. bool isSub = Opc == sub;
  386. return ((int)isSub << 8) | Offset | (IdxMode << 9);
  387. }
  388. inline unsigned char getAM3Offset(unsigned AM3Opc) { return AM3Opc & 0xFF; }
  389. inline AddrOpc getAM3Op(unsigned AM3Opc) {
  390. return ((AM3Opc >> 8) & 1) ? sub : add;
  391. }
  392. inline unsigned getAM3IdxMode(unsigned AM3Opc) { return (AM3Opc >> 9); }
  393. //===--------------------------------------------------------------------===//
  394. // Addressing Mode #4
  395. //===--------------------------------------------------------------------===//
  396. //
  397. // This is used for load / store multiple instructions.
  398. //
  399. // addrmode4 := reg, <mode>
  400. //
  401. // The four modes are:
  402. // IA - Increment after
  403. // IB - Increment before
  404. // DA - Decrement after
  405. // DB - Decrement before
  406. // For VFP instructions, only the IA and DB modes are valid.
  407. inline AMSubMode getAM4SubMode(unsigned Mode) {
  408. return (AMSubMode)(Mode & 0x7);
  409. }
  410. inline unsigned getAM4ModeImm(AMSubMode SubMode) { return (int)SubMode; }
  411. //===--------------------------------------------------------------------===//
  412. // Addressing Mode #5
  413. //===--------------------------------------------------------------------===//
  414. //
  415. // This is used for coprocessor instructions, such as FP load/stores.
  416. //
  417. // addrmode5 := reg +/- imm8*4
  418. //
  419. // The first operand is always a Reg. The second operand encodes the
  420. // operation (add or subtract) in bit 8 and the immediate in bits 0-7.
  421. /// getAM5Opc - This function encodes the addrmode5 opc field.
  422. inline unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset) {
  423. bool isSub = Opc == sub;
  424. return ((int)isSub << 8) | Offset;
  425. }
  426. inline unsigned char getAM5Offset(unsigned AM5Opc) { return AM5Opc & 0xFF; }
  427. inline AddrOpc getAM5Op(unsigned AM5Opc) {
  428. return ((AM5Opc >> 8) & 1) ? sub : add;
  429. }
  430. //===--------------------------------------------------------------------===//
  431. // Addressing Mode #5 FP16
  432. //===--------------------------------------------------------------------===//
  433. //
  434. // This is used for coprocessor instructions, such as 16-bit FP load/stores.
  435. //
  436. // addrmode5fp16 := reg +/- imm8*2
  437. //
  438. // The first operand is always a Reg. The second operand encodes the
  439. // operation (add or subtract) in bit 8 and the immediate in bits 0-7.
  440. /// getAM5FP16Opc - This function encodes the addrmode5fp16 opc field.
  441. inline unsigned getAM5FP16Opc(AddrOpc Opc, unsigned char Offset) {
  442. bool isSub = Opc == sub;
  443. return ((int)isSub << 8) | Offset;
  444. }
  445. inline unsigned char getAM5FP16Offset(unsigned AM5Opc) {
  446. return AM5Opc & 0xFF;
  447. }
  448. inline AddrOpc getAM5FP16Op(unsigned AM5Opc) {
  449. return ((AM5Opc >> 8) & 1) ? sub : add;
  450. }
  451. //===--------------------------------------------------------------------===//
  452. // Addressing Mode #6
  453. //===--------------------------------------------------------------------===//
  454. //
  455. // This is used for NEON load / store instructions.
  456. //
  457. // addrmode6 := reg with optional alignment
  458. //
  459. // This is stored in two operands [regaddr, align]. The first is the
  460. // address register. The second operand is the value of the alignment
  461. // specifier in bytes or zero if no explicit alignment.
  462. // Valid alignments depend on the specific instruction.
  463. //===--------------------------------------------------------------------===//
  464. // NEON/MVE Modified Immediates
  465. //===--------------------------------------------------------------------===//
  466. //
  467. // Several NEON and MVE instructions (e.g., VMOV) take a "modified immediate"
  468. // vector operand, where a small immediate encoded in the instruction
  469. // specifies a full NEON vector value. These modified immediates are
  470. // represented here as encoded integers. The low 8 bits hold the immediate
  471. // value; bit 12 holds the "Op" field of the instruction, and bits 11-8 hold
  472. // the "Cmode" field of the instruction. The interfaces below treat the
  473. // Op and Cmode values as a single 5-bit value.
  474. inline unsigned createVMOVModImm(unsigned OpCmode, unsigned Val) {
  475. return (OpCmode << 8) | Val;
  476. }
  477. inline unsigned getVMOVModImmOpCmode(unsigned ModImm) {
  478. return (ModImm >> 8) & 0x1f;
  479. }
  480. inline unsigned getVMOVModImmVal(unsigned ModImm) { return ModImm & 0xff; }
  481. /// decodeVMOVModImm - Decode a NEON/MVE modified immediate value into the
  482. /// element value and the element size in bits. (If the element size is
  483. /// smaller than the vector, it is splatted into all the elements.)
  484. inline uint64_t decodeVMOVModImm(unsigned ModImm, unsigned &EltBits) {
  485. unsigned OpCmode = getVMOVModImmOpCmode(ModImm);
  486. unsigned Imm8 = getVMOVModImmVal(ModImm);
  487. uint64_t Val = 0;
  488. if (OpCmode == 0xe) {
  489. // 8-bit vector elements
  490. Val = Imm8;
  491. EltBits = 8;
  492. } else if ((OpCmode & 0xc) == 0x8) {
  493. // 16-bit vector elements
  494. unsigned ByteNum = (OpCmode & 0x6) >> 1;
  495. Val = Imm8 << (8 * ByteNum);
  496. EltBits = 16;
  497. } else if ((OpCmode & 0x8) == 0) {
  498. // 32-bit vector elements, zero with one byte set
  499. unsigned ByteNum = (OpCmode & 0x6) >> 1;
  500. Val = Imm8 << (8 * ByteNum);
  501. EltBits = 32;
  502. } else if ((OpCmode & 0xe) == 0xc) {
  503. // 32-bit vector elements, one byte with low bits set
  504. unsigned ByteNum = 1 + (OpCmode & 0x1);
  505. Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
  506. EltBits = 32;
  507. } else if (OpCmode == 0x1e) {
  508. // 64-bit vector elements
  509. for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
  510. if ((ModImm >> ByteNum) & 1)
  511. Val |= (uint64_t)0xff << (8 * ByteNum);
  512. }
  513. EltBits = 64;
  514. } else {
  515. llvm_unreachable("Unsupported VMOV immediate");
  516. }
  517. return Val;
  518. }
  519. // Generic validation for single-byte immediate (0X00, 00X0, etc).
  520. inline bool isNEONBytesplat(unsigned Value, unsigned Size) {
  521. assert(Size >= 1 && Size <= 4 && "Invalid size");
  522. unsigned count = 0;
  523. for (unsigned i = 0; i < Size; ++i) {
  524. if (Value & 0xff) count++;
  525. Value >>= 8;
  526. }
  527. return count == 1;
  528. }
  529. /// Checks if Value is a correct immediate for instructions like VBIC/VORR.
  530. inline bool isNEONi16splat(unsigned Value) {
  531. if (Value > 0xffff)
  532. return false;
  533. // i16 value with set bits only in one byte X0 or 0X.
  534. return Value == 0 || isNEONBytesplat(Value, 2);
  535. }
  536. // Encode NEON 16 bits Splat immediate for instructions like VBIC/VORR
  537. inline unsigned encodeNEONi16splat(unsigned Value) {
  538. assert(isNEONi16splat(Value) && "Invalid NEON splat value");
  539. if (Value >= 0x100)
  540. Value = (Value >> 8) | 0xa00;
  541. else
  542. Value |= 0x800;
  543. return Value;
  544. }
  545. /// Checks if Value is a correct immediate for instructions like VBIC/VORR.
  546. inline bool isNEONi32splat(unsigned Value) {
  547. // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
  548. return Value == 0 || isNEONBytesplat(Value, 4);
  549. }
  550. /// Encode NEON 32 bits Splat immediate for instructions like VBIC/VORR.
  551. inline unsigned encodeNEONi32splat(unsigned Value) {
  552. assert(isNEONi32splat(Value) && "Invalid NEON splat value");
  553. if (Value >= 0x100 && Value <= 0xff00)
  554. Value = (Value >> 8) | 0x200;
  555. else if (Value > 0xffff && Value <= 0xff0000)
  556. Value = (Value >> 16) | 0x400;
  557. else if (Value > 0xffffff)
  558. Value = (Value >> 24) | 0x600;
  559. return Value;
  560. }
  561. //===--------------------------------------------------------------------===//
  562. // Floating-point Immediates
  563. //
  564. inline float getFPImmFloat(unsigned Imm) {
  565. // We expect an 8-bit binary encoding of a floating-point number here.
  566. uint8_t Sign = (Imm >> 7) & 0x1;
  567. uint8_t Exp = (Imm >> 4) & 0x7;
  568. uint8_t Mantissa = Imm & 0xf;
  569. // 8-bit FP IEEE Float Encoding
  570. // abcd efgh aBbbbbbc defgh000 00000000 00000000
  571. //
  572. // where B = NOT(b);
  573. uint32_t I = 0;
  574. I |= Sign << 31;
  575. I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
  576. I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
  577. I |= (Exp & 0x3) << 23;
  578. I |= Mantissa << 19;
  579. return bit_cast<float>(I);
  580. }
  581. /// getFP16Imm - Return an 8-bit floating-point version of the 16-bit
  582. /// floating-point value. If the value cannot be represented as an 8-bit
  583. /// floating-point value, then return -1.
  584. inline int getFP16Imm(const APInt &Imm) {
  585. uint32_t Sign = Imm.lshr(15).getZExtValue() & 1;
  586. int32_t Exp = (Imm.lshr(10).getSExtValue() & 0x1f) - 15; // -14 to 15
  587. int64_t Mantissa = Imm.getZExtValue() & 0x3ff; // 10 bits
  588. // We can handle 4 bits of mantissa.
  589. // mantissa = (16+UInt(e:f:g:h))/16.
  590. if (Mantissa & 0x3f)
  591. return -1;
  592. Mantissa >>= 6;
  593. // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3
  594. if (Exp < -3 || Exp > 4)
  595. return -1;
  596. Exp = ((Exp+3) & 0x7) ^ 4;
  597. return ((int)Sign << 7) | (Exp << 4) | Mantissa;
  598. }
  599. inline int getFP16Imm(const APFloat &FPImm) {
  600. return getFP16Imm(FPImm.bitcastToAPInt());
  601. }
  602. /// If this is a FP16Imm encoded as a fp32 value, return the 8-bit encoding
  603. /// for it. Otherwise return -1 like getFP16Imm.
  604. inline int getFP32FP16Imm(const APInt &Imm) {
  605. if (Imm.getActiveBits() > 16)
  606. return -1;
  607. return ARM_AM::getFP16Imm(Imm.trunc(16));
  608. }
  609. inline int getFP32FP16Imm(const APFloat &FPImm) {
  610. return getFP32FP16Imm(FPImm.bitcastToAPInt());
  611. }
  612. /// getFP32Imm - Return an 8-bit floating-point version of the 32-bit
  613. /// floating-point value. If the value cannot be represented as an 8-bit
  614. /// floating-point value, then return -1.
  615. inline int getFP32Imm(const APInt &Imm) {
  616. uint32_t Sign = Imm.lshr(31).getZExtValue() & 1;
  617. int32_t Exp = (Imm.lshr(23).getSExtValue() & 0xff) - 127; // -126 to 127
  618. int64_t Mantissa = Imm.getZExtValue() & 0x7fffff; // 23 bits
  619. // We can handle 4 bits of mantissa.
  620. // mantissa = (16+UInt(e:f:g:h))/16.
  621. if (Mantissa & 0x7ffff)
  622. return -1;
  623. Mantissa >>= 19;
  624. if ((Mantissa & 0xf) != Mantissa)
  625. return -1;
  626. // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3
  627. if (Exp < -3 || Exp > 4)
  628. return -1;
  629. Exp = ((Exp+3) & 0x7) ^ 4;
  630. return ((int)Sign << 7) | (Exp << 4) | Mantissa;
  631. }
  632. inline int getFP32Imm(const APFloat &FPImm) {
  633. return getFP32Imm(FPImm.bitcastToAPInt());
  634. }
  635. /// getFP64Imm - Return an 8-bit floating-point version of the 64-bit
  636. /// floating-point value. If the value cannot be represented as an 8-bit
  637. /// floating-point value, then return -1.
  638. inline int getFP64Imm(const APInt &Imm) {
  639. uint64_t Sign = Imm.lshr(63).getZExtValue() & 1;
  640. int64_t Exp = (Imm.lshr(52).getSExtValue() & 0x7ff) - 1023; // -1022 to 1023
  641. uint64_t Mantissa = Imm.getZExtValue() & 0xfffffffffffffULL;
  642. // We can handle 4 bits of mantissa.
  643. // mantissa = (16+UInt(e:f:g:h))/16.
  644. if (Mantissa & 0xffffffffffffULL)
  645. return -1;
  646. Mantissa >>= 48;
  647. if ((Mantissa & 0xf) != Mantissa)
  648. return -1;
  649. // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3
  650. if (Exp < -3 || Exp > 4)
  651. return -1;
  652. Exp = ((Exp+3) & 0x7) ^ 4;
  653. return ((int)Sign << 7) | (Exp << 4) | Mantissa;
  654. }
  655. inline int getFP64Imm(const APFloat &FPImm) {
  656. return getFP64Imm(FPImm.bitcastToAPInt());
  657. }
  658. } // end namespace ARM_AM
  659. } // end namespace llvm
  660. #endif