LCOV - code coverage report
Current view: top level - lib/Target/AArch64/MCTargetDesc - AArch64AddressingModes.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 297 302 98.3 %
Date: 2017-09-14 15:23:50 Functions: 20 20 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- AArch64AddressingModes.h - AArch64 Addressing Modes ------*- C++ -*-===//
       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             : //
      10             : // This file contains the AArch64 addressing mode implementation stuff.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64ADDRESSINGMODES_H
      15             : #define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64ADDRESSINGMODES_H
      16             : 
      17             : #include "llvm/ADT/APFloat.h"
      18             : #include "llvm/ADT/APInt.h"
      19             : #include "llvm/Support/ErrorHandling.h"
      20             : #include "llvm/Support/MathExtras.h"
      21             : #include <cassert>
      22             : 
      23             : namespace llvm {
      24             : 
      25             : /// AArch64_AM - AArch64 Addressing Mode Stuff
      26             : namespace AArch64_AM {
      27             : 
      28             : //===----------------------------------------------------------------------===//
      29             : // Shifts
      30             : //
      31             : 
      32             : enum ShiftExtendType {
      33             :   InvalidShiftExtend = -1,
      34             :   LSL = 0,
      35             :   LSR,
      36             :   ASR,
      37             :   ROR,
      38             :   MSL,
      39             : 
      40             :   UXTB,
      41             :   UXTH,
      42             :   UXTW,
      43             :   UXTX,
      44             : 
      45             :   SXTB,
      46             :   SXTH,
      47             :   SXTW,
      48             :   SXTX,
      49             : };
      50             : 
      51             : /// getShiftName - Get the string encoding for the shift type.
      52        2064 : static inline const char *getShiftExtendName(AArch64_AM::ShiftExtendType ST) {
      53        2064 :   switch (ST) {
      54           0 :   default: llvm_unreachable("unhandled shift type!");
      55             :   case AArch64_AM::LSL: return "lsl";
      56         283 :   case AArch64_AM::LSR: return "lsr";
      57         319 :   case AArch64_AM::ASR: return "asr";
      58          48 :   case AArch64_AM::ROR: return "ror";
      59          53 :   case AArch64_AM::MSL: return "msl";
      60          49 :   case AArch64_AM::UXTB: return "uxtb";
      61          50 :   case AArch64_AM::UXTH: return "uxth";
      62          64 :   case AArch64_AM::UXTW: return "uxtw";
      63          27 :   case AArch64_AM::UXTX: return "uxtx";
      64          47 :   case AArch64_AM::SXTB: return "sxtb";
      65          56 :   case AArch64_AM::SXTH: return "sxth";
      66          81 :   case AArch64_AM::SXTW: return "sxtw";
      67          23 :   case AArch64_AM::SXTX: return "sxtx";
      68             :   }
      69             :   return nullptr;
      70             : }
      71             : 
      72             : /// getShiftType - Extract the shift type.
      73             : static inline AArch64_AM::ShiftExtendType getShiftType(unsigned Imm) {
      74        3165 :   switch ((Imm >> 6) & 0x7) {
      75             :   default: return AArch64_AM::InvalidShiftExtend;
      76             :   case 0: return AArch64_AM::LSL;
      77             :   case 1: return AArch64_AM::LSR;
      78             :   case 2: return AArch64_AM::ASR;
      79             :   case 3: return AArch64_AM::ROR;
      80             :   case 4: return AArch64_AM::MSL;
      81             :   }
      82             : }
      83             : 
      84             : /// getShiftValue - Extract the shift value.
      85             : static inline unsigned getShiftValue(unsigned Imm) {
      86        9079 :   return Imm & 0x3f;
      87             : }
      88             : 
      89             : /// getShifterImm - Encode the shift type and amount:
      90             : ///   imm:     6-bit shift amount
      91             : ///   shifter: 000 ==> lsl
      92             : ///            001 ==> lsr
      93             : ///            010 ==> asr
      94             : ///            011 ==> ror
      95             : ///            100 ==> msl
      96             : ///   {8-6}  = shifter
      97             : ///   {5-0}  = imm
      98             : static inline unsigned getShifterImm(AArch64_AM::ShiftExtendType ST,
      99             :                                      unsigned Imm) {
     100             :   assert((Imm & 0x3f) == Imm && "Illegal shifted immedate value!");
     101        7488 :   unsigned STEnc = 0;
     102         625 :   switch (ST) {
     103           0 :   default:  llvm_unreachable("Invalid shift requested");
     104             :   case AArch64_AM::LSL: STEnc = 0; break;
     105         114 :   case AArch64_AM::LSR: STEnc = 1; break;
     106         133 :   case AArch64_AM::ASR: STEnc = 2; break;
     107          23 :   case AArch64_AM::ROR: STEnc = 3; break;
     108          16 :   case AArch64_AM::MSL: STEnc = 4; break;
     109             :   }
     110        1228 :   return (STEnc << 6) | (Imm & 0x3f);
     111             : }
     112             : 
     113             : //===----------------------------------------------------------------------===//
     114             : // Extends
     115             : //
     116             : 
     117             : /// getArithShiftValue - get the arithmetic shift value.
     118             : static inline unsigned getArithShiftValue(unsigned Imm) {
     119         432 :   return Imm & 0x7;
     120             : }
     121             : 
     122             : /// getExtendType - Extract the extend type for operands of arithmetic ops.
     123         985 : static inline AArch64_AM::ShiftExtendType getExtendType(unsigned Imm) {
     124             :   assert((Imm & 0x7) == Imm && "invalid immediate!");
     125         985 :   switch (Imm) {
     126           0 :   default: llvm_unreachable("Compiler bug!");
     127             :   case 0: return AArch64_AM::UXTB;
     128          50 :   case 1: return AArch64_AM::UXTH;
     129          95 :   case 2: return AArch64_AM::UXTW;
     130          31 :   case 3: return AArch64_AM::UXTX;
     131          47 :   case 4: return AArch64_AM::SXTB;
     132          56 :   case 5: return AArch64_AM::SXTH;
     133          81 :   case 6: return AArch64_AM::SXTW;
     134          23 :   case 7: return AArch64_AM::SXTX;
     135             :   }
     136             : }
     137             : 
     138             : static inline AArch64_AM::ShiftExtendType getArithExtendType(unsigned Imm) {
     139         432 :   return getExtendType((Imm >> 3) & 0x7);
     140             : }
     141             : 
     142             : /// Mapping from extend bits to required operation:
     143             : ///   shifter: 000 ==> uxtb
     144             : ///            001 ==> uxth
     145             : ///            010 ==> uxtw
     146             : ///            011 ==> uxtx
     147             : ///            100 ==> sxtb
     148             : ///            101 ==> sxth
     149             : ///            110 ==> sxtw
     150             : ///            111 ==> sxtx
     151         376 : inline unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET) {
     152         376 :   switch (ET) {
     153           0 :   default: llvm_unreachable("Invalid extend type requested");
     154             :   case AArch64_AM::UXTB: return 0; break;
     155          43 :   case AArch64_AM::UXTH: return 1; break;
     156          66 :   case AArch64_AM::UXTW: return 2; break;
     157          30 :   case AArch64_AM::UXTX: return 3; break;
     158          43 :   case AArch64_AM::SXTB: return 4; break;
     159          52 :   case AArch64_AM::SXTH: return 5; break;
     160          82 :   case AArch64_AM::SXTW: return 6; break;
     161          19 :   case AArch64_AM::SXTX: return 7; break;
     162             :   }
     163             : }
     164             : 
     165             : /// getArithExtendImm - Encode the extend type and shift amount for an
     166             : ///                     arithmetic instruction:
     167             : ///   imm:     3-bit extend amount
     168             : ///   {5-3}  = shifter
     169             : ///   {2-0}  = imm3
     170             : static inline unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET,
     171             :                                          unsigned Imm) {
     172             :   assert((Imm & 0x7) == Imm && "Illegal shifted immedate value!");
     173         376 :   return (getExtendEncoding(ET) << 3) | (Imm & 0x7);
     174             : }
     175             : 
     176             : /// getMemDoShift - Extract the "do shift" flag value for load/store
     177             : /// instructions.
     178             : static inline bool getMemDoShift(unsigned Imm) {
     179           0 :   return (Imm & 0x1) != 0;
     180             : }
     181             : 
     182             : /// getExtendType - Extract the extend type for the offset operand of
     183             : /// loads/stores.
     184             : static inline AArch64_AM::ShiftExtendType getMemExtendType(unsigned Imm) {
     185         553 :   return getExtendType((Imm >> 1) & 0x7);
     186             : }
     187             : 
     188             : /// getExtendImm - Encode the extend type and amount for a load/store inst:
     189             : ///   doshift:     should the offset be scaled by the access size
     190             : ///   shifter: 000 ==> uxtb
     191             : ///            001 ==> uxth
     192             : ///            010 ==> uxtw
     193             : ///            011 ==> uxtx
     194             : ///            100 ==> sxtb
     195             : ///            101 ==> sxth
     196             : ///            110 ==> sxtw
     197             : ///            111 ==> sxtx
     198             : ///   {3-1}  = shifter
     199             : ///   {0}  = doshift
     200             : static inline unsigned getMemExtendImm(AArch64_AM::ShiftExtendType ET,
     201             :                                        bool DoShift) {
     202             :   return (getExtendEncoding(ET) << 1) | unsigned(DoShift);
     203             : }
     204             : 
     205             : static inline uint64_t ror(uint64_t elt, unsigned size) {
     206       34620 :   return ((elt & 1) << (size-1)) | (elt >> 1);
     207             : }
     208             : 
     209             : /// processLogicalImmediate - Determine if an immediate value can be encoded
     210             : /// as the immediate operand of a logical instruction for the given register
     211             : /// size.  If so, return true with "encoding" set to the encoded value in
     212             : /// the form N:immr:imms.
     213        5741 : static inline bool processLogicalImmediate(uint64_t Imm, unsigned RegSize,
     214             :                                            uint64_t &Encoding) {
     215        5741 :   if (Imm == 0ULL || Imm == ~0ULL ||
     216        2578 :       (RegSize != 64 && (Imm >> RegSize != 0 || Imm == ~0U)))
     217             :     return false;
     218             : 
     219             :   // First, determine the element size.
     220             :   unsigned Size = RegSize;
     221             : 
     222             :   do {
     223        5990 :     Size /= 2;
     224        5990 :     uint64_t Mask = (1ULL << Size) - 1;
     225             : 
     226        5990 :     if ((Imm & Mask) != ((Imm >> Size) & Mask)) {
     227        5284 :       Size *= 2;
     228        5284 :       break;
     229             :     }
     230         706 :   } while (Size > 2);
     231             : 
     232             :   // Second, determine the rotation to make the element be: 0^m 1^n.
     233             :   uint32_t CTO, I;
     234        5335 :   uint64_t Mask = ((uint64_t)-1LL) >> (64 - Size);
     235        5335 :   Imm &= Mask;
     236             : 
     237        4082 :   if (isShiftedMask_64(Imm)) {
     238        4082 :     I = countTrailingZeros(Imm);
     239             :     assert(I < 64 && "undefined behavior");
     240        8164 :     CTO = countTrailingOnes(Imm >> I);
     241             :   } else {
     242        1253 :     Imm |= ~Mask;
     243        1433 :     if (!isShiftedMask_64(~Imm))
     244             :       return false;
     245             : 
     246         180 :     unsigned CLO = countLeadingOnes(Imm);
     247         180 :     I = 64 - CLO;
     248         180 :     CTO = CLO + countTrailingOnes(Imm) - (64 - Size);
     249             :   }
     250             : 
     251             :   // Encode in Immr the number of RORs it would take to get *from* 0^m 1^n
     252             :   // to our target value, where I is the number of RORs to go the opposite
     253             :   // direction.
     254             :   assert(Size > I && "I should be smaller than element size");
     255        4262 :   unsigned Immr = (Size - I) & (Size - 1);
     256             : 
     257             :   // If size has a 1 in the n'th bit, create a value that has zeroes in
     258             :   // bits [0, n] and ones above that.
     259        4262 :   uint64_t NImms = ~(Size-1) << 1;
     260             : 
     261             :   // Or the CTO value into the low bits, which must be below the Nth bit
     262             :   // bit mentioned above.
     263        4262 :   NImms |= (CTO-1);
     264             : 
     265             :   // Extract the seventh bit and toggle it to create the N field.
     266        4262 :   unsigned N = ((NImms >> 6) & 1) ^ 1;
     267             : 
     268        4262 :   Encoding = (N << 12) | (Immr << 6) | (NImms & 0x3f);
     269        4262 :   return true;
     270             : }
     271             : 
     272             : /// isLogicalImmediate - Return true if the immediate is valid for a logical
     273             : /// immediate instruction of the given register size. Return false otherwise.
     274             : static inline bool isLogicalImmediate(uint64_t imm, unsigned regSize) {
     275             :   uint64_t encoding;
     276        3648 :   return processLogicalImmediate(imm, regSize, encoding);
     277             : }
     278             : 
     279             : /// encodeLogicalImmediate - Return the encoded immediate value for a logical
     280             : /// immediate instruction of the given register size.
     281             : static inline uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize) {
     282         593 :   uint64_t encoding = 0;
     283         593 :   bool res = processLogicalImmediate(imm, regSize, encoding);
     284             :   assert(res && "invalid logical immediate");
     285             :   (void)res;
     286         593 :   return encoding;
     287             : }
     288             : 
     289             : /// decodeLogicalImmediate - Decode a logical immediate value in the form
     290             : /// "N:immr:imms" (where the immr and imms fields are each 6 bits) into the
     291             : /// integer value it represents with regSize bits.
     292        2604 : static inline uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize) {
     293             :   // Extract the N, imms, and immr fields.
     294        2604 :   unsigned N = (val >> 12) & 1;
     295        2604 :   unsigned immr = (val >> 6) & 0x3f;
     296        2604 :   unsigned imms = val & 0x3f;
     297             : 
     298             :   assert((regSize == 64 || N == 0) && "undefined logical immediate encoding");
     299        5208 :   int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f));
     300             :   assert(len >= 0 && "undefined logical immediate encoding");
     301        2604 :   unsigned size = (1 << len);
     302        2604 :   unsigned R = immr & (size - 1);
     303        2604 :   unsigned S = imms & (size - 1);
     304             :   assert(S != size - 1 && "undefined logical immediate encoding");
     305        2604 :   uint64_t pattern = (1ULL << (S + 1)) - 1;
     306       37224 :   for (unsigned i = 0; i < R; ++i)
     307       34620 :     pattern = ror(pattern, size);
     308             : 
     309             :   // Replicate the pattern to fill the regSize.
     310        3610 :   while (size != regSize) {
     311         503 :     pattern |= (pattern << size);
     312         503 :     size *= 2;
     313             :   }
     314        2604 :   return pattern;
     315             : }
     316             : 
     317             : /// isValidDecodeLogicalImmediate - Check to see if the logical immediate value
     318             : /// in the form "N:immr:imms" (where the immr and imms fields are each 6 bits)
     319             : /// is a valid encoding for an integer value with regSize bits.
     320         130 : static inline bool isValidDecodeLogicalImmediate(uint64_t val,
     321             :                                                  unsigned regSize) {
     322             :   // Extract the N and imms fields needed for checking.
     323         130 :   unsigned N = (val >> 12) & 1;
     324         130 :   unsigned imms = val & 0x3f;
     325             : 
     326         130 :   if (regSize == 32 && N != 0) // undefined logical immediate encoding
     327             :     return false;
     328         260 :   int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f));
     329         130 :   if (len < 0) // undefined logical immediate encoding
     330             :     return false;
     331         130 :   unsigned size = (1 << len);
     332         130 :   unsigned S = imms & (size - 1);
     333         130 :   if (S == size - 1) // undefined logical immediate encoding
     334             :     return false;
     335             : 
     336         129 :   return true;
     337             : }
     338             : 
     339             : //===----------------------------------------------------------------------===//
     340             : // Floating-point Immediates
     341             : //
     342         227 : static inline float getFPImmFloat(unsigned Imm) {
     343             :   // We expect an 8-bit binary encoding of a floating-point number here.
     344             :   union {
     345             :     uint32_t I;
     346             :     float F;
     347             :   } FPUnion;
     348             : 
     349         227 :   uint8_t Sign = (Imm >> 7) & 0x1;
     350         227 :   uint8_t Exp = (Imm >> 4) & 0x7;
     351         227 :   uint8_t Mantissa = Imm & 0xf;
     352             : 
     353             :   //   8-bit FP    iEEEE Float Encoding
     354             :   //   abcd efgh   aBbbbbbc defgh000 00000000 00000000
     355             :   //
     356             :   // where B = NOT(b);
     357             : 
     358         227 :   FPUnion.I = 0;
     359         227 :   FPUnion.I |= Sign << 31;
     360         227 :   FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
     361         227 :   FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
     362         227 :   FPUnion.I |= (Exp & 0x3) << 23;
     363         227 :   FPUnion.I |= Mantissa << 19;
     364         227 :   return FPUnion.F;
     365             : }
     366             : 
     367             : /// getFP16Imm - Return an 8-bit floating-point version of the 16-bit
     368             : /// floating-point value. If the value cannot be represented as an 8-bit
     369             : /// floating-point value, then return -1.
     370          38 : static inline int getFP16Imm(const APInt &Imm) {
     371         114 :   uint32_t Sign = Imm.lshr(15).getZExtValue() & 1;
     372         114 :   int32_t Exp = (Imm.lshr(10).getSExtValue() & 0x1f) - 15;  // -14 to 15
     373          38 :   int32_t Mantissa = Imm.getZExtValue() & 0x3ff;  // 10 bits
     374             : 
     375             :   // We can handle 4 bits of mantissa.
     376             :   // mantissa = (16+UInt(e:f:g:h))/16.
     377          38 :   if (Mantissa & 0x3f)
     378             :     return -1;
     379          34 :   Mantissa >>= 6;
     380             : 
     381             :   // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3
     382          34 :   if (Exp < -3 || Exp > 4)
     383             :     return -1;
     384          32 :   Exp = ((Exp+3) & 0x7) ^ 4;
     385             : 
     386          32 :   return ((int)Sign << 7) | (Exp << 4) | Mantissa;
     387             : }
     388             : 
     389          38 : static inline int getFP16Imm(const APFloat &FPImm) {
     390          76 :   return getFP16Imm(FPImm.bitcastToAPInt());
     391             : }
     392             : 
     393             : /// getFP32Imm - Return an 8-bit floating-point version of the 32-bit
     394             : /// floating-point value. If the value cannot be represented as an 8-bit
     395             : /// floating-point value, then return -1.
     396         377 : static inline int getFP32Imm(const APInt &Imm) {
     397        1131 :   uint32_t Sign = Imm.lshr(31).getZExtValue() & 1;
     398        1131 :   int32_t Exp = (Imm.lshr(23).getSExtValue() & 0xff) - 127;  // -126 to 127
     399         377 :   int64_t Mantissa = Imm.getZExtValue() & 0x7fffff;  // 23 bits
     400             : 
     401             :   // We can handle 4 bits of mantissa.
     402             :   // mantissa = (16+UInt(e:f:g:h))/16.
     403         377 :   if (Mantissa & 0x7ffff)
     404             :     return -1;
     405         368 :   Mantissa >>= 19;
     406             :   if ((Mantissa & 0xf) != Mantissa)
     407             :     return -1;
     408             : 
     409             :   // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3
     410         368 :   if (Exp < -3 || Exp > 4)
     411             :     return -1;
     412         337 :   Exp = ((Exp+3) & 0x7) ^ 4;
     413             : 
     414         337 :   return ((int)Sign << 7) | (Exp << 4) | Mantissa;
     415             : }
     416             : 
     417         377 : static inline int getFP32Imm(const APFloat &FPImm) {
     418         754 :   return getFP32Imm(FPImm.bitcastToAPInt());
     419             : }
     420             : 
     421             : /// getFP64Imm - Return an 8-bit floating-point version of the 64-bit
     422             : /// floating-point value. If the value cannot be represented as an 8-bit
     423             : /// floating-point value, then return -1.
     424         222 : static inline int getFP64Imm(const APInt &Imm) {
     425         666 :   uint64_t Sign = Imm.lshr(63).getZExtValue() & 1;
     426         666 :   int64_t Exp = (Imm.lshr(52).getSExtValue() & 0x7ff) - 1023;   // -1022 to 1023
     427         222 :   uint64_t Mantissa = Imm.getZExtValue() & 0xfffffffffffffULL;
     428             : 
     429             :   // We can handle 4 bits of mantissa.
     430             :   // mantissa = (16+UInt(e:f:g:h))/16.
     431         222 :   if (Mantissa & 0xffffffffffffULL)
     432             :     return -1;
     433         204 :   Mantissa >>= 48;
     434             :   if ((Mantissa & 0xf) != Mantissa)
     435             :     return -1;
     436             : 
     437             :   // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3
     438         204 :   if (Exp < -3 || Exp > 4)
     439             :     return -1;
     440         162 :   Exp = ((Exp+3) & 0x7) ^ 4;
     441             : 
     442         162 :   return ((int)Sign << 7) | (Exp << 4) | Mantissa;
     443             : }
     444             : 
     445         179 : static inline int getFP64Imm(const APFloat &FPImm) {
     446         358 :   return getFP64Imm(FPImm.bitcastToAPInt());
     447             : }
     448             : 
     449             : //===--------------------------------------------------------------------===//
     450             : // AdvSIMD Modified Immediates
     451             : //===--------------------------------------------------------------------===//
     452             : 
     453             : // 0x00 0x00 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh
     454             : static inline bool isAdvSIMDModImmType1(uint64_t Imm) {
     455        1149 :   return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
     456         514 :          ((Imm & 0xffffff00ffffff00ULL) == 0);
     457             : }
     458             : 
     459             : static inline uint8_t encodeAdvSIMDModImmType1(uint64_t Imm) {
     460             :   return (Imm & 0xffULL);
     461             : }
     462             : 
     463             : static inline uint64_t decodeAdvSIMDModImmType1(uint8_t Imm) {
     464             :   uint64_t EncVal = Imm;
     465             :   return (EncVal << 32) | EncVal;
     466             : }
     467             : 
     468             : // 0x00 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 0x00
     469             : static inline bool isAdvSIMDModImmType2(uint64_t Imm) {
     470        1053 :   return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
     471         466 :          ((Imm & 0xffff00ffffff00ffULL) == 0);
     472             : }
     473             : 
     474             : static inline uint8_t encodeAdvSIMDModImmType2(uint64_t Imm) {
     475          31 :   return (Imm & 0xff00ULL) >> 8;
     476             : }
     477             : 
     478             : static inline uint64_t decodeAdvSIMDModImmType2(uint8_t Imm) {
     479             :   uint64_t EncVal = Imm;
     480             :   return (EncVal << 40) | (EncVal << 8);
     481             : }
     482             : 
     483             : // 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 0x00
     484             : static inline bool isAdvSIMDModImmType3(uint64_t Imm) {
     485         991 :   return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
     486         435 :          ((Imm & 0xff00ffffff00ffffULL) == 0);
     487             : }
     488             : 
     489             : static inline uint8_t encodeAdvSIMDModImmType3(uint64_t Imm) {
     490          33 :   return (Imm & 0xff0000ULL) >> 16;
     491             : }
     492             : 
     493             : static inline uint64_t decodeAdvSIMDModImmType3(uint8_t Imm) {
     494             :   uint64_t EncVal = Imm;
     495             :   return (EncVal << 48) | (EncVal << 16);
     496             : }
     497             : 
     498             : // abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 0x00 0x00
     499             : static inline bool isAdvSIMDModImmType4(uint64_t Imm) {
     500         925 :   return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
     501         402 :          ((Imm & 0x00ffffff00ffffffULL) == 0);
     502             : }
     503             : 
     504             : static inline uint8_t encodeAdvSIMDModImmType4(uint64_t Imm) {
     505          50 :   return (Imm & 0xff000000ULL) >> 24;
     506             : }
     507             : 
     508             : static inline uint64_t decodeAdvSIMDModImmType4(uint8_t Imm) {
     509             :   uint64_t EncVal = Imm;
     510             :   return (EncVal << 56) | (EncVal << 24);
     511             : }
     512             : 
     513             : // 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh
     514             : static inline bool isAdvSIMDModImmType5(uint64_t Imm) {
     515         352 :   return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
     516        1048 :          (((Imm & 0x00ff0000ULL) >> 16) == (Imm & 0x000000ffULL)) &&
     517         223 :          ((Imm & 0xff00ff00ff00ff00ULL) == 0);
     518             : }
     519             : 
     520             : static inline uint8_t encodeAdvSIMDModImmType5(uint64_t Imm) {
     521             :   return (Imm & 0xffULL);
     522             : }
     523             : 
     524             : static inline uint64_t decodeAdvSIMDModImmType5(uint8_t Imm) {
     525             :   uint64_t EncVal = Imm;
     526             :   return (EncVal << 48) | (EncVal << 32) | (EncVal << 16) | EncVal;
     527             : }
     528             : 
     529             : // abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00
     530             : static inline bool isAdvSIMDModImmType6(uint64_t Imm) {
     531         301 :   return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
     532         927 :          (((Imm & 0xff000000ULL) >> 16) == (Imm & 0x0000ff00ULL)) &&
     533         204 :          ((Imm & 0x00ff00ff00ff00ffULL) == 0);
     534             : }
     535             : 
     536             : static inline uint8_t encodeAdvSIMDModImmType6(uint64_t Imm) {
     537          46 :   return (Imm & 0xff00ULL) >> 8;
     538             : }
     539             : 
     540             : static inline uint64_t decodeAdvSIMDModImmType6(uint8_t Imm) {
     541             :   uint64_t EncVal = Imm;
     542             :   return (EncVal << 56) | (EncVal << 40) | (EncVal << 24) | (EncVal << 8);
     543             : }
     544             : 
     545             : // 0x00 0x00 abcdefgh 0xFF 0x00 0x00 abcdefgh 0xFF
     546             : static inline bool isAdvSIMDModImmType7(uint64_t Imm) {
     547         399 :   return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
     548         147 :          ((Imm & 0xffff00ffffff00ffULL) == 0x000000ff000000ffULL);
     549             : }
     550             : 
     551             : static inline uint8_t encodeAdvSIMDModImmType7(uint64_t Imm) {
     552          15 :   return (Imm & 0xff00ULL) >> 8;
     553             : }
     554             : 
     555             : static inline uint64_t decodeAdvSIMDModImmType7(uint8_t Imm) {
     556             :   uint64_t EncVal = Imm;
     557             :   return (EncVal << 40) | (EncVal << 8) | 0x000000ff000000ffULL;
     558             : }
     559             : 
     560             : // 0x00 abcdefgh 0xFF 0xFF 0x00 abcdefgh 0xFF 0xFF
     561             : static inline bool isAdvSIMDModImmType8(uint64_t Imm) {
     562         369 :   return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
     563         132 :          ((Imm & 0xff00ffffff00ffffULL) == 0x0000ffff0000ffffULL);
     564             : }
     565             : 
     566             : static inline uint64_t decodeAdvSIMDModImmType8(uint8_t Imm) {
     567             :   uint64_t EncVal = Imm;
     568             :   return (EncVal << 48) | (EncVal << 16) | 0x0000ffff0000ffffULL;
     569             : }
     570             : 
     571             : static inline uint8_t encodeAdvSIMDModImmType8(uint64_t Imm) {
     572          14 :   return (Imm & 0x00ff0000ULL) >> 16;
     573             : }
     574             : 
     575             : // abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
     576             : static inline bool isAdvSIMDModImmType9(uint64_t Imm) {
     577          98 :   return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
     578         307 :          ((Imm >> 48) == (Imm & 0x0000ffffULL)) &&
     579          52 :          ((Imm >> 56) == (Imm & 0x000000ffULL));
     580             : }
     581             : 
     582             : static inline uint8_t encodeAdvSIMDModImmType9(uint64_t Imm) {
     583             :   return (Imm & 0xffULL);
     584             : }
     585             : 
     586             : static inline uint64_t decodeAdvSIMDModImmType9(uint8_t Imm) {
     587             :   uint64_t EncVal = Imm;
     588             :   EncVal |= (EncVal << 8);
     589             :   EncVal |= (EncVal << 16);
     590             :   EncVal |= (EncVal << 32);
     591             :   return EncVal;
     592             : }
     593             : 
     594             : // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
     595             : // cmode: 1110, op: 1
     596         355 : static inline bool isAdvSIMDModImmType10(uint64_t Imm) {
     597         355 :   uint64_t ByteA = Imm & 0xff00000000000000ULL;
     598         355 :   uint64_t ByteB = Imm & 0x00ff000000000000ULL;
     599         355 :   uint64_t ByteC = Imm & 0x0000ff0000000000ULL;
     600         355 :   uint64_t ByteD = Imm & 0x000000ff00000000ULL;
     601         355 :   uint64_t ByteE = Imm & 0x00000000ff000000ULL;
     602         355 :   uint64_t ByteF = Imm & 0x0000000000ff0000ULL;
     603         355 :   uint64_t ByteG = Imm & 0x000000000000ff00ULL;
     604         355 :   uint64_t ByteH = Imm & 0x00000000000000ffULL;
     605             : 
     606         557 :   return (ByteA == 0ULL || ByteA == 0xff00000000000000ULL) &&
     607         342 :          (ByteB == 0ULL || ByteB == 0x00ff000000000000ULL) &&
     608         248 :          (ByteC == 0ULL || ByteC == 0x0000ff0000000000ULL) &&
     609         184 :          (ByteD == 0ULL || ByteD == 0x000000ff00000000ULL) &&
     610         150 :          (ByteE == 0ULL || ByteE == 0x00000000ff000000ULL) &&
     611         147 :          (ByteF == 0ULL || ByteF == 0x0000000000ff0000ULL) &&
     612         499 :          (ByteG == 0ULL || ByteG == 0x000000000000ff00ULL) &&
     613         426 :          (ByteH == 0ULL || ByteH == 0x00000000000000ffULL);
     614             : }
     615             : 
     616          59 : static inline uint8_t encodeAdvSIMDModImmType10(uint64_t Imm) {
     617          59 :   uint8_t BitA = (Imm & 0xff00000000000000ULL) != 0;
     618          59 :   uint8_t BitB = (Imm & 0x00ff000000000000ULL) != 0;
     619          59 :   uint8_t BitC = (Imm & 0x0000ff0000000000ULL) != 0;
     620          59 :   uint8_t BitD = (Imm & 0x000000ff00000000ULL) != 0;
     621          59 :   uint8_t BitE = (Imm & 0x00000000ff000000ULL) != 0;
     622          59 :   uint8_t BitF = (Imm & 0x0000000000ff0000ULL) != 0;
     623          59 :   uint8_t BitG = (Imm & 0x000000000000ff00ULL) != 0;
     624          59 :   uint8_t BitH = (Imm & 0x00000000000000ffULL) != 0;
     625             : 
     626          59 :   uint8_t EncVal = BitA;
     627          59 :   EncVal <<= 1;
     628          59 :   EncVal |= BitB;
     629          59 :   EncVal <<= 1;
     630          59 :   EncVal |= BitC;
     631          59 :   EncVal <<= 1;
     632          59 :   EncVal |= BitD;
     633          59 :   EncVal <<= 1;
     634          59 :   EncVal |= BitE;
     635          59 :   EncVal <<= 1;
     636          59 :   EncVal |= BitF;
     637          59 :   EncVal <<= 1;
     638          59 :   EncVal |= BitG;
     639          59 :   EncVal <<= 1;
     640          59 :   EncVal |= BitH;
     641          59 :   return EncVal;
     642             : }
     643             : 
     644         215 : static inline uint64_t decodeAdvSIMDModImmType10(uint8_t Imm) {
     645         215 :   uint64_t EncVal = 0;
     646         215 :   if (Imm & 0x80) EncVal |= 0xff00000000000000ULL;
     647         215 :   if (Imm & 0x40) EncVal |= 0x00ff000000000000ULL;
     648         215 :   if (Imm & 0x20) EncVal |= 0x0000ff0000000000ULL;
     649         215 :   if (Imm & 0x10) EncVal |= 0x000000ff00000000ULL;
     650         215 :   if (Imm & 0x08) EncVal |= 0x00000000ff000000ULL;
     651         215 :   if (Imm & 0x04) EncVal |= 0x0000000000ff0000ULL;
     652         215 :   if (Imm & 0x02) EncVal |= 0x000000000000ff00ULL;
     653         215 :   if (Imm & 0x01) EncVal |= 0x00000000000000ffULL;
     654         215 :   return EncVal;
     655             : }
     656             : 
     657             : // aBbbbbbc defgh000 0x00 0x00 aBbbbbbc defgh000 0x00 0x00
     658             : static inline bool isAdvSIMDModImmType11(uint64_t Imm) {
     659         129 :   uint64_t BString = (Imm & 0x7E000000ULL) >> 25;
     660          70 :   return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
     661         222 :          (BString == 0x1f || BString == 0x20) &&
     662          23 :          ((Imm & 0x0007ffff0007ffffULL) == 0);
     663             : }
     664             : 
     665          23 : static inline uint8_t encodeAdvSIMDModImmType11(uint64_t Imm) {
     666          23 :   uint8_t BitA = (Imm & 0x80000000ULL) != 0;
     667          23 :   uint8_t BitB = (Imm & 0x20000000ULL) != 0;
     668          23 :   uint8_t BitC = (Imm & 0x01000000ULL) != 0;
     669          23 :   uint8_t BitD = (Imm & 0x00800000ULL) != 0;
     670          23 :   uint8_t BitE = (Imm & 0x00400000ULL) != 0;
     671          23 :   uint8_t BitF = (Imm & 0x00200000ULL) != 0;
     672          23 :   uint8_t BitG = (Imm & 0x00100000ULL) != 0;
     673          23 :   uint8_t BitH = (Imm & 0x00080000ULL) != 0;
     674             : 
     675          23 :   uint8_t EncVal = BitA;
     676          23 :   EncVal <<= 1;
     677          23 :   EncVal |= BitB;
     678          23 :   EncVal <<= 1;
     679          23 :   EncVal |= BitC;
     680          23 :   EncVal <<= 1;
     681          23 :   EncVal |= BitD;
     682          23 :   EncVal <<= 1;
     683          23 :   EncVal |= BitE;
     684          23 :   EncVal <<= 1;
     685          23 :   EncVal |= BitF;
     686          23 :   EncVal <<= 1;
     687          23 :   EncVal |= BitG;
     688          23 :   EncVal <<= 1;
     689          23 :   EncVal |= BitH;
     690          23 :   return EncVal;
     691             : }
     692             : 
     693             : static inline uint64_t decodeAdvSIMDModImmType11(uint8_t Imm) {
     694             :   uint64_t EncVal = 0;
     695             :   if (Imm & 0x80) EncVal |= 0x80000000ULL;
     696             :   if (Imm & 0x40) EncVal |= 0x3e000000ULL;
     697             :   else            EncVal |= 0x40000000ULL;
     698             :   if (Imm & 0x20) EncVal |= 0x01000000ULL;
     699             :   if (Imm & 0x10) EncVal |= 0x00800000ULL;
     700             :   if (Imm & 0x08) EncVal |= 0x00400000ULL;
     701             :   if (Imm & 0x04) EncVal |= 0x00200000ULL;
     702             :   if (Imm & 0x02) EncVal |= 0x00100000ULL;
     703             :   if (Imm & 0x01) EncVal |= 0x00080000ULL;
     704             :   return (EncVal << 32) | EncVal;
     705             : }
     706             : 
     707             : // aBbbbbbb bbcdefgh 0x00 0x00 0x00 0x00 0x00 0x00
     708             : static inline bool isAdvSIMDModImmType12(uint64_t Imm) {
     709         106 :   uint64_t BString = (Imm & 0x7fc0000000000000ULL) >> 54;
     710         119 :   return ((BString == 0xff || BString == 0x100) &&
     711          13 :          ((Imm & 0x0000ffffffffffffULL) == 0));
     712             : }
     713             : 
     714          13 : static inline uint8_t encodeAdvSIMDModImmType12(uint64_t Imm) {
     715          13 :   uint8_t BitA = (Imm & 0x8000000000000000ULL) != 0;
     716          13 :   uint8_t BitB = (Imm & 0x0040000000000000ULL) != 0;
     717          13 :   uint8_t BitC = (Imm & 0x0020000000000000ULL) != 0;
     718          13 :   uint8_t BitD = (Imm & 0x0010000000000000ULL) != 0;
     719          13 :   uint8_t BitE = (Imm & 0x0008000000000000ULL) != 0;
     720          13 :   uint8_t BitF = (Imm & 0x0004000000000000ULL) != 0;
     721          13 :   uint8_t BitG = (Imm & 0x0002000000000000ULL) != 0;
     722          13 :   uint8_t BitH = (Imm & 0x0001000000000000ULL) != 0;
     723             : 
     724          13 :   uint8_t EncVal = BitA;
     725          13 :   EncVal <<= 1;
     726          13 :   EncVal |= BitB;
     727          13 :   EncVal <<= 1;
     728          13 :   EncVal |= BitC;
     729          13 :   EncVal <<= 1;
     730          13 :   EncVal |= BitD;
     731          13 :   EncVal <<= 1;
     732          13 :   EncVal |= BitE;
     733          13 :   EncVal <<= 1;
     734          13 :   EncVal |= BitF;
     735          13 :   EncVal <<= 1;
     736          13 :   EncVal |= BitG;
     737          13 :   EncVal <<= 1;
     738          13 :   EncVal |= BitH;
     739          13 :   return EncVal;
     740             : }
     741             : 
     742             : static inline uint64_t decodeAdvSIMDModImmType12(uint8_t Imm) {
     743             :   uint64_t EncVal = 0;
     744             :   if (Imm & 0x80) EncVal |= 0x8000000000000000ULL;
     745             :   if (Imm & 0x40) EncVal |= 0x3fc0000000000000ULL;
     746             :   else            EncVal |= 0x4000000000000000ULL;
     747             :   if (Imm & 0x20) EncVal |= 0x0020000000000000ULL;
     748             :   if (Imm & 0x10) EncVal |= 0x0010000000000000ULL;
     749             :   if (Imm & 0x08) EncVal |= 0x0008000000000000ULL;
     750             :   if (Imm & 0x04) EncVal |= 0x0004000000000000ULL;
     751             :   if (Imm & 0x02) EncVal |= 0x0002000000000000ULL;
     752             :   if (Imm & 0x01) EncVal |= 0x0001000000000000ULL;
     753             :   return (EncVal << 32) | EncVal;
     754             : }
     755             : 
     756             : inline static bool isAnyMOVZMovAlias(uint64_t Value, int RegWidth) {
     757        1776 :   for (int Shift = 0; Shift <= RegWidth - 16; Shift += 16)
     758        1559 :     if ((Value & ~(0xffffULL << Shift)) == 0)
     759             :       return true;
     760             : 
     761             :   return false;
     762             : }
     763             : 
     764             : inline static bool isMOVZMovAlias(uint64_t Value, int Shift, int RegWidth) {
     765          57 :   if (RegWidth == 32)
     766         499 :     Value &= 0xffffffffULL;
     767             : 
     768             :   // "lsl #0" takes precedence: in practice this only affects "#0, lsl #0".
     769         656 :   if (Value == 0 && Shift != 0)
     770             :     return false;
     771             : 
     772         655 :   return (Value & ~(0xffffULL << Shift)) == 0;
     773             : }
     774             : 
     775          59 : inline static bool isMOVNMovAlias(uint64_t Value, int Shift, int RegWidth) {
     776             :   // MOVZ takes precedence over MOVN.
     777          70 :   if (isAnyMOVZMovAlias(Value, RegWidth))
     778             :     return false;
     779             : 
     780          68 :   Value = ~Value;
     781          57 :   if (RegWidth == 32)
     782          42 :     Value &= 0xffffffffULL;
     783             : 
     784             :   return isMOVZMovAlias(Value, Shift, RegWidth);
     785             : }
     786             : 
     787         958 : inline static bool isAnyMOVWMovAlias(uint64_t Value, int RegWidth) {
     788         958 :   if (isAnyMOVZMovAlias(Value, RegWidth))
     789             :     return true;
     790             : 
     791             :   // It's not a MOVZ, but it might be a MOVN.
     792          69 :   Value = ~Value;
     793          69 :   if (RegWidth == 32)
     794          22 :     Value &= 0xffffffffULL;
     795             : 
     796             :   return isAnyMOVZMovAlias(Value, RegWidth);
     797             : }
     798             : 
     799             : } // end namespace AArch64_AM
     800             : 
     801             : } // end namespace llvm
     802             : 
     803             : #endif

Generated by: LCOV version 1.13