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