LLVM API Documentation
00001 //===- AArch64AddressingModes.h - AArch64 Addressing Modes ------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the AArch64 addressing mode implementation stuff. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64ADDRESSINGMODES_H 00015 #define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64ADDRESSINGMODES_H 00016 00017 #include "llvm/ADT/APFloat.h" 00018 #include "llvm/ADT/APInt.h" 00019 #include "llvm/Support/ErrorHandling.h" 00020 #include "llvm/Support/MathExtras.h" 00021 #include <cassert> 00022 00023 namespace llvm { 00024 00025 /// AArch64_AM - AArch64 Addressing Mode Stuff 00026 namespace AArch64_AM { 00027 00028 //===----------------------------------------------------------------------===// 00029 // Shifts 00030 // 00031 00032 enum ShiftExtendType { 00033 InvalidShiftExtend = -1, 00034 LSL = 0, 00035 LSR, 00036 ASR, 00037 ROR, 00038 MSL, 00039 00040 UXTB, 00041 UXTH, 00042 UXTW, 00043 UXTX, 00044 00045 SXTB, 00046 SXTH, 00047 SXTW, 00048 SXTX, 00049 }; 00050 00051 /// getShiftName - Get the string encoding for the shift type. 00052 static inline const char *getShiftExtendName(AArch64_AM::ShiftExtendType ST) { 00053 switch (ST) { 00054 default: assert(false && "unhandled shift type!"); 00055 case AArch64_AM::LSL: return "lsl"; 00056 case AArch64_AM::LSR: return "lsr"; 00057 case AArch64_AM::ASR: return "asr"; 00058 case AArch64_AM::ROR: return "ror"; 00059 case AArch64_AM::MSL: return "msl"; 00060 case AArch64_AM::UXTB: return "uxtb"; 00061 case AArch64_AM::UXTH: return "uxth"; 00062 case AArch64_AM::UXTW: return "uxtw"; 00063 case AArch64_AM::UXTX: return "uxtx"; 00064 case AArch64_AM::SXTB: return "sxtb"; 00065 case AArch64_AM::SXTH: return "sxth"; 00066 case AArch64_AM::SXTW: return "sxtw"; 00067 case AArch64_AM::SXTX: return "sxtx"; 00068 } 00069 return nullptr; 00070 } 00071 00072 /// getShiftType - Extract the shift type. 00073 static inline AArch64_AM::ShiftExtendType getShiftType(unsigned Imm) { 00074 switch ((Imm >> 6) & 0x7) { 00075 default: return AArch64_AM::InvalidShiftExtend; 00076 case 0: return AArch64_AM::LSL; 00077 case 1: return AArch64_AM::LSR; 00078 case 2: return AArch64_AM::ASR; 00079 case 3: return AArch64_AM::ROR; 00080 case 4: return AArch64_AM::MSL; 00081 } 00082 } 00083 00084 /// getShiftValue - Extract the shift value. 00085 static inline unsigned getShiftValue(unsigned Imm) { 00086 return Imm & 0x3f; 00087 } 00088 00089 /// getShifterImm - Encode the shift type and amount: 00090 /// imm: 6-bit shift amount 00091 /// shifter: 000 ==> lsl 00092 /// 001 ==> lsr 00093 /// 010 ==> asr 00094 /// 011 ==> ror 00095 /// 100 ==> msl 00096 /// {8-6} = shifter 00097 /// {5-0} = imm 00098 static inline unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, 00099 unsigned Imm) { 00100 assert((Imm & 0x3f) == Imm && "Illegal shifted immedate value!"); 00101 unsigned STEnc = 0; 00102 switch (ST) { 00103 default: llvm_unreachable("Invalid shift requested"); 00104 case AArch64_AM::LSL: STEnc = 0; break; 00105 case AArch64_AM::LSR: STEnc = 1; break; 00106 case AArch64_AM::ASR: STEnc = 2; break; 00107 case AArch64_AM::ROR: STEnc = 3; break; 00108 case AArch64_AM::MSL: STEnc = 4; break; 00109 } 00110 return (STEnc << 6) | (Imm & 0x3f); 00111 } 00112 00113 //===----------------------------------------------------------------------===// 00114 // Extends 00115 // 00116 00117 /// getArithShiftValue - get the arithmetic shift value. 00118 static inline unsigned getArithShiftValue(unsigned Imm) { 00119 return Imm & 0x7; 00120 } 00121 00122 /// getExtendType - Extract the extend type for operands of arithmetic ops. 00123 static inline AArch64_AM::ShiftExtendType getExtendType(unsigned Imm) { 00124 assert((Imm & 0x7) == Imm && "invalid immediate!"); 00125 switch (Imm) { 00126 default: llvm_unreachable("Compiler bug!"); 00127 case 0: return AArch64_AM::UXTB; 00128 case 1: return AArch64_AM::UXTH; 00129 case 2: return AArch64_AM::UXTW; 00130 case 3: return AArch64_AM::UXTX; 00131 case 4: return AArch64_AM::SXTB; 00132 case 5: return AArch64_AM::SXTH; 00133 case 6: return AArch64_AM::SXTW; 00134 case 7: return AArch64_AM::SXTX; 00135 } 00136 } 00137 00138 static inline AArch64_AM::ShiftExtendType getArithExtendType(unsigned Imm) { 00139 return getExtendType((Imm >> 3) & 0x7); 00140 } 00141 00142 /// Mapping from extend bits to required operation: 00143 /// shifter: 000 ==> uxtb 00144 /// 001 ==> uxth 00145 /// 010 ==> uxtw 00146 /// 011 ==> uxtx 00147 /// 100 ==> sxtb 00148 /// 101 ==> sxth 00149 /// 110 ==> sxtw 00150 /// 111 ==> sxtx 00151 inline unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET) { 00152 switch (ET) { 00153 default: llvm_unreachable("Invalid extend type requested"); 00154 case AArch64_AM::UXTB: return 0; break; 00155 case AArch64_AM::UXTH: return 1; break; 00156 case AArch64_AM::UXTW: return 2; break; 00157 case AArch64_AM::UXTX: return 3; break; 00158 case AArch64_AM::SXTB: return 4; break; 00159 case AArch64_AM::SXTH: return 5; break; 00160 case AArch64_AM::SXTW: return 6; break; 00161 case AArch64_AM::SXTX: return 7; break; 00162 } 00163 } 00164 00165 /// getArithExtendImm - Encode the extend type and shift amount for an 00166 /// arithmetic instruction: 00167 /// imm: 3-bit extend amount 00168 /// {5-3} = shifter 00169 /// {2-0} = imm3 00170 static inline unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, 00171 unsigned Imm) { 00172 assert((Imm & 0x7) == Imm && "Illegal shifted immedate value!"); 00173 return (getExtendEncoding(ET) << 3) | (Imm & 0x7); 00174 } 00175 00176 /// getMemDoShift - Extract the "do shift" flag value for load/store 00177 /// instructions. 00178 static inline bool getMemDoShift(unsigned Imm) { 00179 return (Imm & 0x1) != 0; 00180 } 00181 00182 /// getExtendType - Extract the extend type for the offset operand of 00183 /// loads/stores. 00184 static inline AArch64_AM::ShiftExtendType getMemExtendType(unsigned Imm) { 00185 return getExtendType((Imm >> 1) & 0x7); 00186 } 00187 00188 /// getExtendImm - Encode the extend type and amount for a load/store inst: 00189 /// doshift: should the offset be scaled by the access size 00190 /// shifter: 000 ==> uxtb 00191 /// 001 ==> uxth 00192 /// 010 ==> uxtw 00193 /// 011 ==> uxtx 00194 /// 100 ==> sxtb 00195 /// 101 ==> sxth 00196 /// 110 ==> sxtw 00197 /// 111 ==> sxtx 00198 /// {3-1} = shifter 00199 /// {0} = doshift 00200 static inline unsigned getMemExtendImm(AArch64_AM::ShiftExtendType ET, 00201 bool DoShift) { 00202 return (getExtendEncoding(ET) << 1) | unsigned(DoShift); 00203 } 00204 00205 static inline uint64_t ror(uint64_t elt, unsigned size) { 00206 return ((elt & 1) << (size-1)) | (elt >> 1); 00207 } 00208 00209 /// processLogicalImmediate - Determine if an immediate value can be encoded 00210 /// as the immediate operand of a logical instruction for the given register 00211 /// size. If so, return true with "encoding" set to the encoded value in 00212 /// the form N:immr:imms. 00213 static inline bool processLogicalImmediate(uint64_t imm, unsigned regSize, 00214 uint64_t &encoding) { 00215 if (imm == 0ULL || imm == ~0ULL || 00216 (regSize != 64 && (imm >> regSize != 0 || imm == ~0U))) 00217 return false; 00218 00219 unsigned size = 2; 00220 uint64_t eltVal = imm; 00221 00222 // First, determine the element size. 00223 while (size < regSize) { 00224 unsigned numElts = regSize / size; 00225 unsigned mask = (1ULL << size) - 1; 00226 uint64_t lowestEltVal = imm & mask; 00227 00228 bool allMatched = true; 00229 for (unsigned i = 1; i < numElts; ++i) { 00230 uint64_t currEltVal = (imm >> (i*size)) & mask; 00231 if (currEltVal != lowestEltVal) { 00232 allMatched = false; 00233 break; 00234 } 00235 } 00236 00237 if (allMatched) { 00238 eltVal = lowestEltVal; 00239 break; 00240 } 00241 00242 size *= 2; 00243 } 00244 00245 // Second, determine the rotation to make the element be: 0^m 1^n. 00246 for (unsigned i = 0; i < size; ++i) { 00247 eltVal = ror(eltVal, size); 00248 uint32_t clz = countLeadingZeros(eltVal) - (64 - size); 00249 uint32_t cto = CountTrailingOnes_64(eltVal); 00250 00251 if (clz + cto == size) { 00252 // Encode in immr the number of RORs it would take to get *from* this 00253 // element value to our target value, where i+1 is the number of RORs 00254 // to go the opposite direction. 00255 unsigned immr = size - (i + 1); 00256 00257 // If size has a 1 in the n'th bit, create a value that has zeroes in 00258 // bits [0, n] and ones above that. 00259 uint64_t nimms = ~(size-1) << 1; 00260 00261 // Or the CTO value into the low bits, which must be below the Nth bit 00262 // bit mentioned above. 00263 nimms |= (cto-1); 00264 00265 // Extract the seventh bit and toggle it to create the N field. 00266 unsigned N = ((nimms >> 6) & 1) ^ 1; 00267 00268 encoding = (N << 12) | (immr << 6) | (nimms & 0x3f); 00269 return true; 00270 } 00271 } 00272 00273 return false; 00274 } 00275 00276 /// isLogicalImmediate - Return true if the immediate is valid for a logical 00277 /// immediate instruction of the given register size. Return false otherwise. 00278 static inline bool isLogicalImmediate(uint64_t imm, unsigned regSize) { 00279 uint64_t encoding; 00280 return processLogicalImmediate(imm, regSize, encoding); 00281 } 00282 00283 /// encodeLogicalImmediate - Return the encoded immediate value for a logical 00284 /// immediate instruction of the given register size. 00285 static inline uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize) { 00286 uint64_t encoding = 0; 00287 bool res = processLogicalImmediate(imm, regSize, encoding); 00288 assert(res && "invalid logical immediate"); 00289 (void)res; 00290 return encoding; 00291 } 00292 00293 /// decodeLogicalImmediate - Decode a logical immediate value in the form 00294 /// "N:immr:imms" (where the immr and imms fields are each 6 bits) into the 00295 /// integer value it represents with regSize bits. 00296 static inline uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize) { 00297 // Extract the N, imms, and immr fields. 00298 unsigned N = (val >> 12) & 1; 00299 unsigned immr = (val >> 6) & 0x3f; 00300 unsigned imms = val & 0x3f; 00301 00302 assert((regSize == 64 || N == 0) && "undefined logical immediate encoding"); 00303 int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f)); 00304 assert(len >= 0 && "undefined logical immediate encoding"); 00305 unsigned size = (1 << len); 00306 unsigned R = immr & (size - 1); 00307 unsigned S = imms & (size - 1); 00308 assert(S != size - 1 && "undefined logical immediate encoding"); 00309 uint64_t pattern = (1ULL << (S + 1)) - 1; 00310 for (unsigned i = 0; i < R; ++i) 00311 pattern = ror(pattern, size); 00312 00313 // Replicate the pattern to fill the regSize. 00314 while (size != regSize) { 00315 pattern |= (pattern << size); 00316 size *= 2; 00317 } 00318 return pattern; 00319 } 00320 00321 /// isValidDecodeLogicalImmediate - Check to see if the logical immediate value 00322 /// in the form "N:immr:imms" (where the immr and imms fields are each 6 bits) 00323 /// is a valid encoding for an integer value with regSize bits. 00324 static inline bool isValidDecodeLogicalImmediate(uint64_t val, 00325 unsigned regSize) { 00326 // Extract the N and imms fields needed for checking. 00327 unsigned N = (val >> 12) & 1; 00328 unsigned imms = val & 0x3f; 00329 00330 if (regSize == 32 && N != 0) // undefined logical immediate encoding 00331 return false; 00332 int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f)); 00333 if (len < 0) // undefined logical immediate encoding 00334 return false; 00335 unsigned size = (1 << len); 00336 unsigned S = imms & (size - 1); 00337 if (S == size - 1) // undefined logical immediate encoding 00338 return false; 00339 00340 return true; 00341 } 00342 00343 //===----------------------------------------------------------------------===// 00344 // Floating-point Immediates 00345 // 00346 static inline float getFPImmFloat(unsigned Imm) { 00347 // We expect an 8-bit binary encoding of a floating-point number here. 00348 union { 00349 uint32_t I; 00350 float F; 00351 } FPUnion; 00352 00353 uint8_t Sign = (Imm >> 7) & 0x1; 00354 uint8_t Exp = (Imm >> 4) & 0x7; 00355 uint8_t Mantissa = Imm & 0xf; 00356 00357 // 8-bit FP iEEEE Float Encoding 00358 // abcd efgh aBbbbbbc defgh000 00000000 00000000 00359 // 00360 // where B = NOT(b); 00361 00362 FPUnion.I = 0; 00363 FPUnion.I |= Sign << 31; 00364 FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30; 00365 FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25; 00366 FPUnion.I |= (Exp & 0x3) << 23; 00367 FPUnion.I |= Mantissa << 19; 00368 return FPUnion.F; 00369 } 00370 00371 /// getFP32Imm - Return an 8-bit floating-point version of the 32-bit 00372 /// floating-point value. If the value cannot be represented as an 8-bit 00373 /// floating-point value, then return -1. 00374 static inline int getFP32Imm(const APInt &Imm) { 00375 uint32_t Sign = Imm.lshr(31).getZExtValue() & 1; 00376 int32_t Exp = (Imm.lshr(23).getSExtValue() & 0xff) - 127; // -126 to 127 00377 int64_t Mantissa = Imm.getZExtValue() & 0x7fffff; // 23 bits 00378 00379 // We can handle 4 bits of mantissa. 00380 // mantissa = (16+UInt(e:f:g:h))/16. 00381 if (Mantissa & 0x7ffff) 00382 return -1; 00383 Mantissa >>= 19; 00384 if ((Mantissa & 0xf) != Mantissa) 00385 return -1; 00386 00387 // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3 00388 if (Exp < -3 || Exp > 4) 00389 return -1; 00390 Exp = ((Exp+3) & 0x7) ^ 4; 00391 00392 return ((int)Sign << 7) | (Exp << 4) | Mantissa; 00393 } 00394 00395 static inline int getFP32Imm(const APFloat &FPImm) { 00396 return getFP32Imm(FPImm.bitcastToAPInt()); 00397 } 00398 00399 /// getFP64Imm - Return an 8-bit floating-point version of the 64-bit 00400 /// floating-point value. If the value cannot be represented as an 8-bit 00401 /// floating-point value, then return -1. 00402 static inline int getFP64Imm(const APInt &Imm) { 00403 uint64_t Sign = Imm.lshr(63).getZExtValue() & 1; 00404 int64_t Exp = (Imm.lshr(52).getSExtValue() & 0x7ff) - 1023; // -1022 to 1023 00405 uint64_t Mantissa = Imm.getZExtValue() & 0xfffffffffffffULL; 00406 00407 // We can handle 4 bits of mantissa. 00408 // mantissa = (16+UInt(e:f:g:h))/16. 00409 if (Mantissa & 0xffffffffffffULL) 00410 return -1; 00411 Mantissa >>= 48; 00412 if ((Mantissa & 0xf) != Mantissa) 00413 return -1; 00414 00415 // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3 00416 if (Exp < -3 || Exp > 4) 00417 return -1; 00418 Exp = ((Exp+3) & 0x7) ^ 4; 00419 00420 return ((int)Sign << 7) | (Exp << 4) | Mantissa; 00421 } 00422 00423 static inline int getFP64Imm(const APFloat &FPImm) { 00424 return getFP64Imm(FPImm.bitcastToAPInt()); 00425 } 00426 00427 //===--------------------------------------------------------------------===// 00428 // AdvSIMD Modified Immediates 00429 //===--------------------------------------------------------------------===// 00430 00431 // 0x00 0x00 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 00432 static inline bool isAdvSIMDModImmType1(uint64_t Imm) { 00433 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 00434 ((Imm & 0xffffff00ffffff00ULL) == 0); 00435 } 00436 00437 static inline uint8_t encodeAdvSIMDModImmType1(uint64_t Imm) { 00438 return (Imm & 0xffULL); 00439 } 00440 00441 static inline uint64_t decodeAdvSIMDModImmType1(uint8_t Imm) { 00442 uint64_t EncVal = Imm; 00443 return (EncVal << 32) | EncVal; 00444 } 00445 00446 // 0x00 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 00447 static inline bool isAdvSIMDModImmType2(uint64_t Imm) { 00448 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 00449 ((Imm & 0xffff00ffffff00ffULL) == 0); 00450 } 00451 00452 static inline uint8_t encodeAdvSIMDModImmType2(uint64_t Imm) { 00453 return (Imm & 0xff00ULL) >> 8; 00454 } 00455 00456 static inline uint64_t decodeAdvSIMDModImmType2(uint8_t Imm) { 00457 uint64_t EncVal = Imm; 00458 return (EncVal << 40) | (EncVal << 8); 00459 } 00460 00461 // 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 0x00 00462 static inline bool isAdvSIMDModImmType3(uint64_t Imm) { 00463 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 00464 ((Imm & 0xff00ffffff00ffffULL) == 0); 00465 } 00466 00467 static inline uint8_t encodeAdvSIMDModImmType3(uint64_t Imm) { 00468 return (Imm & 0xff0000ULL) >> 16; 00469 } 00470 00471 static inline uint64_t decodeAdvSIMDModImmType3(uint8_t Imm) { 00472 uint64_t EncVal = Imm; 00473 return (EncVal << 48) | (EncVal << 16); 00474 } 00475 00476 // abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 0x00 0x00 00477 static inline bool isAdvSIMDModImmType4(uint64_t Imm) { 00478 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 00479 ((Imm & 0x00ffffff00ffffffULL) == 0); 00480 } 00481 00482 static inline uint8_t encodeAdvSIMDModImmType4(uint64_t Imm) { 00483 return (Imm & 0xff000000ULL) >> 24; 00484 } 00485 00486 static inline uint64_t decodeAdvSIMDModImmType4(uint8_t Imm) { 00487 uint64_t EncVal = Imm; 00488 return (EncVal << 56) | (EncVal << 24); 00489 } 00490 00491 // 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 00492 static inline bool isAdvSIMDModImmType5(uint64_t Imm) { 00493 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 00494 (((Imm & 0x00ff0000ULL) >> 16) == (Imm & 0x000000ffULL)) && 00495 ((Imm & 0xff00ff00ff00ff00ULL) == 0); 00496 } 00497 00498 static inline uint8_t encodeAdvSIMDModImmType5(uint64_t Imm) { 00499 return (Imm & 0xffULL); 00500 } 00501 00502 static inline uint64_t decodeAdvSIMDModImmType5(uint8_t Imm) { 00503 uint64_t EncVal = Imm; 00504 return (EncVal << 48) | (EncVal << 32) | (EncVal << 16) | EncVal; 00505 } 00506 00507 // abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 00508 static inline bool isAdvSIMDModImmType6(uint64_t Imm) { 00509 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 00510 (((Imm & 0xff000000ULL) >> 16) == (Imm & 0x0000ff00ULL)) && 00511 ((Imm & 0x00ff00ff00ff00ffULL) == 0); 00512 } 00513 00514 static inline uint8_t encodeAdvSIMDModImmType6(uint64_t Imm) { 00515 return (Imm & 0xff00ULL) >> 8; 00516 } 00517 00518 static inline uint64_t decodeAdvSIMDModImmType6(uint8_t Imm) { 00519 uint64_t EncVal = Imm; 00520 return (EncVal << 56) | (EncVal << 40) | (EncVal << 24) | (EncVal << 8); 00521 } 00522 00523 // 0x00 0x00 abcdefgh 0xFF 0x00 0x00 abcdefgh 0xFF 00524 static inline bool isAdvSIMDModImmType7(uint64_t Imm) { 00525 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 00526 ((Imm & 0xffff00ffffff00ffULL) == 0x000000ff000000ffULL); 00527 } 00528 00529 static inline uint8_t encodeAdvSIMDModImmType7(uint64_t Imm) { 00530 return (Imm & 0xff00ULL) >> 8; 00531 } 00532 00533 static inline uint64_t decodeAdvSIMDModImmType7(uint8_t Imm) { 00534 uint64_t EncVal = Imm; 00535 return (EncVal << 40) | (EncVal << 8) | 0x000000ff000000ffULL; 00536 } 00537 00538 // 0x00 abcdefgh 0xFF 0xFF 0x00 abcdefgh 0xFF 0xFF 00539 static inline bool isAdvSIMDModImmType8(uint64_t Imm) { 00540 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 00541 ((Imm & 0xff00ffffff00ffffULL) == 0x0000ffff0000ffffULL); 00542 } 00543 00544 static inline uint64_t decodeAdvSIMDModImmType8(uint8_t Imm) { 00545 uint64_t EncVal = Imm; 00546 return (EncVal << 48) | (EncVal << 16) | 0x0000ffff0000ffffULL; 00547 } 00548 00549 static inline uint8_t encodeAdvSIMDModImmType8(uint64_t Imm) { 00550 return (Imm & 0x00ff0000ULL) >> 16; 00551 } 00552 00553 // abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh 00554 static inline bool isAdvSIMDModImmType9(uint64_t Imm) { 00555 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 00556 ((Imm >> 48) == (Imm & 0x0000ffffULL)) && 00557 ((Imm >> 56) == (Imm & 0x000000ffULL)); 00558 } 00559 00560 static inline uint8_t encodeAdvSIMDModImmType9(uint64_t Imm) { 00561 return (Imm & 0xffULL); 00562 } 00563 00564 static inline uint64_t decodeAdvSIMDModImmType9(uint8_t Imm) { 00565 uint64_t EncVal = Imm; 00566 EncVal |= (EncVal << 8); 00567 EncVal |= (EncVal << 16); 00568 EncVal |= (EncVal << 32); 00569 return EncVal; 00570 } 00571 00572 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 00573 // cmode: 1110, op: 1 00574 static inline bool isAdvSIMDModImmType10(uint64_t Imm) { 00575 uint64_t ByteA = Imm & 0xff00000000000000ULL; 00576 uint64_t ByteB = Imm & 0x00ff000000000000ULL; 00577 uint64_t ByteC = Imm & 0x0000ff0000000000ULL; 00578 uint64_t ByteD = Imm & 0x000000ff00000000ULL; 00579 uint64_t ByteE = Imm & 0x00000000ff000000ULL; 00580 uint64_t ByteF = Imm & 0x0000000000ff0000ULL; 00581 uint64_t ByteG = Imm & 0x000000000000ff00ULL; 00582 uint64_t ByteH = Imm & 0x00000000000000ffULL; 00583 00584 return (ByteA == 0ULL || ByteA == 0xff00000000000000ULL) && 00585 (ByteB == 0ULL || ByteB == 0x00ff000000000000ULL) && 00586 (ByteC == 0ULL || ByteC == 0x0000ff0000000000ULL) && 00587 (ByteD == 0ULL || ByteD == 0x000000ff00000000ULL) && 00588 (ByteE == 0ULL || ByteE == 0x00000000ff000000ULL) && 00589 (ByteF == 0ULL || ByteF == 0x0000000000ff0000ULL) && 00590 (ByteG == 0ULL || ByteG == 0x000000000000ff00ULL) && 00591 (ByteH == 0ULL || ByteH == 0x00000000000000ffULL); 00592 } 00593 00594 static inline uint8_t encodeAdvSIMDModImmType10(uint64_t Imm) { 00595 uint8_t BitA = (Imm & 0xff00000000000000ULL) != 0; 00596 uint8_t BitB = (Imm & 0x00ff000000000000ULL) != 0; 00597 uint8_t BitC = (Imm & 0x0000ff0000000000ULL) != 0; 00598 uint8_t BitD = (Imm & 0x000000ff00000000ULL) != 0; 00599 uint8_t BitE = (Imm & 0x00000000ff000000ULL) != 0; 00600 uint8_t BitF = (Imm & 0x0000000000ff0000ULL) != 0; 00601 uint8_t BitG = (Imm & 0x000000000000ff00ULL) != 0; 00602 uint8_t BitH = (Imm & 0x00000000000000ffULL) != 0; 00603 00604 uint8_t EncVal = BitA; 00605 EncVal <<= 1; 00606 EncVal |= BitB; 00607 EncVal <<= 1; 00608 EncVal |= BitC; 00609 EncVal <<= 1; 00610 EncVal |= BitD; 00611 EncVal <<= 1; 00612 EncVal |= BitE; 00613 EncVal <<= 1; 00614 EncVal |= BitF; 00615 EncVal <<= 1; 00616 EncVal |= BitG; 00617 EncVal <<= 1; 00618 EncVal |= BitH; 00619 return EncVal; 00620 } 00621 00622 static inline uint64_t decodeAdvSIMDModImmType10(uint8_t Imm) { 00623 uint64_t EncVal = 0; 00624 if (Imm & 0x80) EncVal |= 0xff00000000000000ULL; 00625 if (Imm & 0x40) EncVal |= 0x00ff000000000000ULL; 00626 if (Imm & 0x20) EncVal |= 0x0000ff0000000000ULL; 00627 if (Imm & 0x10) EncVal |= 0x000000ff00000000ULL; 00628 if (Imm & 0x08) EncVal |= 0x00000000ff000000ULL; 00629 if (Imm & 0x04) EncVal |= 0x0000000000ff0000ULL; 00630 if (Imm & 0x02) EncVal |= 0x000000000000ff00ULL; 00631 if (Imm & 0x01) EncVal |= 0x00000000000000ffULL; 00632 return EncVal; 00633 } 00634 00635 // aBbbbbbc defgh000 0x00 0x00 aBbbbbbc defgh000 0x00 0x00 00636 static inline bool isAdvSIMDModImmType11(uint64_t Imm) { 00637 uint64_t BString = (Imm & 0x7E000000ULL) >> 25; 00638 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 00639 (BString == 0x1f || BString == 0x20) && 00640 ((Imm & 0x0007ffff0007ffffULL) == 0); 00641 } 00642 00643 static inline uint8_t encodeAdvSIMDModImmType11(uint64_t Imm) { 00644 uint8_t BitA = (Imm & 0x80000000ULL) != 0; 00645 uint8_t BitB = (Imm & 0x20000000ULL) != 0; 00646 uint8_t BitC = (Imm & 0x01000000ULL) != 0; 00647 uint8_t BitD = (Imm & 0x00800000ULL) != 0; 00648 uint8_t BitE = (Imm & 0x00400000ULL) != 0; 00649 uint8_t BitF = (Imm & 0x00200000ULL) != 0; 00650 uint8_t BitG = (Imm & 0x00100000ULL) != 0; 00651 uint8_t BitH = (Imm & 0x00080000ULL) != 0; 00652 00653 uint8_t EncVal = BitA; 00654 EncVal <<= 1; 00655 EncVal |= BitB; 00656 EncVal <<= 1; 00657 EncVal |= BitC; 00658 EncVal <<= 1; 00659 EncVal |= BitD; 00660 EncVal <<= 1; 00661 EncVal |= BitE; 00662 EncVal <<= 1; 00663 EncVal |= BitF; 00664 EncVal <<= 1; 00665 EncVal |= BitG; 00666 EncVal <<= 1; 00667 EncVal |= BitH; 00668 return EncVal; 00669 } 00670 00671 static inline uint64_t decodeAdvSIMDModImmType11(uint8_t Imm) { 00672 uint64_t EncVal = 0; 00673 if (Imm & 0x80) EncVal |= 0x80000000ULL; 00674 if (Imm & 0x40) EncVal |= 0x3e000000ULL; 00675 else EncVal |= 0x40000000ULL; 00676 if (Imm & 0x20) EncVal |= 0x01000000ULL; 00677 if (Imm & 0x10) EncVal |= 0x00800000ULL; 00678 if (Imm & 0x08) EncVal |= 0x00400000ULL; 00679 if (Imm & 0x04) EncVal |= 0x00200000ULL; 00680 if (Imm & 0x02) EncVal |= 0x00100000ULL; 00681 if (Imm & 0x01) EncVal |= 0x00080000ULL; 00682 return (EncVal << 32) | EncVal; 00683 } 00684 00685 // aBbbbbbb bbcdefgh 0x00 0x00 0x00 0x00 0x00 0x00 00686 static inline bool isAdvSIMDModImmType12(uint64_t Imm) { 00687 uint64_t BString = (Imm & 0x7fc0000000000000ULL) >> 54; 00688 return ((BString == 0xff || BString == 0x100) && 00689 ((Imm & 0x0000ffffffffffffULL) == 0)); 00690 } 00691 00692 static inline uint8_t encodeAdvSIMDModImmType12(uint64_t Imm) { 00693 uint8_t BitA = (Imm & 0x8000000000000000ULL) != 0; 00694 uint8_t BitB = (Imm & 0x0040000000000000ULL) != 0; 00695 uint8_t BitC = (Imm & 0x0020000000000000ULL) != 0; 00696 uint8_t BitD = (Imm & 0x0010000000000000ULL) != 0; 00697 uint8_t BitE = (Imm & 0x0008000000000000ULL) != 0; 00698 uint8_t BitF = (Imm & 0x0004000000000000ULL) != 0; 00699 uint8_t BitG = (Imm & 0x0002000000000000ULL) != 0; 00700 uint8_t BitH = (Imm & 0x0001000000000000ULL) != 0; 00701 00702 uint8_t EncVal = BitA; 00703 EncVal <<= 1; 00704 EncVal |= BitB; 00705 EncVal <<= 1; 00706 EncVal |= BitC; 00707 EncVal <<= 1; 00708 EncVal |= BitD; 00709 EncVal <<= 1; 00710 EncVal |= BitE; 00711 EncVal <<= 1; 00712 EncVal |= BitF; 00713 EncVal <<= 1; 00714 EncVal |= BitG; 00715 EncVal <<= 1; 00716 EncVal |= BitH; 00717 return EncVal; 00718 } 00719 00720 static inline uint64_t decodeAdvSIMDModImmType12(uint8_t Imm) { 00721 uint64_t EncVal = 0; 00722 if (Imm & 0x80) EncVal |= 0x8000000000000000ULL; 00723 if (Imm & 0x40) EncVal |= 0x3fc0000000000000ULL; 00724 else EncVal |= 0x4000000000000000ULL; 00725 if (Imm & 0x20) EncVal |= 0x0020000000000000ULL; 00726 if (Imm & 0x10) EncVal |= 0x0010000000000000ULL; 00727 if (Imm & 0x08) EncVal |= 0x0008000000000000ULL; 00728 if (Imm & 0x04) EncVal |= 0x0004000000000000ULL; 00729 if (Imm & 0x02) EncVal |= 0x0002000000000000ULL; 00730 if (Imm & 0x01) EncVal |= 0x0001000000000000ULL; 00731 return (EncVal << 32) | EncVal; 00732 } 00733 00734 } // end namespace AArch64_AM 00735 00736 } // end namespace llvm 00737 00738 #endif