ARMMCCodeEmitter.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1//===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM code to machine code -------===// 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 implements the ARMMCCodeEmitter class. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "mccodeemitter" 15#include "MCTargetDesc/ARMMCTargetDesc.h" 16#include "MCTargetDesc/ARMAddressingModes.h" 17#include "MCTargetDesc/ARMBaseInfo.h" 18#include "MCTargetDesc/ARMFixupKinds.h" 19#include "MCTargetDesc/ARMMCExpr.h" 20#include "llvm/ADT/APFloat.h" 21#include "llvm/ADT/Statistic.h" 22#include "llvm/MC/MCCodeEmitter.h" 23#include "llvm/MC/MCContext.h" 24#include "llvm/MC/MCExpr.h" 25#include "llvm/MC/MCInst.h" 26#include "llvm/MC/MCInstrInfo.h" 27#include "llvm/MC/MCRegisterInfo.h" 28#include "llvm/MC/MCSubtargetInfo.h" 29#include "llvm/Support/ErrorHandling.h" 30#include "llvm/Support/raw_ostream.h" 31 32using namespace llvm; 33 34STATISTIC(MCNumEmitted, "Number of MC instructions emitted."); 35STATISTIC(MCNumCPRelocations, "Number of constant pool relocations created."); 36 37namespace { 38class ARMMCCodeEmitter : public MCCodeEmitter { 39 ARMMCCodeEmitter(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION; 40 void operator=(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION; 41 const MCInstrInfo &MCII; 42 const MCContext &CTX; 43 bool IsLittleEndian; 44 45public: 46 ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool IsLittle) 47 : MCII(mcii), CTX(ctx), IsLittleEndian(IsLittle) { 48 } 49 50 ~ARMMCCodeEmitter() {} 51 52 bool isThumb(const MCSubtargetInfo &STI) const { 53 return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 54 } 55 bool isThumb2(const MCSubtargetInfo &STI) const { 56 return isThumb(STI) && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0; 57 } 58 bool isTargetMachO(const MCSubtargetInfo &STI) const { 59 Triple TT(STI.getTargetTriple()); 60 return TT.isOSBinFormatMachO(); 61 } 62 63 unsigned getMachineSoImmOpValue(unsigned SoImm) const; 64 65 // getBinaryCodeForInstr - TableGen'erated function for getting the 66 // binary encoding for an instruction. 67 uint64_t getBinaryCodeForInstr(const MCInst &MI, 68 SmallVectorImpl<MCFixup> &Fixups, 69 const MCSubtargetInfo &STI) const; 70 71 /// getMachineOpValue - Return binary encoding of operand. If the machine 72 /// operand requires relocation, record the relocation and return zero. 73 unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO, 74 SmallVectorImpl<MCFixup> &Fixups, 75 const MCSubtargetInfo &STI) const; 76 77 /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of 78 /// the specified operand. This is used for operands with :lower16: and 79 /// :upper16: prefixes. 80 uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 81 SmallVectorImpl<MCFixup> &Fixups, 82 const MCSubtargetInfo &STI) const; 83 84 bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, 85 unsigned &Reg, unsigned &Imm, 86 SmallVectorImpl<MCFixup> &Fixups, 87 const MCSubtargetInfo &STI) const; 88 89 /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate 90 /// BL branch target. 91 uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 92 SmallVectorImpl<MCFixup> &Fixups, 93 const MCSubtargetInfo &STI) const; 94 95 /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 96 /// BLX branch target. 97 uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 98 SmallVectorImpl<MCFixup> &Fixups, 99 const MCSubtargetInfo &STI) const; 100 101 /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 102 uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 103 SmallVectorImpl<MCFixup> &Fixups, 104 const MCSubtargetInfo &STI) const; 105 106 /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 107 uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 108 SmallVectorImpl<MCFixup> &Fixups, 109 const MCSubtargetInfo &STI) const; 110 111 /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 112 uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 113 SmallVectorImpl<MCFixup> &Fixups, 114 const MCSubtargetInfo &STI) const; 115 116 /// getBranchTargetOpValue - Return encoding info for 24-bit immediate 117 /// branch target. 118 uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 119 SmallVectorImpl<MCFixup> &Fixups, 120 const MCSubtargetInfo &STI) const; 121 122 /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 123 /// immediate Thumb2 direct branch target. 124 uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 125 SmallVectorImpl<MCFixup> &Fixups, 126 const MCSubtargetInfo &STI) const; 127 128 /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate 129 /// branch target. 130 uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 131 SmallVectorImpl<MCFixup> &Fixups, 132 const MCSubtargetInfo &STI) const; 133 uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 134 SmallVectorImpl<MCFixup> &Fixups, 135 const MCSubtargetInfo &STI) const; 136 uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 137 SmallVectorImpl<MCFixup> &Fixups, 138 const MCSubtargetInfo &STI) const; 139 140 /// getAdrLabelOpValue - Return encoding info for 12-bit immediate 141 /// ADR label target. 142 uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 143 SmallVectorImpl<MCFixup> &Fixups, 144 const MCSubtargetInfo &STI) const; 145 uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 146 SmallVectorImpl<MCFixup> &Fixups, 147 const MCSubtargetInfo &STI) const; 148 uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 149 SmallVectorImpl<MCFixup> &Fixups, 150 const MCSubtargetInfo &STI) const; 151 152 153 /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' 154 /// operand. 155 uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 156 SmallVectorImpl<MCFixup> &Fixups, 157 const MCSubtargetInfo &STI) const; 158 159 /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand. 160 uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 161 SmallVectorImpl<MCFixup> &Fixups, 162 const MCSubtargetInfo &STI) const; 163 164 /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2' 165 /// operand. 166 uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 167 SmallVectorImpl<MCFixup> &Fixups, 168 const MCSubtargetInfo &STI) const; 169 170 /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2' 171 /// operand. 172 uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 173 SmallVectorImpl<MCFixup> &Fixups, 174 const MCSubtargetInfo &STI) const; 175 176 /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2' 177 /// operand. 178 uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 179 SmallVectorImpl<MCFixup> &Fixups, 180 const MCSubtargetInfo &STI) const; 181 182 183 /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm' 184 /// operand as needed by load/store instructions. 185 uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 186 SmallVectorImpl<MCFixup> &Fixups, 187 const MCSubtargetInfo &STI) const; 188 189 /// getLdStmModeOpValue - Return encoding for load/store multiple mode. 190 uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx, 191 SmallVectorImpl<MCFixup> &Fixups, 192 const MCSubtargetInfo &STI) const { 193 ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm(); 194 switch (Mode) { 195 default: llvm_unreachable("Unknown addressing sub-mode!"); 196 case ARM_AM::da: return 0; 197 case ARM_AM::ia: return 1; 198 case ARM_AM::db: return 2; 199 case ARM_AM::ib: return 3; 200 } 201 } 202 /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. 203 /// 204 unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const { 205 switch (ShOpc) { 206 case ARM_AM::no_shift: 207 case ARM_AM::lsl: return 0; 208 case ARM_AM::lsr: return 1; 209 case ARM_AM::asr: return 2; 210 case ARM_AM::ror: 211 case ARM_AM::rrx: return 3; 212 } 213 llvm_unreachable("Invalid ShiftOpc!"); 214 } 215 216 /// getAddrMode2OpValue - Return encoding for addrmode2 operands. 217 uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 218 SmallVectorImpl<MCFixup> &Fixups, 219 const MCSubtargetInfo &STI) const; 220 221 /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands. 222 uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 223 SmallVectorImpl<MCFixup> &Fixups, 224 const MCSubtargetInfo &STI) const; 225 226 /// getPostIdxRegOpValue - Return encoding for postidx_reg operands. 227 uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 228 SmallVectorImpl<MCFixup> &Fixups, 229 const MCSubtargetInfo &STI) const; 230 231 /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands. 232 uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 233 SmallVectorImpl<MCFixup> &Fixups, 234 const MCSubtargetInfo &STI) const; 235 236 /// getAddrMode3OpValue - Return encoding for addrmode3 operands. 237 uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 238 SmallVectorImpl<MCFixup> &Fixups, 239 const MCSubtargetInfo &STI) const; 240 241 /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12' 242 /// operand. 243 uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 244 SmallVectorImpl<MCFixup> &Fixups, 245 const MCSubtargetInfo &STI) const; 246 247 /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 248 uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 249 SmallVectorImpl<MCFixup> &Fixups, 250 const MCSubtargetInfo &STI) const; 251 252 /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 253 uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 254 SmallVectorImpl<MCFixup> &Fixups, 255 const MCSubtargetInfo &STI) const; 256 257 /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand. 258 uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 259 SmallVectorImpl<MCFixup> &Fixups, 260 const MCSubtargetInfo &STI) const; 261 262 /// getCCOutOpValue - Return encoding of the 's' bit. 263 unsigned getCCOutOpValue(const MCInst &MI, unsigned Op, 264 SmallVectorImpl<MCFixup> &Fixups, 265 const MCSubtargetInfo &STI) const { 266 // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or 267 // '1' respectively. 268 return MI.getOperand(Op).getReg() == ARM::CPSR; 269 } 270 271 /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value. 272 unsigned getSOImmOpValue(const MCInst &MI, unsigned Op, 273 SmallVectorImpl<MCFixup> &Fixups, 274 const MCSubtargetInfo &STI) const { 275 276 const MCOperand &MO = MI.getOperand(Op); 277 278 // We expect MO to be an immediate or an expression, 279 // if it is an immediate - that's fine, just encode the value. 280 // Otherwise - create a Fixup. 281 if (MO.isExpr()) { 282 const MCExpr *Expr = MO.getExpr(); 283 // In instruction code this value always encoded as lowest 12 bits, 284 // so we don't have to perform any specific adjustments. 285 // Due to requirements of relocatable records we have to use FK_Data_4. 286 // See ARMELFObjectWriter::ExplicitRelSym and 287 // ARMELFObjectWriter::GetRelocTypeInner for more details. 288 MCFixupKind Kind = MCFixupKind(FK_Data_4); 289 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 290 return 0; 291 } 292 293 unsigned SoImm = MO.getImm(); 294 int SoImmVal = ARM_AM::getSOImmVal(SoImm); 295 assert(SoImmVal != -1 && "Not a valid so_imm value!"); 296 297 // Encode rotate_imm. 298 unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1) 299 << ARMII::SoRotImmShift; 300 301 // Encode immed_8. 302 Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); 303 return Binary; 304 } 305 306 /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value. 307 unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op, 308 SmallVectorImpl<MCFixup> &Fixups, 309 const MCSubtargetInfo &STI) const { 310 unsigned SoImm = MI.getOperand(Op).getImm(); 311 unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm); 312 assert(Encoded != ~0U && "Not a Thumb2 so_imm value?"); 313 return Encoded; 314 } 315 316 unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 317 SmallVectorImpl<MCFixup> &Fixups, 318 const MCSubtargetInfo &STI) const; 319 unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 320 SmallVectorImpl<MCFixup> &Fixups, 321 const MCSubtargetInfo &STI) const; 322 unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 323 SmallVectorImpl<MCFixup> &Fixups, 324 const MCSubtargetInfo &STI) const; 325 unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 326 SmallVectorImpl<MCFixup> &Fixups, 327 const MCSubtargetInfo &STI) const; 328 329 /// getSORegOpValue - Return an encoded so_reg shifted register value. 330 unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op, 331 SmallVectorImpl<MCFixup> &Fixups, 332 const MCSubtargetInfo &STI) const; 333 unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op, 334 SmallVectorImpl<MCFixup> &Fixups, 335 const MCSubtargetInfo &STI) const; 336 unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op, 337 SmallVectorImpl<MCFixup> &Fixups, 338 const MCSubtargetInfo &STI) const; 339 340 unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op, 341 SmallVectorImpl<MCFixup> &Fixups, 342 const MCSubtargetInfo &STI) const { 343 return 64 - MI.getOperand(Op).getImm(); 344 } 345 346 unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 347 SmallVectorImpl<MCFixup> &Fixups, 348 const MCSubtargetInfo &STI) const; 349 350 unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op, 351 SmallVectorImpl<MCFixup> &Fixups, 352 const MCSubtargetInfo &STI) const; 353 unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 354 SmallVectorImpl<MCFixup> &Fixups, 355 const MCSubtargetInfo &STI) const; 356 unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 357 SmallVectorImpl<MCFixup> &Fixups, 358 const MCSubtargetInfo &STI) const; 359 unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 360 SmallVectorImpl<MCFixup> &Fixups, 361 const MCSubtargetInfo &STI) const; 362 unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 363 SmallVectorImpl<MCFixup> &Fixups, 364 const MCSubtargetInfo &STI) const; 365 366 unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op, 367 SmallVectorImpl<MCFixup> &Fixups, 368 const MCSubtargetInfo &STI) const; 369 unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op, 370 SmallVectorImpl<MCFixup> &Fixups, 371 const MCSubtargetInfo &STI) const; 372 unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op, 373 SmallVectorImpl<MCFixup> &Fixups, 374 const MCSubtargetInfo &STI) const; 375 unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op, 376 SmallVectorImpl<MCFixup> &Fixups, 377 const MCSubtargetInfo &STI) const; 378 379 unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op, 380 SmallVectorImpl<MCFixup> &Fixups, 381 const MCSubtargetInfo &STI) const; 382 383 unsigned NEONThumb2DataIPostEncoder(const MCInst &MI, 384 unsigned EncodedValue, 385 const MCSubtargetInfo &STI) const; 386 unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI, 387 unsigned EncodedValue, 388 const MCSubtargetInfo &STI) const; 389 unsigned NEONThumb2DupPostEncoder(const MCInst &MI, 390 unsigned EncodedValue, 391 const MCSubtargetInfo &STI) const; 392 unsigned NEONThumb2V8PostEncoder(const MCInst &MI, 393 unsigned EncodedValue, 394 const MCSubtargetInfo &STI) const; 395 396 unsigned VFPThumb2PostEncoder(const MCInst &MI, 397 unsigned EncodedValue, 398 const MCSubtargetInfo &STI) const; 399 400 void EmitByte(unsigned char C, raw_ostream &OS) const { 401 OS << (char)C; 402 } 403 404 void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const { 405 // Output the constant in little endian byte order. 406 for (unsigned i = 0; i != Size; ++i) { 407 unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 408 EmitByte((Val >> Shift) & 0xff, OS); 409 } 410 } 411 412 void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 413 SmallVectorImpl<MCFixup> &Fixups, 414 const MCSubtargetInfo &STI) const override; 415}; 416 417} // end anonymous namespace 418 419MCCodeEmitter *llvm::createARMLEMCCodeEmitter(const MCInstrInfo &MCII, 420 const MCRegisterInfo &MRI, 421 const MCSubtargetInfo &STI, 422 MCContext &Ctx) { 423 return new ARMMCCodeEmitter(MCII, Ctx, true); 424} 425 426MCCodeEmitter *llvm::createARMBEMCCodeEmitter(const MCInstrInfo &MCII, 427 const MCRegisterInfo &MRI, 428 const MCSubtargetInfo &STI, 429 MCContext &Ctx) { 430 return new ARMMCCodeEmitter(MCII, Ctx, false); 431} 432 433/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing 434/// instructions, and rewrite them to their Thumb2 form if we are currently in 435/// Thumb2 mode. 436unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI, 437 unsigned EncodedValue, 438 const MCSubtargetInfo &STI) const { 439 if (isThumb2(STI)) { 440 // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved 441 // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are 442 // set to 1111. 443 unsigned Bit24 = EncodedValue & 0x01000000; 444 unsigned Bit28 = Bit24 << 4; 445 EncodedValue &= 0xEFFFFFFF; 446 EncodedValue |= Bit28; 447 EncodedValue |= 0x0F000000; 448 } 449 450 return EncodedValue; 451} 452 453/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store 454/// instructions, and rewrite them to their Thumb2 form if we are currently in 455/// Thumb2 mode. 456unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI, 457 unsigned EncodedValue, 458 const MCSubtargetInfo &STI) const { 459 if (isThumb2(STI)) { 460 EncodedValue &= 0xF0FFFFFF; 461 EncodedValue |= 0x09000000; 462 } 463 464 return EncodedValue; 465} 466 467/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup 468/// instructions, and rewrite them to their Thumb2 form if we are currently in 469/// Thumb2 mode. 470unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI, 471 unsigned EncodedValue, 472 const MCSubtargetInfo &STI) const { 473 if (isThumb2(STI)) { 474 EncodedValue &= 0x00FFFFFF; 475 EncodedValue |= 0xEE000000; 476 } 477 478 return EncodedValue; 479} 480 481/// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form 482/// if we are in Thumb2. 483unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI, 484 unsigned EncodedValue, 485 const MCSubtargetInfo &STI) const { 486 if (isThumb2(STI)) { 487 EncodedValue |= 0xC000000; // Set bits 27-26 488 } 489 490 return EncodedValue; 491} 492 493/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite 494/// them to their Thumb2 form if we are currently in Thumb2 mode. 495unsigned ARMMCCodeEmitter:: 496VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue, 497 const MCSubtargetInfo &STI) const { 498 if (isThumb2(STI)) { 499 EncodedValue &= 0x0FFFFFFF; 500 EncodedValue |= 0xE0000000; 501 } 502 return EncodedValue; 503} 504 505/// getMachineOpValue - Return binary encoding of operand. If the machine 506/// operand requires relocation, record the relocation and return zero. 507unsigned ARMMCCodeEmitter:: 508getMachineOpValue(const MCInst &MI, const MCOperand &MO, 509 SmallVectorImpl<MCFixup> &Fixups, 510 const MCSubtargetInfo &STI) const { 511 if (MO.isReg()) { 512 unsigned Reg = MO.getReg(); 513 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg); 514 515 // Q registers are encoded as 2x their register number. 516 switch (Reg) { 517 default: 518 return RegNo; 519 case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3: 520 case ARM::Q4: case ARM::Q5: case ARM::Q6: case ARM::Q7: 521 case ARM::Q8: case ARM::Q9: case ARM::Q10: case ARM::Q11: 522 case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15: 523 return 2 * RegNo; 524 } 525 } else if (MO.isImm()) { 526 return static_cast<unsigned>(MO.getImm()); 527 } else if (MO.isFPImm()) { 528 return static_cast<unsigned>(APFloat(MO.getFPImm()) 529 .bitcastToAPInt().getHiBits(32).getLimitedValue()); 530 } 531 532 llvm_unreachable("Unable to encode MCOperand!"); 533} 534 535/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand. 536bool ARMMCCodeEmitter:: 537EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg, 538 unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups, 539 const MCSubtargetInfo &STI) const { 540 const MCOperand &MO = MI.getOperand(OpIdx); 541 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 542 543 Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 544 545 int32_t SImm = MO1.getImm(); 546 bool isAdd = true; 547 548 // Special value for #-0 549 if (SImm == INT32_MIN) { 550 SImm = 0; 551 isAdd = false; 552 } 553 554 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 555 if (SImm < 0) { 556 SImm = -SImm; 557 isAdd = false; 558 } 559 560 Imm = SImm; 561 return isAdd; 562} 563 564/// getBranchTargetOpValue - Helper function to get the branch target operand, 565/// which is either an immediate or requires a fixup. 566static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 567 unsigned FixupKind, 568 SmallVectorImpl<MCFixup> &Fixups, 569 const MCSubtargetInfo &STI) { 570 const MCOperand &MO = MI.getOperand(OpIdx); 571 572 // If the destination is an immediate, we have nothing to do. 573 if (MO.isImm()) return MO.getImm(); 574 assert(MO.isExpr() && "Unexpected branch target type!"); 575 const MCExpr *Expr = MO.getExpr(); 576 MCFixupKind Kind = MCFixupKind(FixupKind); 577 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 578 579 // All of the information is in the fixup. 580 return 0; 581} 582 583// Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are 584// determined by negating them and XOR'ing them with bit 23. 585static int32_t encodeThumbBLOffset(int32_t offset) { 586 offset >>= 1; 587 uint32_t S = (offset & 0x800000) >> 23; 588 uint32_t J1 = (offset & 0x400000) >> 22; 589 uint32_t J2 = (offset & 0x200000) >> 21; 590 J1 = (~J1 & 0x1); 591 J2 = (~J2 & 0x1); 592 J1 ^= S; 593 J2 ^= S; 594 595 offset &= ~0x600000; 596 offset |= J1 << 22; 597 offset |= J2 << 21; 598 599 return offset; 600} 601 602/// getThumbBLTargetOpValue - Return encoding info for immediate branch target. 603uint32_t ARMMCCodeEmitter:: 604getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 605 SmallVectorImpl<MCFixup> &Fixups, 606 const MCSubtargetInfo &STI) const { 607 const MCOperand MO = MI.getOperand(OpIdx); 608 if (MO.isExpr()) 609 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl, 610 Fixups, STI); 611 return encodeThumbBLOffset(MO.getImm()); 612} 613 614/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 615/// BLX branch target. 616uint32_t ARMMCCodeEmitter:: 617getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 618 SmallVectorImpl<MCFixup> &Fixups, 619 const MCSubtargetInfo &STI) const { 620 const MCOperand MO = MI.getOperand(OpIdx); 621 if (MO.isExpr()) 622 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx, 623 Fixups, STI); 624 return encodeThumbBLOffset(MO.getImm()); 625} 626 627/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 628uint32_t ARMMCCodeEmitter:: 629getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 630 SmallVectorImpl<MCFixup> &Fixups, 631 const MCSubtargetInfo &STI) const { 632 const MCOperand MO = MI.getOperand(OpIdx); 633 if (MO.isExpr()) 634 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br, 635 Fixups, STI); 636 return (MO.getImm() >> 1); 637} 638 639/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 640uint32_t ARMMCCodeEmitter:: 641getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 642 SmallVectorImpl<MCFixup> &Fixups, 643 const MCSubtargetInfo &STI) const { 644 const MCOperand MO = MI.getOperand(OpIdx); 645 if (MO.isExpr()) 646 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc, 647 Fixups, STI); 648 return (MO.getImm() >> 1); 649} 650 651/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 652uint32_t ARMMCCodeEmitter:: 653getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 654 SmallVectorImpl<MCFixup> &Fixups, 655 const MCSubtargetInfo &STI) const { 656 const MCOperand MO = MI.getOperand(OpIdx); 657 if (MO.isExpr()) 658 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups, STI); 659 return (MO.getImm() >> 1); 660} 661 662/// Return true if this branch has a non-always predication 663static bool HasConditionalBranch(const MCInst &MI) { 664 int NumOp = MI.getNumOperands(); 665 if (NumOp >= 2) { 666 for (int i = 0; i < NumOp-1; ++i) { 667 const MCOperand &MCOp1 = MI.getOperand(i); 668 const MCOperand &MCOp2 = MI.getOperand(i + 1); 669 if (MCOp1.isImm() && MCOp2.isReg() && 670 (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) { 671 if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL) 672 return true; 673 } 674 } 675 } 676 return false; 677} 678 679/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 680/// target. 681uint32_t ARMMCCodeEmitter:: 682getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 683 SmallVectorImpl<MCFixup> &Fixups, 684 const MCSubtargetInfo &STI) const { 685 // FIXME: This really, really shouldn't use TargetMachine. We don't want 686 // coupling between MC and TM anywhere we can help it. 687 if (isThumb2(STI)) 688 return 689 ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups, STI); 690 return getARMBranchTargetOpValue(MI, OpIdx, Fixups, STI); 691} 692 693/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 694/// target. 695uint32_t ARMMCCodeEmitter:: 696getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 697 SmallVectorImpl<MCFixup> &Fixups, 698 const MCSubtargetInfo &STI) const { 699 const MCOperand MO = MI.getOperand(OpIdx); 700 if (MO.isExpr()) { 701 if (HasConditionalBranch(MI)) 702 return ::getBranchTargetOpValue(MI, OpIdx, 703 ARM::fixup_arm_condbranch, Fixups, STI); 704 return ::getBranchTargetOpValue(MI, OpIdx, 705 ARM::fixup_arm_uncondbranch, Fixups, STI); 706 } 707 708 return MO.getImm() >> 2; 709} 710 711uint32_t ARMMCCodeEmitter:: 712getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 713 SmallVectorImpl<MCFixup> &Fixups, 714 const MCSubtargetInfo &STI) const { 715 const MCOperand MO = MI.getOperand(OpIdx); 716 if (MO.isExpr()) { 717 if (HasConditionalBranch(MI)) 718 return ::getBranchTargetOpValue(MI, OpIdx, 719 ARM::fixup_arm_condbl, Fixups, STI); 720 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups, STI); 721 } 722 723 return MO.getImm() >> 2; 724} 725 726uint32_t ARMMCCodeEmitter:: 727getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 728 SmallVectorImpl<MCFixup> &Fixups, 729 const MCSubtargetInfo &STI) const { 730 const MCOperand MO = MI.getOperand(OpIdx); 731 if (MO.isExpr()) 732 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx, Fixups, STI); 733 734 return MO.getImm() >> 1; 735} 736 737/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 738/// immediate branch target. 739uint32_t ARMMCCodeEmitter:: 740getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 741 SmallVectorImpl<MCFixup> &Fixups, 742 const MCSubtargetInfo &STI) const { 743 unsigned Val = 0; 744 const MCOperand MO = MI.getOperand(OpIdx); 745 746 if(MO.isExpr()) 747 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups, STI); 748 else 749 Val = MO.getImm() >> 1; 750 751 bool I = (Val & 0x800000); 752 bool J1 = (Val & 0x400000); 753 bool J2 = (Val & 0x200000); 754 if (I ^ J1) 755 Val &= ~0x400000; 756 else 757 Val |= 0x400000; 758 759 if (I ^ J2) 760 Val &= ~0x200000; 761 else 762 Val |= 0x200000; 763 764 return Val; 765} 766 767/// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate 768/// ADR label target. 769uint32_t ARMMCCodeEmitter:: 770getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 771 SmallVectorImpl<MCFixup> &Fixups, 772 const MCSubtargetInfo &STI) const { 773 const MCOperand MO = MI.getOperand(OpIdx); 774 if (MO.isExpr()) 775 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12, 776 Fixups, STI); 777 int64_t offset = MO.getImm(); 778 uint32_t Val = 0x2000; 779 780 int SoImmVal; 781 if (offset == INT32_MIN) { 782 Val = 0x1000; 783 SoImmVal = 0; 784 } else if (offset < 0) { 785 Val = 0x1000; 786 offset *= -1; 787 SoImmVal = ARM_AM::getSOImmVal(offset); 788 if(SoImmVal == -1) { 789 Val = 0x2000; 790 offset *= -1; 791 SoImmVal = ARM_AM::getSOImmVal(offset); 792 } 793 } else { 794 SoImmVal = ARM_AM::getSOImmVal(offset); 795 if(SoImmVal == -1) { 796 Val = 0x1000; 797 offset *= -1; 798 SoImmVal = ARM_AM::getSOImmVal(offset); 799 } 800 } 801 802 assert(SoImmVal != -1 && "Not a valid so_imm value!"); 803 804 Val |= SoImmVal; 805 return Val; 806} 807 808/// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label 809/// target. 810uint32_t ARMMCCodeEmitter:: 811getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 812 SmallVectorImpl<MCFixup> &Fixups, 813 const MCSubtargetInfo &STI) const { 814 const MCOperand MO = MI.getOperand(OpIdx); 815 if (MO.isExpr()) 816 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, 817 Fixups, STI); 818 int32_t Val = MO.getImm(); 819 if (Val == INT32_MIN) 820 Val = 0x1000; 821 else if (Val < 0) { 822 Val *= -1; 823 Val |= 0x1000; 824 } 825 return Val; 826} 827 828/// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label 829/// target. 830uint32_t ARMMCCodeEmitter:: 831getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 832 SmallVectorImpl<MCFixup> &Fixups, 833 const MCSubtargetInfo &STI) const { 834 const MCOperand MO = MI.getOperand(OpIdx); 835 if (MO.isExpr()) 836 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10, 837 Fixups, STI); 838 return MO.getImm(); 839} 840 841/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg' 842/// operand. 843uint32_t ARMMCCodeEmitter:: 844getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 845 SmallVectorImpl<MCFixup> &, 846 const MCSubtargetInfo &STI) const { 847 // [Rn, Rm] 848 // {5-3} = Rm 849 // {2-0} = Rn 850 const MCOperand &MO1 = MI.getOperand(OpIdx); 851 const MCOperand &MO2 = MI.getOperand(OpIdx + 1); 852 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 853 unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO2.getReg()); 854 return (Rm << 3) | Rn; 855} 856 857/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand. 858uint32_t ARMMCCodeEmitter:: 859getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 860 SmallVectorImpl<MCFixup> &Fixups, 861 const MCSubtargetInfo &STI) const { 862 // {17-13} = reg 863 // {12} = (U)nsigned (add == '1', sub == '0') 864 // {11-0} = imm12 865 unsigned Reg, Imm12; 866 bool isAdd = true; 867 // If The first operand isn't a register, we have a label reference. 868 const MCOperand &MO = MI.getOperand(OpIdx); 869 if (!MO.isReg()) { 870 Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 871 Imm12 = 0; 872 873 if (MO.isExpr()) { 874 const MCExpr *Expr = MO.getExpr(); 875 isAdd = false ; // 'U' bit is set as part of the fixup. 876 877 MCFixupKind Kind; 878 if (isThumb2(STI)) 879 Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12); 880 else 881 Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12); 882 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 883 884 ++MCNumCPRelocations; 885 } else { 886 Reg = ARM::PC; 887 int32_t Offset = MO.getImm(); 888 if (Offset == INT32_MIN) { 889 Offset = 0; 890 isAdd = false; 891 } else if (Offset < 0) { 892 Offset *= -1; 893 isAdd = false; 894 } 895 Imm12 = Offset; 896 } 897 } else 898 isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups, STI); 899 900 uint32_t Binary = Imm12 & 0xfff; 901 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 902 if (isAdd) 903 Binary |= (1 << 12); 904 Binary |= (Reg << 13); 905 return Binary; 906} 907 908/// getT2Imm8s4OpValue - Return encoding info for 909/// '+/- imm8<<2' operand. 910uint32_t ARMMCCodeEmitter:: 911getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 912 SmallVectorImpl<MCFixup> &Fixups, 913 const MCSubtargetInfo &STI) const { 914 // FIXME: The immediate operand should have already been encoded like this 915 // before ever getting here. The encoder method should just need to combine 916 // the MI operands for the register and the offset into a single 917 // representation for the complex operand in the .td file. This isn't just 918 // style, unfortunately. As-is, we can't represent the distinct encoding 919 // for #-0. 920 921 // {8} = (U)nsigned (add == '1', sub == '0') 922 // {7-0} = imm8 923 int32_t Imm8 = MI.getOperand(OpIdx).getImm(); 924 bool isAdd = Imm8 >= 0; 925 926 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 927 if (Imm8 < 0) 928 Imm8 = -(uint32_t)Imm8; 929 930 // Scaled by 4. 931 Imm8 /= 4; 932 933 uint32_t Binary = Imm8 & 0xff; 934 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 935 if (isAdd) 936 Binary |= (1 << 8); 937 return Binary; 938} 939 940/// getT2AddrModeImm8s4OpValue - Return encoding info for 941/// 'reg +/- imm8<<2' operand. 942uint32_t ARMMCCodeEmitter:: 943getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 944 SmallVectorImpl<MCFixup> &Fixups, 945 const MCSubtargetInfo &STI) const { 946 // {12-9} = reg 947 // {8} = (U)nsigned (add == '1', sub == '0') 948 // {7-0} = imm8 949 unsigned Reg, Imm8; 950 bool isAdd = true; 951 // If The first operand isn't a register, we have a label reference. 952 const MCOperand &MO = MI.getOperand(OpIdx); 953 if (!MO.isReg()) { 954 Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 955 Imm8 = 0; 956 isAdd = false ; // 'U' bit is set as part of the fixup. 957 958 assert(MO.isExpr() && "Unexpected machine operand type!"); 959 const MCExpr *Expr = MO.getExpr(); 960 MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 961 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 962 963 ++MCNumCPRelocations; 964 } else 965 isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI); 966 967 // FIXME: The immediate operand should have already been encoded like this 968 // before ever getting here. The encoder method should just need to combine 969 // the MI operands for the register and the offset into a single 970 // representation for the complex operand in the .td file. This isn't just 971 // style, unfortunately. As-is, we can't represent the distinct encoding 972 // for #-0. 973 uint32_t Binary = (Imm8 >> 2) & 0xff; 974 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 975 if (isAdd) 976 Binary |= (1 << 8); 977 Binary |= (Reg << 9); 978 return Binary; 979} 980 981/// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 982/// 'reg + imm8<<2' operand. 983uint32_t ARMMCCodeEmitter:: 984getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 985 SmallVectorImpl<MCFixup> &Fixups, 986 const MCSubtargetInfo &STI) const { 987 // {11-8} = reg 988 // {7-0} = imm8 989 const MCOperand &MO = MI.getOperand(OpIdx); 990 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 991 unsigned Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 992 unsigned Imm8 = MO1.getImm(); 993 return (Reg << 8) | Imm8; 994} 995 996uint32_t 997ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 998 SmallVectorImpl<MCFixup> &Fixups, 999 const MCSubtargetInfo &STI) const { 1000 // {20-16} = imm{15-12} 1001 // {11-0} = imm{11-0} 1002 const MCOperand &MO = MI.getOperand(OpIdx); 1003 if (MO.isImm()) 1004 // Hi / lo 16 bits already extracted during earlier passes. 1005 return static_cast<unsigned>(MO.getImm()); 1006 1007 // Handle :upper16: and :lower16: assembly prefixes. 1008 const MCExpr *E = MO.getExpr(); 1009 MCFixupKind Kind; 1010 if (E->getKind() == MCExpr::Target) { 1011 const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E); 1012 E = ARM16Expr->getSubExpr(); 1013 1014 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(E)) { 1015 const int64_t Value = MCE->getValue(); 1016 if (Value > UINT32_MAX) 1017 report_fatal_error("constant value truncated (limited to 32-bit)"); 1018 1019 switch (ARM16Expr->getKind()) { 1020 case ARMMCExpr::VK_ARM_HI16: 1021 return (int32_t(Value) & 0xffff0000) >> 16; 1022 case ARMMCExpr::VK_ARM_LO16: 1023 return (int32_t(Value) & 0x0000ffff); 1024 default: llvm_unreachable("Unsupported ARMFixup"); 1025 } 1026 } 1027 1028 switch (ARM16Expr->getKind()) { 1029 default: llvm_unreachable("Unsupported ARMFixup"); 1030 case ARMMCExpr::VK_ARM_HI16: 1031 Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movt_hi16 1032 : ARM::fixup_arm_movt_hi16); 1033 break; 1034 case ARMMCExpr::VK_ARM_LO16: 1035 Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movw_lo16 1036 : ARM::fixup_arm_movw_lo16); 1037 break; 1038 } 1039 Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc())); 1040 return 0; 1041 } 1042 // If the expression doesn't have :upper16: or :lower16: on it, 1043 // it's just a plain immediate expression, and those evaluate to 1044 // the lower 16 bits of the expression regardless of whether 1045 // we have a movt or a movw. 1046 Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movw_lo16 1047 : ARM::fixup_arm_movw_lo16); 1048 Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc())); 1049 return 0; 1050} 1051 1052uint32_t ARMMCCodeEmitter:: 1053getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 1054 SmallVectorImpl<MCFixup> &Fixups, 1055 const MCSubtargetInfo &STI) const { 1056 const MCOperand &MO = MI.getOperand(OpIdx); 1057 const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1058 const MCOperand &MO2 = MI.getOperand(OpIdx+2); 1059 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1060 unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 1061 unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()); 1062 bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add; 1063 ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm()); 1064 unsigned SBits = getShiftOp(ShOp); 1065 1066 // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift 1067 // amount. However, it would be an easy mistake to make so check here. 1068 assert((ShImm & ~0x1f) == 0 && "Out of range shift amount"); 1069 1070 // {16-13} = Rn 1071 // {12} = isAdd 1072 // {11-0} = shifter 1073 // {3-0} = Rm 1074 // {4} = 0 1075 // {6-5} = type 1076 // {11-7} = imm 1077 uint32_t Binary = Rm; 1078 Binary |= Rn << 13; 1079 Binary |= SBits << 5; 1080 Binary |= ShImm << 7; 1081 if (isAdd) 1082 Binary |= 1 << 12; 1083 return Binary; 1084} 1085 1086uint32_t ARMMCCodeEmitter:: 1087getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 1088 SmallVectorImpl<MCFixup> &Fixups, 1089 const MCSubtargetInfo &STI) const { 1090 // {17-14} Rn 1091 // {13} 1 == imm12, 0 == Rm 1092 // {12} isAdd 1093 // {11-0} imm12/Rm 1094 const MCOperand &MO = MI.getOperand(OpIdx); 1095 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1096 uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups, STI); 1097 Binary |= Rn << 14; 1098 return Binary; 1099} 1100 1101uint32_t ARMMCCodeEmitter:: 1102getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 1103 SmallVectorImpl<MCFixup> &Fixups, 1104 const MCSubtargetInfo &STI) const { 1105 // {13} 1 == imm12, 0 == Rm 1106 // {12} isAdd 1107 // {11-0} imm12/Rm 1108 const MCOperand &MO = MI.getOperand(OpIdx); 1109 const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1110 unsigned Imm = MO1.getImm(); 1111 bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add; 1112 bool isReg = MO.getReg() != 0; 1113 uint32_t Binary = ARM_AM::getAM2Offset(Imm); 1114 // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12 1115 if (isReg) { 1116 ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm); 1117 Binary <<= 7; // Shift amount is bits [11:7] 1118 Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5] 1119 Binary |= CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); // Rm is bits [3:0] 1120 } 1121 return Binary | (isAdd << 12) | (isReg << 13); 1122} 1123 1124uint32_t ARMMCCodeEmitter:: 1125getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 1126 SmallVectorImpl<MCFixup> &Fixups, 1127 const MCSubtargetInfo &STI) const { 1128 // {4} isAdd 1129 // {3-0} Rm 1130 const MCOperand &MO = MI.getOperand(OpIdx); 1131 const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1132 bool isAdd = MO1.getImm() != 0; 1133 return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()) | (isAdd << 4); 1134} 1135 1136uint32_t ARMMCCodeEmitter:: 1137getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 1138 SmallVectorImpl<MCFixup> &Fixups, 1139 const MCSubtargetInfo &STI) const { 1140 // {9} 1 == imm8, 0 == Rm 1141 // {8} isAdd 1142 // {7-4} imm7_4/zero 1143 // {3-0} imm3_0/Rm 1144 const MCOperand &MO = MI.getOperand(OpIdx); 1145 const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1146 unsigned Imm = MO1.getImm(); 1147 bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 1148 bool isImm = MO.getReg() == 0; 1149 uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 1150 // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 1151 if (!isImm) 1152 Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1153 return Imm8 | (isAdd << 8) | (isImm << 9); 1154} 1155 1156uint32_t ARMMCCodeEmitter:: 1157getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 1158 SmallVectorImpl<MCFixup> &Fixups, 1159 const MCSubtargetInfo &STI) const { 1160 // {13} 1 == imm8, 0 == Rm 1161 // {12-9} Rn 1162 // {8} isAdd 1163 // {7-4} imm7_4/zero 1164 // {3-0} imm3_0/Rm 1165 const MCOperand &MO = MI.getOperand(OpIdx); 1166 const MCOperand &MO1 = MI.getOperand(OpIdx+1); 1167 const MCOperand &MO2 = MI.getOperand(OpIdx+2); 1168 1169 // If The first operand isn't a register, we have a label reference. 1170 if (!MO.isReg()) { 1171 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 1172 1173 assert(MO.isExpr() && "Unexpected machine operand type!"); 1174 const MCExpr *Expr = MO.getExpr(); 1175 MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled); 1176 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 1177 1178 ++MCNumCPRelocations; 1179 return (Rn << 9) | (1 << 13); 1180 } 1181 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1182 unsigned Imm = MO2.getImm(); 1183 bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 1184 bool isImm = MO1.getReg() == 0; 1185 uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 1186 // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 1187 if (!isImm) 1188 Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 1189 return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13); 1190} 1191 1192/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands. 1193uint32_t ARMMCCodeEmitter:: 1194getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 1195 SmallVectorImpl<MCFixup> &Fixups, 1196 const MCSubtargetInfo &STI) const { 1197 // [SP, #imm] 1198 // {7-0} = imm8 1199 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1200 assert(MI.getOperand(OpIdx).getReg() == ARM::SP && 1201 "Unexpected base register!"); 1202 1203 // The immediate is already shifted for the implicit zeroes, so no change 1204 // here. 1205 return MO1.getImm() & 0xff; 1206} 1207 1208/// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 1209uint32_t ARMMCCodeEmitter:: 1210getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 1211 SmallVectorImpl<MCFixup> &Fixups, 1212 const MCSubtargetInfo &STI) const { 1213 // [Rn, #imm] 1214 // {7-3} = imm5 1215 // {2-0} = Rn 1216 const MCOperand &MO = MI.getOperand(OpIdx); 1217 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1218 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1219 unsigned Imm5 = MO1.getImm(); 1220 return ((Imm5 & 0x1f) << 3) | Rn; 1221} 1222 1223/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 1224uint32_t ARMMCCodeEmitter:: 1225getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 1226 SmallVectorImpl<MCFixup> &Fixups, 1227 const MCSubtargetInfo &STI) const { 1228 const MCOperand MO = MI.getOperand(OpIdx); 1229 if (MO.isExpr()) 1230 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups, STI); 1231 return (MO.getImm() >> 2); 1232} 1233 1234/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand. 1235uint32_t ARMMCCodeEmitter:: 1236getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 1237 SmallVectorImpl<MCFixup> &Fixups, 1238 const MCSubtargetInfo &STI) const { 1239 // {12-9} = reg 1240 // {8} = (U)nsigned (add == '1', sub == '0') 1241 // {7-0} = imm8 1242 unsigned Reg, Imm8; 1243 bool isAdd; 1244 // If The first operand isn't a register, we have a label reference. 1245 const MCOperand &MO = MI.getOperand(OpIdx); 1246 if (!MO.isReg()) { 1247 Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 1248 Imm8 = 0; 1249 isAdd = false; // 'U' bit is handled as part of the fixup. 1250 1251 assert(MO.isExpr() && "Unexpected machine operand type!"); 1252 const MCExpr *Expr = MO.getExpr(); 1253 MCFixupKind Kind; 1254 if (isThumb2(STI)) 1255 Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 1256 else 1257 Kind = MCFixupKind(ARM::fixup_arm_pcrel_10); 1258 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 1259 1260 ++MCNumCPRelocations; 1261 } else { 1262 EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI); 1263 isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add; 1264 } 1265 1266 uint32_t Binary = ARM_AM::getAM5Offset(Imm8); 1267 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 1268 if (isAdd) 1269 Binary |= (1 << 8); 1270 Binary |= (Reg << 9); 1271 return Binary; 1272} 1273 1274unsigned ARMMCCodeEmitter:: 1275getSORegRegOpValue(const MCInst &MI, unsigned OpIdx, 1276 SmallVectorImpl<MCFixup> &Fixups, 1277 const MCSubtargetInfo &STI) const { 1278 // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be 1279 // shifted. The second is Rs, the amount to shift by, and the third specifies 1280 // the type of the shift. 1281 // 1282 // {3-0} = Rm. 1283 // {4} = 1 1284 // {6-5} = type 1285 // {11-8} = Rs 1286 // {7} = 0 1287 1288 const MCOperand &MO = MI.getOperand(OpIdx); 1289 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1290 const MCOperand &MO2 = MI.getOperand(OpIdx + 2); 1291 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm()); 1292 1293 // Encode Rm. 1294 unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1295 1296 // Encode the shift opcode. 1297 unsigned SBits = 0; 1298 unsigned Rs = MO1.getReg(); 1299 if (Rs) { 1300 // Set shift operand (bit[7:4]). 1301 // LSL - 0001 1302 // LSR - 0011 1303 // ASR - 0101 1304 // ROR - 0111 1305 switch (SOpc) { 1306 default: llvm_unreachable("Unknown shift opc!"); 1307 case ARM_AM::lsl: SBits = 0x1; break; 1308 case ARM_AM::lsr: SBits = 0x3; break; 1309 case ARM_AM::asr: SBits = 0x5; break; 1310 case ARM_AM::ror: SBits = 0x7; break; 1311 } 1312 } 1313 1314 Binary |= SBits << 4; 1315 1316 // Encode the shift operation Rs. 1317 // Encode Rs bit[11:8]. 1318 assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0); 1319 return Binary | (CTX.getRegisterInfo()->getEncodingValue(Rs) << ARMII::RegRsShift); 1320} 1321 1322unsigned ARMMCCodeEmitter:: 1323getSORegImmOpValue(const MCInst &MI, unsigned OpIdx, 1324 SmallVectorImpl<MCFixup> &Fixups, 1325 const MCSubtargetInfo &STI) const { 1326 // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 1327 // shifted. The second is the amount to shift by. 1328 // 1329 // {3-0} = Rm. 1330 // {4} = 0 1331 // {6-5} = type 1332 // {11-7} = imm 1333 1334 const MCOperand &MO = MI.getOperand(OpIdx); 1335 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1336 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 1337 1338 // Encode Rm. 1339 unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1340 1341 // Encode the shift opcode. 1342 unsigned SBits = 0; 1343 1344 // Set shift operand (bit[6:4]). 1345 // LSL - 000 1346 // LSR - 010 1347 // ASR - 100 1348 // ROR - 110 1349 // RRX - 110 and bit[11:8] clear. 1350 switch (SOpc) { 1351 default: llvm_unreachable("Unknown shift opc!"); 1352 case ARM_AM::lsl: SBits = 0x0; break; 1353 case ARM_AM::lsr: SBits = 0x2; break; 1354 case ARM_AM::asr: SBits = 0x4; break; 1355 case ARM_AM::ror: SBits = 0x6; break; 1356 case ARM_AM::rrx: 1357 Binary |= 0x60; 1358 return Binary; 1359 } 1360 1361 // Encode shift_imm bit[11:7]. 1362 Binary |= SBits << 4; 1363 unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm()); 1364 assert(Offset < 32 && "Offset must be in range 0-31!"); 1365 return Binary | (Offset << 7); 1366} 1367 1368 1369unsigned ARMMCCodeEmitter:: 1370getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 1371 SmallVectorImpl<MCFixup> &Fixups, 1372 const MCSubtargetInfo &STI) const { 1373 const MCOperand &MO1 = MI.getOperand(OpNum); 1374 const MCOperand &MO2 = MI.getOperand(OpNum+1); 1375 const MCOperand &MO3 = MI.getOperand(OpNum+2); 1376 1377 // Encoded as [Rn, Rm, imm]. 1378 // FIXME: Needs fixup support. 1379 unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 1380 Value <<= 4; 1381 Value |= CTX.getRegisterInfo()->getEncodingValue(MO2.getReg()); 1382 Value <<= 2; 1383 Value |= MO3.getImm(); 1384 1385 return Value; 1386} 1387 1388unsigned ARMMCCodeEmitter:: 1389getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 1390 SmallVectorImpl<MCFixup> &Fixups, 1391 const MCSubtargetInfo &STI) const { 1392 const MCOperand &MO1 = MI.getOperand(OpNum); 1393 const MCOperand &MO2 = MI.getOperand(OpNum+1); 1394 1395 // FIXME: Needs fixup support. 1396 unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 1397 1398 // Even though the immediate is 8 bits long, we need 9 bits in order 1399 // to represent the (inverse of the) sign bit. 1400 Value <<= 9; 1401 int32_t tmp = (int32_t)MO2.getImm(); 1402 if (tmp < 0) 1403 tmp = abs(tmp); 1404 else 1405 Value |= 256; // Set the ADD bit 1406 Value |= tmp & 255; 1407 return Value; 1408} 1409 1410unsigned ARMMCCodeEmitter:: 1411getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 1412 SmallVectorImpl<MCFixup> &Fixups, 1413 const MCSubtargetInfo &STI) const { 1414 const MCOperand &MO1 = MI.getOperand(OpNum); 1415 1416 // FIXME: Needs fixup support. 1417 unsigned Value = 0; 1418 int32_t tmp = (int32_t)MO1.getImm(); 1419 if (tmp < 0) 1420 tmp = abs(tmp); 1421 else 1422 Value |= 256; // Set the ADD bit 1423 Value |= tmp & 255; 1424 return Value; 1425} 1426 1427unsigned ARMMCCodeEmitter:: 1428getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 1429 SmallVectorImpl<MCFixup> &Fixups, 1430 const MCSubtargetInfo &STI) const { 1431 const MCOperand &MO1 = MI.getOperand(OpNum); 1432 1433 // FIXME: Needs fixup support. 1434 unsigned Value = 0; 1435 int32_t tmp = (int32_t)MO1.getImm(); 1436 if (tmp < 0) 1437 tmp = abs(tmp); 1438 else 1439 Value |= 4096; // Set the ADD bit 1440 Value |= tmp & 4095; 1441 return Value; 1442} 1443 1444unsigned ARMMCCodeEmitter:: 1445getT2SORegOpValue(const MCInst &MI, unsigned OpIdx, 1446 SmallVectorImpl<MCFixup> &Fixups, 1447 const MCSubtargetInfo &STI) const { 1448 // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 1449 // shifted. The second is the amount to shift by. 1450 // 1451 // {3-0} = Rm. 1452 // {4} = 0 1453 // {6-5} = type 1454 // {11-7} = imm 1455 1456 const MCOperand &MO = MI.getOperand(OpIdx); 1457 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 1458 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 1459 1460 // Encode Rm. 1461 unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1462 1463 // Encode the shift opcode. 1464 unsigned SBits = 0; 1465 // Set shift operand (bit[6:4]). 1466 // LSL - 000 1467 // LSR - 010 1468 // ASR - 100 1469 // ROR - 110 1470 switch (SOpc) { 1471 default: llvm_unreachable("Unknown shift opc!"); 1472 case ARM_AM::lsl: SBits = 0x0; break; 1473 case ARM_AM::lsr: SBits = 0x2; break; 1474 case ARM_AM::asr: SBits = 0x4; break; 1475 case ARM_AM::rrx: // FALLTHROUGH 1476 case ARM_AM::ror: SBits = 0x6; break; 1477 } 1478 1479 Binary |= SBits << 4; 1480 if (SOpc == ARM_AM::rrx) 1481 return Binary; 1482 1483 // Encode shift_imm bit[11:7]. 1484 return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7; 1485} 1486 1487unsigned ARMMCCodeEmitter:: 1488getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 1489 SmallVectorImpl<MCFixup> &Fixups, 1490 const MCSubtargetInfo &STI) const { 1491 // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the 1492 // msb of the mask. 1493 const MCOperand &MO = MI.getOperand(Op); 1494 uint32_t v = ~MO.getImm(); 1495 uint32_t lsb = countTrailingZeros(v); 1496 uint32_t msb = (32 - countLeadingZeros (v)) - 1; 1497 assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!"); 1498 return lsb | (msb << 5); 1499} 1500 1501unsigned ARMMCCodeEmitter:: 1502getRegisterListOpValue(const MCInst &MI, unsigned Op, 1503 SmallVectorImpl<MCFixup> &Fixups, 1504 const MCSubtargetInfo &STI) const { 1505 // VLDM/VSTM: 1506 // {12-8} = Vd 1507 // {7-0} = Number of registers 1508 // 1509 // LDM/STM: 1510 // {15-0} = Bitfield of GPRs. 1511 unsigned Reg = MI.getOperand(Op).getReg(); 1512 bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg); 1513 bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg); 1514 1515 unsigned Binary = 0; 1516 1517 if (SPRRegs || DPRRegs) { 1518 // VLDM/VSTM 1519 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg); 1520 unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff; 1521 Binary |= (RegNo & 0x1f) << 8; 1522 if (SPRRegs) 1523 Binary |= NumRegs; 1524 else 1525 Binary |= NumRegs * 2; 1526 } else { 1527 for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) { 1528 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(MI.getOperand(I).getReg()); 1529 Binary |= 1 << RegNo; 1530 } 1531 } 1532 1533 return Binary; 1534} 1535 1536/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along 1537/// with the alignment operand. 1538unsigned ARMMCCodeEmitter:: 1539getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 1540 SmallVectorImpl<MCFixup> &Fixups, 1541 const MCSubtargetInfo &STI) const { 1542 const MCOperand &Reg = MI.getOperand(Op); 1543 const MCOperand &Imm = MI.getOperand(Op + 1); 1544 1545 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 1546 unsigned Align = 0; 1547 1548 switch (Imm.getImm()) { 1549 default: break; 1550 case 2: 1551 case 4: 1552 case 8: Align = 0x01; break; 1553 case 16: Align = 0x02; break; 1554 case 32: Align = 0x03; break; 1555 } 1556 1557 return RegNo | (Align << 4); 1558} 1559 1560/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number 1561/// along with the alignment operand for use in VST1 and VLD1 with size 32. 1562unsigned ARMMCCodeEmitter:: 1563getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 1564 SmallVectorImpl<MCFixup> &Fixups, 1565 const MCSubtargetInfo &STI) const { 1566 const MCOperand &Reg = MI.getOperand(Op); 1567 const MCOperand &Imm = MI.getOperand(Op + 1); 1568 1569 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 1570 unsigned Align = 0; 1571 1572 switch (Imm.getImm()) { 1573 default: break; 1574 case 8: 1575 case 16: 1576 case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes. 1577 case 2: Align = 0x00; break; 1578 case 4: Align = 0x03; break; 1579 } 1580 1581 return RegNo | (Align << 4); 1582} 1583 1584 1585/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and 1586/// alignment operand for use in VLD-dup instructions. This is the same as 1587/// getAddrMode6AddressOpValue except for the alignment encoding, which is 1588/// different for VLD4-dup. 1589unsigned ARMMCCodeEmitter:: 1590getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 1591 SmallVectorImpl<MCFixup> &Fixups, 1592 const MCSubtargetInfo &STI) const { 1593 const MCOperand &Reg = MI.getOperand(Op); 1594 const MCOperand &Imm = MI.getOperand(Op + 1); 1595 1596 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 1597 unsigned Align = 0; 1598 1599 switch (Imm.getImm()) { 1600 default: break; 1601 case 2: 1602 case 4: 1603 case 8: Align = 0x01; break; 1604 case 16: Align = 0x03; break; 1605 } 1606 1607 return RegNo | (Align << 4); 1608} 1609 1610unsigned ARMMCCodeEmitter:: 1611getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 1612 SmallVectorImpl<MCFixup> &Fixups, 1613 const MCSubtargetInfo &STI) const { 1614 const MCOperand &MO = MI.getOperand(Op); 1615 if (MO.getReg() == 0) return 0x0D; 1616 return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 1617} 1618 1619unsigned ARMMCCodeEmitter:: 1620getShiftRight8Imm(const MCInst &MI, unsigned Op, 1621 SmallVectorImpl<MCFixup> &Fixups, 1622 const MCSubtargetInfo &STI) const { 1623 return 8 - MI.getOperand(Op).getImm(); 1624} 1625 1626unsigned ARMMCCodeEmitter:: 1627getShiftRight16Imm(const MCInst &MI, unsigned Op, 1628 SmallVectorImpl<MCFixup> &Fixups, 1629 const MCSubtargetInfo &STI) const { 1630 return 16 - MI.getOperand(Op).getImm(); 1631} 1632 1633unsigned ARMMCCodeEmitter:: 1634getShiftRight32Imm(const MCInst &MI, unsigned Op, 1635 SmallVectorImpl<MCFixup> &Fixups, 1636 const MCSubtargetInfo &STI) const { 1637 return 32 - MI.getOperand(Op).getImm(); 1638} 1639 1640unsigned ARMMCCodeEmitter:: 1641getShiftRight64Imm(const MCInst &MI, unsigned Op, 1642 SmallVectorImpl<MCFixup> &Fixups, 1643 const MCSubtargetInfo &STI) const { 1644 return 64 - MI.getOperand(Op).getImm(); 1645} 1646 1647void ARMMCCodeEmitter:: 1648EncodeInstruction(const MCInst &MI, raw_ostream &OS, 1649 SmallVectorImpl<MCFixup> &Fixups, 1650 const MCSubtargetInfo &STI) const { 1651 // Pseudo instructions don't get encoded. 1652 const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 1653 uint64_t TSFlags = Desc.TSFlags; 1654 if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo) 1655 return; 1656 1657 int Size; 1658 if (Desc.getSize() == 2 || Desc.getSize() == 4) 1659 Size = Desc.getSize(); 1660 else 1661 llvm_unreachable("Unexpected instruction size!"); 1662 1663 uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI); 1664 // Thumb 32-bit wide instructions need to emit the high order halfword 1665 // first. 1666 if (isThumb(STI) && Size == 4) { 1667 EmitConstant(Binary >> 16, 2, OS); 1668 EmitConstant(Binary & 0xffff, 2, OS); 1669 } else 1670 EmitConstant(Binary, Size, OS); 1671 ++MCNumEmitted; // Keep track of the # of mi's emitted. 1672} 1673 1674#include "ARMGenMCCodeEmitter.inc" 1675