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