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_TARGET_ARM_ARMADDRESSINGMODES_H 15 #define LLVM_TARGET_ARM_ARMADDRESSINGMODES_H 16 17 #include "llvm/CodeGen/SelectionDAGNodes.h" 18 #include "llvm/Support/MathExtras.h" 19 #include <cassert> 20 21 namespace llvm { 22 23 /// ARM_AM - ARM Addressing Mode Stuff 24 namespace ARM_AM { 25 enum ShiftOpc { 26 no_shift = 0, 27 asr, 28 lsl, 29 lsr, 30 ror, 31 rrx 32 }; 33 34 enum AddrOpc { 35 add = '+', sub = '-' 36 }; 37 38 static inline const char *getAddrOpcStr(AddrOpc Op) { 39 return Op == sub ? "-" : ""; 40 } 41 42 static inline const char *getShiftOpcStr(ShiftOpc Op) { 43 switch (Op) { 44 default: assert(0 && "Unknown shift opc!"); 45 case ARM_AM::asr: return "asr"; 46 case ARM_AM::lsl: return "lsl"; 47 case ARM_AM::lsr: return "lsr"; 48 case ARM_AM::ror: return "ror"; 49 case ARM_AM::rrx: return "rrx"; 50 } 51 } 52 53 static inline unsigned getShiftOpcEncoding(ShiftOpc Op) { 54 switch (Op) { 55 default: assert(0 && "Unknown shift opc!"); 56 case ARM_AM::asr: return 2; 57 case ARM_AM::lsl: return 0; 58 case ARM_AM::lsr: return 1; 59 case ARM_AM::ror: return 3; 60 } 61 } 62 63 static inline ShiftOpc getShiftOpcForNode(SDValue N) { 64 switch (N.getOpcode()) { 65 default: return ARM_AM::no_shift; 66 case ISD::SHL: return ARM_AM::lsl; 67 case ISD::SRL: return ARM_AM::lsr; 68 case ISD::SRA: return ARM_AM::asr; 69 case ISD::ROTR: return ARM_AM::ror; 70 //case ISD::ROTL: // Only if imm -> turn into ROTR. 71 // Can't handle RRX here, because it would require folding a flag into 72 // the addressing mode. :( This causes us to miss certain things. 73 //case ARMISD::RRX: return ARM_AM::rrx; 74 } 75 } 76 77 enum AMSubMode { 78 bad_am_submode = 0, 79 ia, 80 ib, 81 da, 82 db 83 }; 84 85 static inline const char *getAMSubModeStr(AMSubMode Mode) { 86 switch (Mode) { 87 default: assert(0 && "Unknown addressing sub-mode!"); 88 case ARM_AM::ia: return "ia"; 89 case ARM_AM::ib: return "ib"; 90 case ARM_AM::da: return "da"; 91 case ARM_AM::db: return "db"; 92 } 93 } 94 95 /// rotr32 - Rotate a 32-bit unsigned value right by a specified # bits. 96 /// 97 static inline unsigned rotr32(unsigned Val, unsigned Amt) { 98 assert(Amt < 32 && "Invalid rotate amount"); 99 return (Val >> Amt) | (Val << ((32-Amt)&31)); 100 } 101 102 /// rotl32 - Rotate a 32-bit unsigned value left by a specified # bits. 103 /// 104 static inline unsigned rotl32(unsigned Val, unsigned Amt) { 105 assert(Amt < 32 && "Invalid rotate amount"); 106 return (Val << Amt) | (Val >> ((32-Amt)&31)); 107 } 108 109 //===--------------------------------------------------------------------===// 110 // Addressing Mode #1: shift_operand with registers 111 //===--------------------------------------------------------------------===// 112 // 113 // This 'addressing mode' is used for arithmetic instructions. It can 114 // represent things like: 115 // reg 116 // reg [asr|lsl|lsr|ror|rrx] reg 117 // reg [asr|lsl|lsr|ror|rrx] imm 118 // 119 // This is stored three operands [rega, regb, opc]. The first is the base 120 // reg, the second is the shift amount (or reg0 if not present or imm). The 121 // third operand encodes the shift opcode and the imm if a reg isn't present. 122 // 123 static inline unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm) { 124 return ShOp | (Imm << 3); 125 } 126 static inline unsigned getSORegOffset(unsigned Op) { 127 return Op >> 3; 128 } 129 static inline ShiftOpc getSORegShOp(unsigned Op) { 130 return (ShiftOpc)(Op & 7); 131 } 132 133 /// getSOImmValImm - Given an encoded imm field for the reg/imm form, return 134 /// the 8-bit imm value. 135 static inline unsigned getSOImmValImm(unsigned Imm) { 136 return Imm & 0xFF; 137 } 138 /// getSOImmValRot - Given an encoded imm field for the reg/imm form, return 139 /// the rotate amount. 140 static inline unsigned getSOImmValRot(unsigned Imm) { 141 return (Imm >> 8) * 2; 142 } 143 144 /// getSOImmValRotate - Try to handle Imm with an immediate shifter operand, 145 /// computing the rotate amount to use. If this immediate value cannot be 146 /// handled with a single shifter-op, determine a good rotate amount that will 147 /// take a maximal chunk of bits out of the immediate. 148 static inline unsigned getSOImmValRotate(unsigned Imm) { 149 // 8-bit (or less) immediates are trivially shifter_operands with a rotate 150 // of zero. 151 if ((Imm & ~255U) == 0) return 0; 152 153 // Use CTZ to compute the rotate amount. 154 unsigned TZ = CountTrailingZeros_32(Imm); 155 156 // Rotate amount must be even. Something like 0x200 must be rotated 8 bits, 157 // not 9. 158 unsigned RotAmt = TZ & ~1; 159 160 // If we can handle this spread, return it. 161 if ((rotr32(Imm, RotAmt) & ~255U) == 0) 162 return (32-RotAmt)&31; // HW rotates right, not left. 163 164 // For values like 0xF000000F, we should ignore the low 6 bits, then 165 // retry the hunt. 166 if (Imm & 63U) { 167 unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U); 168 unsigned RotAmt2 = TZ2 & ~1; 169 if ((rotr32(Imm, RotAmt2) & ~255U) == 0) 170 return (32-RotAmt2)&31; // HW rotates right, not left. 171 } 172 173 // Otherwise, we have no way to cover this span of bits with a single 174 // shifter_op immediate. Return a chunk of bits that will be useful to 175 // handle. 176 return (32-RotAmt)&31; // HW rotates right, not left. 177 } 178 179 /// getSOImmVal - Given a 32-bit immediate, if it is something that can fit 180 /// into an shifter_operand immediate operand, return the 12-bit encoding for 181 /// it. If not, return -1. 182 static inline int getSOImmVal(unsigned Arg) { 183 // 8-bit (or less) immediates are trivially shifter_operands with a rotate 184 // of zero. 185 if ((Arg & ~255U) == 0) return Arg; 186 187 unsigned RotAmt = getSOImmValRotate(Arg); 188 189 // If this cannot be handled with a single shifter_op, bail out. 190 if (rotr32(~255U, RotAmt) & Arg) 191 return -1; 192 193 // Encode this correctly. 194 return rotl32(Arg, RotAmt) | ((RotAmt>>1) << 8); 195 } 196 197 /// isSOImmTwoPartVal - Return true if the specified value can be obtained by 198 /// or'ing together two SOImmVal's. 199 static inline bool isSOImmTwoPartVal(unsigned V) { 200 // If this can be handled with a single shifter_op, bail out. 201 V = rotr32(~255U, getSOImmValRotate(V)) & V; 202 if (V == 0) 203 return false; 204 205 // If this can be handled with two shifter_op's, accept. 206 V = rotr32(~255U, getSOImmValRotate(V)) & V; 207 return V == 0; 208 } 209 210 /// getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal, 211 /// return the first chunk of it. 212 static inline unsigned getSOImmTwoPartFirst(unsigned V) { 213 return rotr32(255U, getSOImmValRotate(V)) & V; 214 } 215 216 /// getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal, 217 /// return the second chunk of it. 218 static inline unsigned getSOImmTwoPartSecond(unsigned V) { 219 // Mask out the first hunk. 220 V = rotr32(~255U, getSOImmValRotate(V)) & V; 221 222 // Take what's left. 223 assert(V == (rotr32(255U, getSOImmValRotate(V)) & V)); 224 return V; 225 } 226 227 /// getThumbImmValShift - Try to handle Imm with a 8-bit immediate followed 228 /// by a left shift. Returns the shift amount to use. 229 static inline unsigned getThumbImmValShift(unsigned Imm) { 230 // 8-bit (or less) immediates are trivially immediate operand with a shift 231 // of zero. 232 if ((Imm & ~255U) == 0) return 0; 233 234 // Use CTZ to compute the shift amount. 235 return CountTrailingZeros_32(Imm); 236 } 237 238 /// isThumbImmShiftedVal - Return true if the specified value can be obtained 239 /// by left shifting a 8-bit immediate. 240 static inline bool isThumbImmShiftedVal(unsigned V) { 241 // If this can be handled with 242 V = (~255U << getThumbImmValShift(V)) & V; 243 return V == 0; 244 } 245 246 /// getThumbImm16ValShift - Try to handle Imm with a 16-bit immediate followed 247 /// by a left shift. Returns the shift amount to use. 248 static inline unsigned getThumbImm16ValShift(unsigned Imm) { 249 // 16-bit (or less) immediates are trivially immediate operand with a shift 250 // of zero. 251 if ((Imm & ~65535U) == 0) return 0; 252 253 // Use CTZ to compute the shift amount. 254 return CountTrailingZeros_32(Imm); 255 } 256 257 /// isThumbImm16ShiftedVal - Return true if the specified value can be 258 /// obtained by left shifting a 16-bit immediate. 259 static inline bool isThumbImm16ShiftedVal(unsigned V) { 260 // If this can be handled with 261 V = (~65535U << getThumbImm16ValShift(V)) & V; 262 return V == 0; 263 } 264 265 /// getThumbImmNonShiftedVal - If V is a value that satisfies 266 /// isThumbImmShiftedVal, return the non-shiftd value. 267 static inline unsigned getThumbImmNonShiftedVal(unsigned V) { 268 return V >> getThumbImmValShift(V); 269 } 270 271 272 /// getT2SOImmValSplat - Return the 12-bit encoded representation 273 /// if the specified value can be obtained by splatting the low 8 bits 274 /// into every other byte or every byte of a 32-bit value. i.e., 275 /// 00000000 00000000 00000000 abcdefgh control = 0 276 /// 00000000 abcdefgh 00000000 abcdefgh control = 1 277 /// abcdefgh 00000000 abcdefgh 00000000 control = 2 278 /// abcdefgh abcdefgh abcdefgh abcdefgh control = 3 279 /// Return -1 if none of the above apply. 280 /// See ARM Reference Manual A6.3.2. 281 static inline int getT2SOImmValSplatVal(unsigned V) { 282 unsigned u, Vs, Imm; 283 // control = 0 284 if ((V & 0xffffff00) == 0) 285 return V; 286 287 // If the value is zeroes in the first byte, just shift those off 288 Vs = ((V & 0xff) == 0) ? V >> 8 : V; 289 // Any passing value only has 8 bits of payload, splatted across the word 290 Imm = Vs & 0xff; 291 // Likewise, any passing values have the payload splatted into the 3rd byte 292 u = Imm | (Imm << 16); 293 294 // control = 1 or 2 295 if (Vs == u) 296 return (((Vs == V) ? 1 : 2) << 8) | Imm; 297 298 // control = 3 299 if (Vs == (u | (u << 8))) 300 return (3 << 8) | Imm; 301 302 return -1; 303 } 304 305 /// getT2SOImmValRotateVal - Return the 12-bit encoded representation if the 306 /// specified value is a rotated 8-bit value. Return -1 if no rotation 307 /// encoding is possible. 308 /// See ARM Reference Manual A6.3.2. 309 static inline int getT2SOImmValRotateVal(unsigned V) { 310 unsigned RotAmt = CountLeadingZeros_32(V); 311 if (RotAmt >= 24) 312 return -1; 313 314 // If 'Arg' can be handled with a single shifter_op return the value. 315 if ((rotr32(0xff000000U, RotAmt) & V) == V) 316 return (rotr32(V, 24 - RotAmt) & 0x7f) | ((RotAmt + 8) << 7); 317 318 return -1; 319 } 320 321 /// getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit 322 /// into a Thumb-2 shifter_operand immediate operand, return the 12-bit 323 /// encoding for it. If not, return -1. 324 /// See ARM Reference Manual A6.3.2. 325 static inline int getT2SOImmVal(unsigned Arg) { 326 // If 'Arg' is an 8-bit splat, then get the encoded value. 327 int Splat = getT2SOImmValSplatVal(Arg); 328 if (Splat != -1) 329 return Splat; 330 331 // If 'Arg' can be handled with a single shifter_op return the value. 332 int Rot = getT2SOImmValRotateVal(Arg); 333 if (Rot != -1) 334 return Rot; 335 336 return -1; 337 } 338 339 static inline unsigned getT2SOImmValRotate(unsigned V) { 340 if ((V & ~255U) == 0) return 0; 341 // Use CTZ to compute the rotate amount. 342 unsigned RotAmt = CountTrailingZeros_32(V); 343 return (32 - RotAmt) & 31; 344 } 345 346 static inline bool isT2SOImmTwoPartVal (unsigned Imm) { 347 unsigned V = Imm; 348 // Passing values can be any combination of splat values and shifter 349 // values. If this can be handled with a single shifter or splat, bail 350 // out. Those should be handled directly, not with a two-part val. 351 if (getT2SOImmValSplatVal(V) != -1) 352 return false; 353 V = rotr32 (~255U, getT2SOImmValRotate(V)) & V; 354 if (V == 0) 355 return false; 356 357 // If this can be handled as an immediate, accept. 358 if (getT2SOImmVal(V) != -1) return true; 359 360 // Likewise, try masking out a splat value first. 361 V = Imm; 362 if (getT2SOImmValSplatVal(V & 0xff00ff00U) != -1) 363 V &= ~0xff00ff00U; 364 else if (getT2SOImmValSplatVal(V & 0x00ff00ffU) != -1) 365 V &= ~0x00ff00ffU; 366 // If what's left can be handled as an immediate, accept. 367 if (getT2SOImmVal(V) != -1) return true; 368 369 // Otherwise, do not accept. 370 return false; 371 } 372 373 static inline unsigned getT2SOImmTwoPartFirst(unsigned Imm) { 374 assert (isT2SOImmTwoPartVal(Imm) && 375 "Immedate cannot be encoded as two part immediate!"); 376 // Try a shifter operand as one part 377 unsigned V = rotr32 (~255, getT2SOImmValRotate(Imm)) & Imm; 378 // If the rest is encodable as an immediate, then return it. 379 if (getT2SOImmVal(V) != -1) return V; 380 381 // Try masking out a splat value first. 382 if (getT2SOImmValSplatVal(Imm & 0xff00ff00U) != -1) 383 return Imm & 0xff00ff00U; 384 385 // The other splat is all that's left as an option. 386 assert (getT2SOImmValSplatVal(Imm & 0x00ff00ffU) != -1); 387 return Imm & 0x00ff00ffU; 388 } 389 390 static inline unsigned getT2SOImmTwoPartSecond(unsigned Imm) { 391 // Mask out the first hunk 392 Imm ^= getT2SOImmTwoPartFirst(Imm); 393 // Return what's left 394 assert (getT2SOImmVal(Imm) != -1 && 395 "Unable to encode second part of T2 two part SO immediate"); 396 return Imm; 397 } 398 399 400 //===--------------------------------------------------------------------===// 401 // Addressing Mode #2 402 //===--------------------------------------------------------------------===// 403 // 404 // This is used for most simple load/store instructions. 405 // 406 // addrmode2 := reg +/- reg shop imm 407 // addrmode2 := reg +/- imm12 408 // 409 // The first operand is always a Reg. The second operand is a reg if in 410 // reg/reg form, otherwise it's reg#0. The third field encodes the operation 411 // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The 412 // fourth operand 16-17 encodes the index mode. 413 // 414 // If this addressing mode is a frame index (before prolog/epilog insertion 415 // and code rewriting), this operand will have the form: FI#, reg0, <offs> 416 // with no shift amount for the frame offset. 417 // 418 static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, 419 unsigned IdxMode = 0) { 420 assert(Imm12 < (1 << 12) && "Imm too large!"); 421 bool isSub = Opc == sub; 422 return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ; 423 } 424 static inline unsigned getAM2Offset(unsigned AM2Opc) { 425 return AM2Opc & ((1 << 12)-1); 426 } 427 static inline AddrOpc getAM2Op(unsigned AM2Opc) { 428 return ((AM2Opc >> 12) & 1) ? sub : add; 429 } 430 static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) { 431 return (ShiftOpc)((AM2Opc >> 13) & 7); 432 } 433 static inline unsigned getAM2IdxMode(unsigned AM2Opc) { 434 return (AM2Opc >> 16); 435 } 436 437 438 //===--------------------------------------------------------------------===// 439 // Addressing Mode #3 440 //===--------------------------------------------------------------------===// 441 // 442 // This is used for sign-extending loads, and load/store-pair instructions. 443 // 444 // addrmode3 := reg +/- reg 445 // addrmode3 := reg +/- imm8 446 // 447 // The first operand is always a Reg. The second operand is a reg if in 448 // reg/reg form, otherwise it's reg#0. The third field encodes the operation 449 // in bit 8, the immediate in bits 0-7. The fourth operand 9-10 encodes the 450 // index mode. 451 452 /// getAM3Opc - This function encodes the addrmode3 opc field. 453 static inline unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset, 454 unsigned IdxMode = 0) { 455 bool isSub = Opc == sub; 456 return ((int)isSub << 8) | Offset | (IdxMode << 9); 457 } 458 static inline unsigned char getAM3Offset(unsigned AM3Opc) { 459 return AM3Opc & 0xFF; 460 } 461 static inline AddrOpc getAM3Op(unsigned AM3Opc) { 462 return ((AM3Opc >> 8) & 1) ? sub : add; 463 } 464 static inline unsigned getAM3IdxMode(unsigned AM3Opc) { 465 return (AM3Opc >> 9); 466 } 467 468 //===--------------------------------------------------------------------===// 469 // Addressing Mode #4 470 //===--------------------------------------------------------------------===// 471 // 472 // This is used for load / store multiple instructions. 473 // 474 // addrmode4 := reg, <mode> 475 // 476 // The four modes are: 477 // IA - Increment after 478 // IB - Increment before 479 // DA - Decrement after 480 // DB - Decrement before 481 // For VFP instructions, only the IA and DB modes are valid. 482 483 static inline AMSubMode getAM4SubMode(unsigned Mode) { 484 return (AMSubMode)(Mode & 0x7); 485 } 486 487 static inline unsigned getAM4ModeImm(AMSubMode SubMode) { 488 return (int)SubMode; 489 } 490 491 //===--------------------------------------------------------------------===// 492 // Addressing Mode #5 493 //===--------------------------------------------------------------------===// 494 // 495 // This is used for coprocessor instructions, such as FP load/stores. 496 // 497 // addrmode5 := reg +/- imm8*4 498 // 499 // The first operand is always a Reg. The second operand encodes the 500 // operation in bit 8 and the immediate in bits 0-7. 501 502 /// getAM5Opc - This function encodes the addrmode5 opc field. 503 static inline unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset) { 504 bool isSub = Opc == sub; 505 return ((int)isSub << 8) | Offset; 506 } 507 static inline unsigned char getAM5Offset(unsigned AM5Opc) { 508 return AM5Opc & 0xFF; 509 } 510 static inline AddrOpc getAM5Op(unsigned AM5Opc) { 511 return ((AM5Opc >> 8) & 1) ? sub : add; 512 } 513 514 //===--------------------------------------------------------------------===// 515 // Addressing Mode #6 516 //===--------------------------------------------------------------------===// 517 // 518 // This is used for NEON load / store instructions. 519 // 520 // addrmode6 := reg with optional alignment 521 // 522 // This is stored in two operands [regaddr, align]. The first is the 523 // address register. The second operand is the value of the alignment 524 // specifier in bytes or zero if no explicit alignment. 525 // Valid alignments depend on the specific instruction. 526 527 //===--------------------------------------------------------------------===// 528 // NEON Modified Immediates 529 //===--------------------------------------------------------------------===// 530 // 531 // Several NEON instructions (e.g., VMOV) take a "modified immediate" 532 // vector operand, where a small immediate encoded in the instruction 533 // specifies a full NEON vector value. These modified immediates are 534 // represented here as encoded integers. The low 8 bits hold the immediate 535 // value; bit 12 holds the "Op" field of the instruction, and bits 11-8 hold 536 // the "Cmode" field of the instruction. The interfaces below treat the 537 // Op and Cmode values as a single 5-bit value. 538 539 static inline unsigned createNEONModImm(unsigned OpCmode, unsigned Val) { 540 return (OpCmode << 8) | Val; 541 } 542 static inline unsigned getNEONModImmOpCmode(unsigned ModImm) { 543 return (ModImm >> 8) & 0x1f; 544 } 545 static inline unsigned getNEONModImmVal(unsigned ModImm) { 546 return ModImm & 0xff; 547 } 548 549 /// decodeNEONModImm - Decode a NEON modified immediate value into the 550 /// element value and the element size in bits. (If the element size is 551 /// smaller than the vector, it is splatted into all the elements.) 552 static inline uint64_t decodeNEONModImm(unsigned ModImm, unsigned &EltBits) { 553 unsigned OpCmode = getNEONModImmOpCmode(ModImm); 554 unsigned Imm8 = getNEONModImmVal(ModImm); 555 uint64_t Val = 0; 556 557 if (OpCmode == 0xe) { 558 // 8-bit vector elements 559 Val = Imm8; 560 EltBits = 8; 561 } else if ((OpCmode & 0xc) == 0x8) { 562 // 16-bit vector elements 563 unsigned ByteNum = (OpCmode & 0x6) >> 1; 564 Val = Imm8 << (8 * ByteNum); 565 EltBits = 16; 566 } else if ((OpCmode & 0x8) == 0) { 567 // 32-bit vector elements, zero with one byte set 568 unsigned ByteNum = (OpCmode & 0x6) >> 1; 569 Val = Imm8 << (8 * ByteNum); 570 EltBits = 32; 571 } else if ((OpCmode & 0xe) == 0xc) { 572 // 32-bit vector elements, one byte with low bits set 573 unsigned ByteNum = 1 + (OpCmode & 0x1); 574 Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum))); 575 EltBits = 32; 576 } else if (OpCmode == 0x1e) { 577 // 64-bit vector elements 578 for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) { 579 if ((ModImm >> ByteNum) & 1) 580 Val |= (uint64_t)0xff << (8 * ByteNum); 581 } 582 EltBits = 64; 583 } else { 584 assert(false && "Unsupported NEON immediate"); 585 } 586 return Val; 587 } 588 589 AMSubMode getLoadStoreMultipleSubMode(int Opcode); 590 591 } // end namespace ARM_AM 592 } // end namespace llvm 593 594 #endif 595 596