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