AArch64AddressingModes.h revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
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_TARGET_AArch64_AArch64ADDRESSINGMODES_H 15#define LLVM_TARGET_AArch64_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 23namespace llvm { 24 25/// AArch64_AM - AArch64 Addressing Mode Stuff 26namespace AArch64_AM { 27 28//===----------------------------------------------------------------------===// 29// Shifts 30// 31 32enum 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. 52static inline const char *getShiftExtendName(AArch64_AM::ShiftExtendType ST) { 53 switch (ST) { 54 default: assert(false && "unhandled shift type!"); 55 case AArch64_AM::LSL: return "lsl"; 56 case AArch64_AM::LSR: return "lsr"; 57 case AArch64_AM::ASR: return "asr"; 58 case AArch64_AM::ROR: return "ror"; 59 case AArch64_AM::MSL: return "msl"; 60 case AArch64_AM::UXTB: return "uxtb"; 61 case AArch64_AM::UXTH: return "uxth"; 62 case AArch64_AM::UXTW: return "uxtw"; 63 case AArch64_AM::UXTX: return "uxtx"; 64 case AArch64_AM::SXTB: return "sxtb"; 65 case AArch64_AM::SXTH: return "sxth"; 66 case AArch64_AM::SXTW: return "sxtw"; 67 case AArch64_AM::SXTX: return "sxtx"; 68 } 69 return nullptr; 70} 71 72/// getShiftType - Extract the shift type. 73static inline AArch64_AM::ShiftExtendType getShiftType(unsigned Imm) { 74 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. 85static inline unsigned getShiftValue(unsigned Imm) { 86 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 98static inline unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, 99 unsigned Imm) { 100 assert((Imm & 0x3f) == Imm && "Illegal shifted immedate value!"); 101 unsigned STEnc = 0; 102 switch (ST) { 103 default: llvm_unreachable("Invalid shift requested"); 104 case AArch64_AM::LSL: STEnc = 0; break; 105 case AArch64_AM::LSR: STEnc = 1; break; 106 case AArch64_AM::ASR: STEnc = 2; break; 107 case AArch64_AM::ROR: STEnc = 3; break; 108 case AArch64_AM::MSL: STEnc = 4; break; 109 } 110 return (STEnc << 6) | (Imm & 0x3f); 111} 112 113//===----------------------------------------------------------------------===// 114// Extends 115// 116 117/// getArithShiftValue - get the arithmetic shift value. 118static inline unsigned getArithShiftValue(unsigned Imm) { 119 return Imm & 0x7; 120} 121 122/// getExtendType - Extract the extend type for operands of arithmetic ops. 123static inline AArch64_AM::ShiftExtendType getExtendType(unsigned Imm) { 124 assert((Imm & 0x7) == Imm && "invalid immediate!"); 125 switch (Imm) { 126 default: llvm_unreachable("Compiler bug!"); 127 case 0: return AArch64_AM::UXTB; 128 case 1: return AArch64_AM::UXTH; 129 case 2: return AArch64_AM::UXTW; 130 case 3: return AArch64_AM::UXTX; 131 case 4: return AArch64_AM::SXTB; 132 case 5: return AArch64_AM::SXTH; 133 case 6: return AArch64_AM::SXTW; 134 case 7: return AArch64_AM::SXTX; 135 } 136} 137 138static inline AArch64_AM::ShiftExtendType getArithExtendType(unsigned Imm) { 139 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 151inline unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET) { 152 switch (ET) { 153 default: llvm_unreachable("Invalid extend type requested"); 154 case AArch64_AM::UXTB: return 0; break; 155 case AArch64_AM::UXTH: return 1; break; 156 case AArch64_AM::UXTW: return 2; break; 157 case AArch64_AM::UXTX: return 3; break; 158 case AArch64_AM::SXTB: return 4; break; 159 case AArch64_AM::SXTH: return 5; break; 160 case AArch64_AM::SXTW: return 6; break; 161 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 170static inline unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, 171 unsigned Imm) { 172 assert((Imm & 0x7) == Imm && "Illegal shifted immedate value!"); 173 return (getExtendEncoding(ET) << 3) | (Imm & 0x7); 174} 175 176/// getMemDoShift - Extract the "do shift" flag value for load/store 177/// instructions. 178static inline bool getMemDoShift(unsigned Imm) { 179 return (Imm & 0x1) != 0; 180} 181 182/// getExtendType - Extract the extend type for the offset operand of 183/// loads/stores. 184static inline AArch64_AM::ShiftExtendType getMemExtendType(unsigned Imm) { 185 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 200static inline unsigned getMemExtendImm(AArch64_AM::ShiftExtendType ET, 201 bool DoShift) { 202 return (getExtendEncoding(ET) << 1) | unsigned(DoShift); 203} 204 205static inline uint64_t ror(uint64_t elt, unsigned size) { 206 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. 213static inline bool processLogicalImmediate(uint64_t imm, unsigned regSize, 214 uint64_t &encoding) { 215 if (imm == 0ULL || imm == ~0ULL || 216 (regSize != 64 && (imm >> regSize != 0 || imm == ~0U))) 217 return false; 218 219 unsigned size = 2; 220 uint64_t eltVal = imm; 221 222 // First, determine the element size. 223 while (size < regSize) { 224 unsigned numElts = regSize / size; 225 unsigned mask = (1ULL << size) - 1; 226 uint64_t lowestEltVal = imm & mask; 227 228 bool allMatched = true; 229 for (unsigned i = 1; i < numElts; ++i) { 230 uint64_t currEltVal = (imm >> (i*size)) & mask; 231 if (currEltVal != lowestEltVal) { 232 allMatched = false; 233 break; 234 } 235 } 236 237 if (allMatched) { 238 eltVal = lowestEltVal; 239 break; 240 } 241 242 size *= 2; 243 } 244 245 // Second, determine the rotation to make the element be: 0^m 1^n. 246 for (unsigned i = 0; i < size; ++i) { 247 eltVal = ror(eltVal, size); 248 uint32_t clz = countLeadingZeros(eltVal) - (64 - size); 249 uint32_t cto = CountTrailingOnes_64(eltVal); 250 251 if (clz + cto == size) { 252 // Encode in immr the number of RORs it would take to get *from* this 253 // element value to our target value, where i+1 is the number of RORs 254 // to go the opposite direction. 255 unsigned immr = size - (i + 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 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 nimms |= (cto-1); 264 265 // Extract the seventh bit and toggle it to create the N field. 266 unsigned N = ((nimms >> 6) & 1) ^ 1; 267 268 encoding = (N << 12) | (immr << 6) | (nimms & 0x3f); 269 return true; 270 } 271 } 272 273 return false; 274} 275 276/// isLogicalImmediate - Return true if the immediate is valid for a logical 277/// immediate instruction of the given register size. Return false otherwise. 278static inline bool isLogicalImmediate(uint64_t imm, unsigned regSize) { 279 uint64_t encoding; 280 return processLogicalImmediate(imm, regSize, encoding); 281} 282 283/// encodeLogicalImmediate - Return the encoded immediate value for a logical 284/// immediate instruction of the given register size. 285static inline uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize) { 286 uint64_t encoding = 0; 287 bool res = processLogicalImmediate(imm, regSize, encoding); 288 assert(res && "invalid logical immediate"); 289 (void)res; 290 return encoding; 291} 292 293/// decodeLogicalImmediate - Decode a logical immediate value in the form 294/// "N:immr:imms" (where the immr and imms fields are each 6 bits) into the 295/// integer value it represents with regSize bits. 296static inline uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize) { 297 // Extract the N, imms, and immr fields. 298 unsigned N = (val >> 12) & 1; 299 unsigned immr = (val >> 6) & 0x3f; 300 unsigned imms = val & 0x3f; 301 302 assert((regSize == 64 || N == 0) && "undefined logical immediate encoding"); 303 int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f)); 304 assert(len >= 0 && "undefined logical immediate encoding"); 305 unsigned size = (1 << len); 306 unsigned R = immr & (size - 1); 307 unsigned S = imms & (size - 1); 308 assert(S != size - 1 && "undefined logical immediate encoding"); 309 uint64_t pattern = (1ULL << (S + 1)) - 1; 310 for (unsigned i = 0; i < R; ++i) 311 pattern = ror(pattern, size); 312 313 // Replicate the pattern to fill the regSize. 314 while (size != regSize) { 315 pattern |= (pattern << size); 316 size *= 2; 317 } 318 return pattern; 319} 320 321/// isValidDecodeLogicalImmediate - Check to see if the logical immediate value 322/// in the form "N:immr:imms" (where the immr and imms fields are each 6 bits) 323/// is a valid encoding for an integer value with regSize bits. 324static inline bool isValidDecodeLogicalImmediate(uint64_t val, 325 unsigned regSize) { 326 // Extract the N and imms fields needed for checking. 327 unsigned N = (val >> 12) & 1; 328 unsigned imms = val & 0x3f; 329 330 if (regSize == 32 && N != 0) // undefined logical immediate encoding 331 return false; 332 int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f)); 333 if (len < 0) // undefined logical immediate encoding 334 return false; 335 unsigned size = (1 << len); 336 unsigned S = imms & (size - 1); 337 if (S == size - 1) // undefined logical immediate encoding 338 return false; 339 340 return true; 341} 342 343//===----------------------------------------------------------------------===// 344// Floating-point Immediates 345// 346static inline float getFPImmFloat(unsigned Imm) { 347 // We expect an 8-bit binary encoding of a floating-point number here. 348 union { 349 uint32_t I; 350 float F; 351 } FPUnion; 352 353 uint8_t Sign = (Imm >> 7) & 0x1; 354 uint8_t Exp = (Imm >> 4) & 0x7; 355 uint8_t Mantissa = Imm & 0xf; 356 357 // 8-bit FP iEEEE Float Encoding 358 // abcd efgh aBbbbbbc defgh000 00000000 00000000 359 // 360 // where B = NOT(b); 361 362 FPUnion.I = 0; 363 FPUnion.I |= Sign << 31; 364 FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30; 365 FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25; 366 FPUnion.I |= (Exp & 0x3) << 23; 367 FPUnion.I |= Mantissa << 19; 368 return FPUnion.F; 369} 370 371/// getFP32Imm - Return an 8-bit floating-point version of the 32-bit 372/// floating-point value. If the value cannot be represented as an 8-bit 373/// floating-point value, then return -1. 374static inline int getFP32Imm(const APInt &Imm) { 375 uint32_t Sign = Imm.lshr(31).getZExtValue() & 1; 376 int32_t Exp = (Imm.lshr(23).getSExtValue() & 0xff) - 127; // -126 to 127 377 int64_t Mantissa = Imm.getZExtValue() & 0x7fffff; // 23 bits 378 379 // We can handle 4 bits of mantissa. 380 // mantissa = (16+UInt(e:f:g:h))/16. 381 if (Mantissa & 0x7ffff) 382 return -1; 383 Mantissa >>= 19; 384 if ((Mantissa & 0xf) != Mantissa) 385 return -1; 386 387 // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3 388 if (Exp < -3 || Exp > 4) 389 return -1; 390 Exp = ((Exp+3) & 0x7) ^ 4; 391 392 return ((int)Sign << 7) | (Exp << 4) | Mantissa; 393} 394 395static inline int getFP32Imm(const APFloat &FPImm) { 396 return getFP32Imm(FPImm.bitcastToAPInt()); 397} 398 399/// getFP64Imm - Return an 8-bit floating-point version of the 64-bit 400/// floating-point value. If the value cannot be represented as an 8-bit 401/// floating-point value, then return -1. 402static inline int getFP64Imm(const APInt &Imm) { 403 uint64_t Sign = Imm.lshr(63).getZExtValue() & 1; 404 int64_t Exp = (Imm.lshr(52).getSExtValue() & 0x7ff) - 1023; // -1022 to 1023 405 uint64_t Mantissa = Imm.getZExtValue() & 0xfffffffffffffULL; 406 407 // We can handle 4 bits of mantissa. 408 // mantissa = (16+UInt(e:f:g:h))/16. 409 if (Mantissa & 0xffffffffffffULL) 410 return -1; 411 Mantissa >>= 48; 412 if ((Mantissa & 0xf) != Mantissa) 413 return -1; 414 415 // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3 416 if (Exp < -3 || Exp > 4) 417 return -1; 418 Exp = ((Exp+3) & 0x7) ^ 4; 419 420 return ((int)Sign << 7) | (Exp << 4) | Mantissa; 421} 422 423static inline int getFP64Imm(const APFloat &FPImm) { 424 return getFP64Imm(FPImm.bitcastToAPInt()); 425} 426 427//===--------------------------------------------------------------------===// 428// AdvSIMD Modified Immediates 429//===--------------------------------------------------------------------===// 430 431// 0x00 0x00 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 432static inline bool isAdvSIMDModImmType1(uint64_t Imm) { 433 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 434 ((Imm & 0xffffff00ffffff00ULL) == 0); 435} 436 437static inline uint8_t encodeAdvSIMDModImmType1(uint64_t Imm) { 438 return (Imm & 0xffULL); 439} 440 441static inline uint64_t decodeAdvSIMDModImmType1(uint8_t Imm) { 442 uint64_t EncVal = Imm; 443 return (EncVal << 32) | EncVal; 444} 445 446// 0x00 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 447static inline bool isAdvSIMDModImmType2(uint64_t Imm) { 448 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 449 ((Imm & 0xffff00ffffff00ffULL) == 0); 450} 451 452static inline uint8_t encodeAdvSIMDModImmType2(uint64_t Imm) { 453 return (Imm & 0xff00ULL) >> 8; 454} 455 456static inline uint64_t decodeAdvSIMDModImmType2(uint8_t Imm) { 457 uint64_t EncVal = Imm; 458 return (EncVal << 40) | (EncVal << 8); 459} 460 461// 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 0x00 462static inline bool isAdvSIMDModImmType3(uint64_t Imm) { 463 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 464 ((Imm & 0xff00ffffff00ffffULL) == 0); 465} 466 467static inline uint8_t encodeAdvSIMDModImmType3(uint64_t Imm) { 468 return (Imm & 0xff0000ULL) >> 16; 469} 470 471static inline uint64_t decodeAdvSIMDModImmType3(uint8_t Imm) { 472 uint64_t EncVal = Imm; 473 return (EncVal << 48) | (EncVal << 16); 474} 475 476// abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 0x00 0x00 477static inline bool isAdvSIMDModImmType4(uint64_t Imm) { 478 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 479 ((Imm & 0x00ffffff00ffffffULL) == 0); 480} 481 482static inline uint8_t encodeAdvSIMDModImmType4(uint64_t Imm) { 483 return (Imm & 0xff000000ULL) >> 24; 484} 485 486static inline uint64_t decodeAdvSIMDModImmType4(uint8_t Imm) { 487 uint64_t EncVal = Imm; 488 return (EncVal << 56) | (EncVal << 24); 489} 490 491// 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 492static inline bool isAdvSIMDModImmType5(uint64_t Imm) { 493 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 494 (((Imm & 0x00ff0000ULL) >> 16) == (Imm & 0x000000ffULL)) && 495 ((Imm & 0xff00ff00ff00ff00ULL) == 0); 496} 497 498static inline uint8_t encodeAdvSIMDModImmType5(uint64_t Imm) { 499 return (Imm & 0xffULL); 500} 501 502static inline uint64_t decodeAdvSIMDModImmType5(uint8_t Imm) { 503 uint64_t EncVal = Imm; 504 return (EncVal << 48) | (EncVal << 32) | (EncVal << 16) | EncVal; 505} 506 507// abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 508static inline bool isAdvSIMDModImmType6(uint64_t Imm) { 509 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 510 (((Imm & 0xff000000ULL) >> 16) == (Imm & 0x0000ff00ULL)) && 511 ((Imm & 0x00ff00ff00ff00ffULL) == 0); 512} 513 514static inline uint8_t encodeAdvSIMDModImmType6(uint64_t Imm) { 515 return (Imm & 0xff00ULL) >> 8; 516} 517 518static inline uint64_t decodeAdvSIMDModImmType6(uint8_t Imm) { 519 uint64_t EncVal = Imm; 520 return (EncVal << 56) | (EncVal << 40) | (EncVal << 24) | (EncVal << 8); 521} 522 523// 0x00 0x00 abcdefgh 0xFF 0x00 0x00 abcdefgh 0xFF 524static inline bool isAdvSIMDModImmType7(uint64_t Imm) { 525 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 526 ((Imm & 0xffff00ffffff00ffULL) == 0x000000ff000000ffULL); 527} 528 529static inline uint8_t encodeAdvSIMDModImmType7(uint64_t Imm) { 530 return (Imm & 0xff00ULL) >> 8; 531} 532 533static inline uint64_t decodeAdvSIMDModImmType7(uint8_t Imm) { 534 uint64_t EncVal = Imm; 535 return (EncVal << 40) | (EncVal << 8) | 0x000000ff000000ffULL; 536} 537 538// 0x00 abcdefgh 0xFF 0xFF 0x00 abcdefgh 0xFF 0xFF 539static inline bool isAdvSIMDModImmType8(uint64_t Imm) { 540 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 541 ((Imm & 0xff00ffffff00ffffULL) == 0x0000ffff0000ffffULL); 542} 543 544static inline uint64_t decodeAdvSIMDModImmType8(uint8_t Imm) { 545 uint64_t EncVal = Imm; 546 return (EncVal << 48) | (EncVal << 16) | 0x0000ffff0000ffffULL; 547} 548 549static inline uint8_t encodeAdvSIMDModImmType8(uint64_t Imm) { 550 return (Imm & 0x00ff0000ULL) >> 16; 551} 552 553// abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh 554static inline bool isAdvSIMDModImmType9(uint64_t Imm) { 555 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 556 ((Imm >> 48) == (Imm & 0x0000ffffULL)) && 557 ((Imm >> 56) == (Imm & 0x000000ffULL)); 558} 559 560static inline uint8_t encodeAdvSIMDModImmType9(uint64_t Imm) { 561 return (Imm & 0xffULL); 562} 563 564static inline uint64_t decodeAdvSIMDModImmType9(uint8_t Imm) { 565 uint64_t EncVal = Imm; 566 EncVal |= (EncVal << 8); 567 EncVal |= (EncVal << 16); 568 EncVal |= (EncVal << 32); 569 return EncVal; 570} 571 572// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 573// cmode: 1110, op: 1 574static inline bool isAdvSIMDModImmType10(uint64_t Imm) { 575 uint64_t ByteA = Imm & 0xff00000000000000ULL; 576 uint64_t ByteB = Imm & 0x00ff000000000000ULL; 577 uint64_t ByteC = Imm & 0x0000ff0000000000ULL; 578 uint64_t ByteD = Imm & 0x000000ff00000000ULL; 579 uint64_t ByteE = Imm & 0x00000000ff000000ULL; 580 uint64_t ByteF = Imm & 0x0000000000ff0000ULL; 581 uint64_t ByteG = Imm & 0x000000000000ff00ULL; 582 uint64_t ByteH = Imm & 0x00000000000000ffULL; 583 584 return (ByteA == 0ULL || ByteA == 0xff00000000000000ULL) && 585 (ByteB == 0ULL || ByteB == 0x00ff000000000000ULL) && 586 (ByteC == 0ULL || ByteC == 0x0000ff0000000000ULL) && 587 (ByteD == 0ULL || ByteD == 0x000000ff00000000ULL) && 588 (ByteE == 0ULL || ByteE == 0x00000000ff000000ULL) && 589 (ByteF == 0ULL || ByteF == 0x0000000000ff0000ULL) && 590 (ByteG == 0ULL || ByteG == 0x000000000000ff00ULL) && 591 (ByteH == 0ULL || ByteH == 0x00000000000000ffULL); 592} 593 594static inline uint8_t encodeAdvSIMDModImmType10(uint64_t Imm) { 595 uint8_t BitA = (Imm & 0xff00000000000000ULL) != 0; 596 uint8_t BitB = (Imm & 0x00ff000000000000ULL) != 0; 597 uint8_t BitC = (Imm & 0x0000ff0000000000ULL) != 0; 598 uint8_t BitD = (Imm & 0x000000ff00000000ULL) != 0; 599 uint8_t BitE = (Imm & 0x00000000ff000000ULL) != 0; 600 uint8_t BitF = (Imm & 0x0000000000ff0000ULL) != 0; 601 uint8_t BitG = (Imm & 0x000000000000ff00ULL) != 0; 602 uint8_t BitH = (Imm & 0x00000000000000ffULL) != 0; 603 604 uint8_t EncVal = BitA; 605 EncVal <<= 1; 606 EncVal |= BitB; 607 EncVal <<= 1; 608 EncVal |= BitC; 609 EncVal <<= 1; 610 EncVal |= BitD; 611 EncVal <<= 1; 612 EncVal |= BitE; 613 EncVal <<= 1; 614 EncVal |= BitF; 615 EncVal <<= 1; 616 EncVal |= BitG; 617 EncVal <<= 1; 618 EncVal |= BitH; 619 return EncVal; 620} 621 622static inline uint64_t decodeAdvSIMDModImmType10(uint8_t Imm) { 623 uint64_t EncVal = 0; 624 if (Imm & 0x80) EncVal |= 0xff00000000000000ULL; 625 if (Imm & 0x40) EncVal |= 0x00ff000000000000ULL; 626 if (Imm & 0x20) EncVal |= 0x0000ff0000000000ULL; 627 if (Imm & 0x10) EncVal |= 0x000000ff00000000ULL; 628 if (Imm & 0x08) EncVal |= 0x00000000ff000000ULL; 629 if (Imm & 0x04) EncVal |= 0x0000000000ff0000ULL; 630 if (Imm & 0x02) EncVal |= 0x000000000000ff00ULL; 631 if (Imm & 0x01) EncVal |= 0x00000000000000ffULL; 632 return EncVal; 633} 634 635// aBbbbbbc defgh000 0x00 0x00 aBbbbbbc defgh000 0x00 0x00 636static inline bool isAdvSIMDModImmType11(uint64_t Imm) { 637 uint64_t BString = (Imm & 0x7E000000ULL) >> 25; 638 return ((Imm >> 32) == (Imm & 0xffffffffULL)) && 639 (BString == 0x1f || BString == 0x20) && 640 ((Imm & 0x0007ffff0007ffffULL) == 0); 641} 642 643static inline uint8_t encodeAdvSIMDModImmType11(uint64_t Imm) { 644 uint8_t BitA = (Imm & 0x80000000ULL) != 0; 645 uint8_t BitB = (Imm & 0x20000000ULL) != 0; 646 uint8_t BitC = (Imm & 0x01000000ULL) != 0; 647 uint8_t BitD = (Imm & 0x00800000ULL) != 0; 648 uint8_t BitE = (Imm & 0x00400000ULL) != 0; 649 uint8_t BitF = (Imm & 0x00200000ULL) != 0; 650 uint8_t BitG = (Imm & 0x00100000ULL) != 0; 651 uint8_t BitH = (Imm & 0x00080000ULL) != 0; 652 653 uint8_t EncVal = BitA; 654 EncVal <<= 1; 655 EncVal |= BitB; 656 EncVal <<= 1; 657 EncVal |= BitC; 658 EncVal <<= 1; 659 EncVal |= BitD; 660 EncVal <<= 1; 661 EncVal |= BitE; 662 EncVal <<= 1; 663 EncVal |= BitF; 664 EncVal <<= 1; 665 EncVal |= BitG; 666 EncVal <<= 1; 667 EncVal |= BitH; 668 return EncVal; 669} 670 671static inline uint64_t decodeAdvSIMDModImmType11(uint8_t Imm) { 672 uint64_t EncVal = 0; 673 if (Imm & 0x80) EncVal |= 0x80000000ULL; 674 if (Imm & 0x40) EncVal |= 0x3e000000ULL; 675 else EncVal |= 0x40000000ULL; 676 if (Imm & 0x20) EncVal |= 0x01000000ULL; 677 if (Imm & 0x10) EncVal |= 0x00800000ULL; 678 if (Imm & 0x08) EncVal |= 0x00400000ULL; 679 if (Imm & 0x04) EncVal |= 0x00200000ULL; 680 if (Imm & 0x02) EncVal |= 0x00100000ULL; 681 if (Imm & 0x01) EncVal |= 0x00080000ULL; 682 return (EncVal << 32) | EncVal; 683} 684 685// aBbbbbbb bbcdefgh 0x00 0x00 0x00 0x00 0x00 0x00 686static inline bool isAdvSIMDModImmType12(uint64_t Imm) { 687 uint64_t BString = (Imm & 0x7fc0000000000000ULL) >> 54; 688 return ((BString == 0xff || BString == 0x100) && 689 ((Imm & 0x0000ffffffffffffULL) == 0)); 690} 691 692static inline uint8_t encodeAdvSIMDModImmType12(uint64_t Imm) { 693 uint8_t BitA = (Imm & 0x8000000000000000ULL) != 0; 694 uint8_t BitB = (Imm & 0x0040000000000000ULL) != 0; 695 uint8_t BitC = (Imm & 0x0020000000000000ULL) != 0; 696 uint8_t BitD = (Imm & 0x0010000000000000ULL) != 0; 697 uint8_t BitE = (Imm & 0x0008000000000000ULL) != 0; 698 uint8_t BitF = (Imm & 0x0004000000000000ULL) != 0; 699 uint8_t BitG = (Imm & 0x0002000000000000ULL) != 0; 700 uint8_t BitH = (Imm & 0x0001000000000000ULL) != 0; 701 702 uint8_t EncVal = BitA; 703 EncVal <<= 1; 704 EncVal |= BitB; 705 EncVal <<= 1; 706 EncVal |= BitC; 707 EncVal <<= 1; 708 EncVal |= BitD; 709 EncVal <<= 1; 710 EncVal |= BitE; 711 EncVal <<= 1; 712 EncVal |= BitF; 713 EncVal <<= 1; 714 EncVal |= BitG; 715 EncVal <<= 1; 716 EncVal |= BitH; 717 return EncVal; 718} 719 720static inline uint64_t decodeAdvSIMDModImmType12(uint8_t Imm) { 721 uint64_t EncVal = 0; 722 if (Imm & 0x80) EncVal |= 0x8000000000000000ULL; 723 if (Imm & 0x40) EncVal |= 0x3fc0000000000000ULL; 724 else EncVal |= 0x4000000000000000ULL; 725 if (Imm & 0x20) EncVal |= 0x0020000000000000ULL; 726 if (Imm & 0x10) EncVal |= 0x0010000000000000ULL; 727 if (Imm & 0x08) EncVal |= 0x0008000000000000ULL; 728 if (Imm & 0x04) EncVal |= 0x0004000000000000ULL; 729 if (Imm & 0x02) EncVal |= 0x0002000000000000ULL; 730 if (Imm & 0x01) EncVal |= 0x0001000000000000ULL; 731 return (EncVal << 32) | EncVal; 732} 733 734} // end namespace AArch64_AM 735 736} // end namespace llvm 737 738#endif 739