LLVM API Documentation
00001 //===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM code to machine code -------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the ARMMCCodeEmitter class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "MCTargetDesc/ARMMCTargetDesc.h" 00015 #include "MCTargetDesc/ARMAddressingModes.h" 00016 #include "MCTargetDesc/ARMBaseInfo.h" 00017 #include "MCTargetDesc/ARMFixupKinds.h" 00018 #include "MCTargetDesc/ARMMCExpr.h" 00019 #include "llvm/ADT/APFloat.h" 00020 #include "llvm/ADT/Statistic.h" 00021 #include "llvm/MC/MCCodeEmitter.h" 00022 #include "llvm/MC/MCContext.h" 00023 #include "llvm/MC/MCExpr.h" 00024 #include "llvm/MC/MCInst.h" 00025 #include "llvm/MC/MCInstrInfo.h" 00026 #include "llvm/MC/MCRegisterInfo.h" 00027 #include "llvm/MC/MCSubtargetInfo.h" 00028 #include "llvm/Support/ErrorHandling.h" 00029 #include "llvm/Support/raw_ostream.h" 00030 00031 using namespace llvm; 00032 00033 #define DEBUG_TYPE "mccodeemitter" 00034 00035 STATISTIC(MCNumEmitted, "Number of MC instructions emitted."); 00036 STATISTIC(MCNumCPRelocations, "Number of constant pool relocations created."); 00037 00038 namespace { 00039 class ARMMCCodeEmitter : public MCCodeEmitter { 00040 ARMMCCodeEmitter(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION; 00041 void operator=(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION; 00042 const MCInstrInfo &MCII; 00043 const MCContext &CTX; 00044 bool IsLittleEndian; 00045 00046 public: 00047 ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool IsLittle) 00048 : MCII(mcii), CTX(ctx), IsLittleEndian(IsLittle) { 00049 } 00050 00051 ~ARMMCCodeEmitter() {} 00052 00053 bool isThumb(const MCSubtargetInfo &STI) const { 00054 return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 00055 } 00056 bool isThumb2(const MCSubtargetInfo &STI) const { 00057 return isThumb(STI) && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0; 00058 } 00059 bool isTargetMachO(const MCSubtargetInfo &STI) const { 00060 Triple TT(STI.getTargetTriple()); 00061 return TT.isOSBinFormatMachO(); 00062 } 00063 00064 unsigned getMachineSoImmOpValue(unsigned SoImm) const; 00065 00066 // getBinaryCodeForInstr - TableGen'erated function for getting the 00067 // binary encoding for an instruction. 00068 uint64_t getBinaryCodeForInstr(const MCInst &MI, 00069 SmallVectorImpl<MCFixup> &Fixups, 00070 const MCSubtargetInfo &STI) const; 00071 00072 /// getMachineOpValue - Return binary encoding of operand. If the machine 00073 /// operand requires relocation, record the relocation and return zero. 00074 unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO, 00075 SmallVectorImpl<MCFixup> &Fixups, 00076 const MCSubtargetInfo &STI) const; 00077 00078 /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of 00079 /// the specified operand. This is used for operands with :lower16: and 00080 /// :upper16: prefixes. 00081 uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 00082 SmallVectorImpl<MCFixup> &Fixups, 00083 const MCSubtargetInfo &STI) const; 00084 00085 bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, 00086 unsigned &Reg, unsigned &Imm, 00087 SmallVectorImpl<MCFixup> &Fixups, 00088 const MCSubtargetInfo &STI) const; 00089 00090 /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate 00091 /// BL branch target. 00092 uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 00093 SmallVectorImpl<MCFixup> &Fixups, 00094 const MCSubtargetInfo &STI) const; 00095 00096 /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 00097 /// BLX branch target. 00098 uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 00099 SmallVectorImpl<MCFixup> &Fixups, 00100 const MCSubtargetInfo &STI) const; 00101 00102 /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 00103 uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 00104 SmallVectorImpl<MCFixup> &Fixups, 00105 const MCSubtargetInfo &STI) const; 00106 00107 /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 00108 uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 00109 SmallVectorImpl<MCFixup> &Fixups, 00110 const MCSubtargetInfo &STI) const; 00111 00112 /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 00113 uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 00114 SmallVectorImpl<MCFixup> &Fixups, 00115 const MCSubtargetInfo &STI) const; 00116 00117 /// getBranchTargetOpValue - Return encoding info for 24-bit immediate 00118 /// branch target. 00119 uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 00120 SmallVectorImpl<MCFixup> &Fixups, 00121 const MCSubtargetInfo &STI) const; 00122 00123 /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 00124 /// immediate Thumb2 direct branch target. 00125 uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 00126 SmallVectorImpl<MCFixup> &Fixups, 00127 const MCSubtargetInfo &STI) const; 00128 00129 /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate 00130 /// branch target. 00131 uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 00132 SmallVectorImpl<MCFixup> &Fixups, 00133 const MCSubtargetInfo &STI) const; 00134 uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 00135 SmallVectorImpl<MCFixup> &Fixups, 00136 const MCSubtargetInfo &STI) const; 00137 uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 00138 SmallVectorImpl<MCFixup> &Fixups, 00139 const MCSubtargetInfo &STI) const; 00140 00141 /// getAdrLabelOpValue - Return encoding info for 12-bit immediate 00142 /// ADR label target. 00143 uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 00144 SmallVectorImpl<MCFixup> &Fixups, 00145 const MCSubtargetInfo &STI) const; 00146 uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 00147 SmallVectorImpl<MCFixup> &Fixups, 00148 const MCSubtargetInfo &STI) const; 00149 uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 00150 SmallVectorImpl<MCFixup> &Fixups, 00151 const MCSubtargetInfo &STI) const; 00152 00153 00154 /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' 00155 /// operand. 00156 uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 00157 SmallVectorImpl<MCFixup> &Fixups, 00158 const MCSubtargetInfo &STI) const; 00159 00160 /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand. 00161 uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 00162 SmallVectorImpl<MCFixup> &Fixups, 00163 const MCSubtargetInfo &STI) const; 00164 00165 /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2' 00166 /// operand. 00167 uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 00168 SmallVectorImpl<MCFixup> &Fixups, 00169 const MCSubtargetInfo &STI) const; 00170 00171 /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2' 00172 /// operand. 00173 uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 00174 SmallVectorImpl<MCFixup> &Fixups, 00175 const MCSubtargetInfo &STI) const; 00176 00177 /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2' 00178 /// operand. 00179 uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 00180 SmallVectorImpl<MCFixup> &Fixups, 00181 const MCSubtargetInfo &STI) const; 00182 00183 00184 /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm' 00185 /// operand as needed by load/store instructions. 00186 uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 00187 SmallVectorImpl<MCFixup> &Fixups, 00188 const MCSubtargetInfo &STI) const; 00189 00190 /// getLdStmModeOpValue - Return encoding for load/store multiple mode. 00191 uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx, 00192 SmallVectorImpl<MCFixup> &Fixups, 00193 const MCSubtargetInfo &STI) const { 00194 ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm(); 00195 switch (Mode) { 00196 default: llvm_unreachable("Unknown addressing sub-mode!"); 00197 case ARM_AM::da: return 0; 00198 case ARM_AM::ia: return 1; 00199 case ARM_AM::db: return 2; 00200 case ARM_AM::ib: return 3; 00201 } 00202 } 00203 /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. 00204 /// 00205 unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const { 00206 switch (ShOpc) { 00207 case ARM_AM::no_shift: 00208 case ARM_AM::lsl: return 0; 00209 case ARM_AM::lsr: return 1; 00210 case ARM_AM::asr: return 2; 00211 case ARM_AM::ror: 00212 case ARM_AM::rrx: return 3; 00213 } 00214 llvm_unreachable("Invalid ShiftOpc!"); 00215 } 00216 00217 /// getAddrMode2OpValue - Return encoding for addrmode2 operands. 00218 uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 00219 SmallVectorImpl<MCFixup> &Fixups, 00220 const MCSubtargetInfo &STI) const; 00221 00222 /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands. 00223 uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 00224 SmallVectorImpl<MCFixup> &Fixups, 00225 const MCSubtargetInfo &STI) const; 00226 00227 /// getPostIdxRegOpValue - Return encoding for postidx_reg operands. 00228 uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 00229 SmallVectorImpl<MCFixup> &Fixups, 00230 const MCSubtargetInfo &STI) const; 00231 00232 /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands. 00233 uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 00234 SmallVectorImpl<MCFixup> &Fixups, 00235 const MCSubtargetInfo &STI) const; 00236 00237 /// getAddrMode3OpValue - Return encoding for addrmode3 operands. 00238 uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 00239 SmallVectorImpl<MCFixup> &Fixups, 00240 const MCSubtargetInfo &STI) const; 00241 00242 /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12' 00243 /// operand. 00244 uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 00245 SmallVectorImpl<MCFixup> &Fixups, 00246 const MCSubtargetInfo &STI) const; 00247 00248 /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 00249 uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 00250 SmallVectorImpl<MCFixup> &Fixups, 00251 const MCSubtargetInfo &STI) const; 00252 00253 /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 00254 uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 00255 SmallVectorImpl<MCFixup> &Fixups, 00256 const MCSubtargetInfo &STI) const; 00257 00258 /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand. 00259 uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 00260 SmallVectorImpl<MCFixup> &Fixups, 00261 const MCSubtargetInfo &STI) const; 00262 00263 /// getCCOutOpValue - Return encoding of the 's' bit. 00264 unsigned getCCOutOpValue(const MCInst &MI, unsigned Op, 00265 SmallVectorImpl<MCFixup> &Fixups, 00266 const MCSubtargetInfo &STI) const { 00267 // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or 00268 // '1' respectively. 00269 return MI.getOperand(Op).getReg() == ARM::CPSR; 00270 } 00271 00272 /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value. 00273 unsigned getSOImmOpValue(const MCInst &MI, unsigned Op, 00274 SmallVectorImpl<MCFixup> &Fixups, 00275 const MCSubtargetInfo &STI) const { 00276 00277 const MCOperand &MO = MI.getOperand(Op); 00278 00279 // We expect MO to be an immediate or an expression, 00280 // if it is an immediate - that's fine, just encode the value. 00281 // Otherwise - create a Fixup. 00282 if (MO.isExpr()) { 00283 const MCExpr *Expr = MO.getExpr(); 00284 // In instruction code this value always encoded as lowest 12 bits, 00285 // so we don't have to perform any specific adjustments. 00286 // Due to requirements of relocatable records we have to use FK_Data_4. 00287 // See ARMELFObjectWriter::ExplicitRelSym and 00288 // ARMELFObjectWriter::GetRelocTypeInner for more details. 00289 MCFixupKind Kind = MCFixupKind(FK_Data_4); 00290 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 00291 return 0; 00292 } 00293 00294 unsigned SoImm = MO.getImm(); 00295 int SoImmVal = ARM_AM::getSOImmVal(SoImm); 00296 assert(SoImmVal != -1 && "Not a valid so_imm value!"); 00297 00298 // Encode rotate_imm. 00299 unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1) 00300 << ARMII::SoRotImmShift; 00301 00302 // Encode immed_8. 00303 Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); 00304 return Binary; 00305 } 00306 00307 /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value. 00308 unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op, 00309 SmallVectorImpl<MCFixup> &Fixups, 00310 const MCSubtargetInfo &STI) const { 00311 unsigned SoImm = MI.getOperand(Op).getImm(); 00312 unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm); 00313 assert(Encoded != ~0U && "Not a Thumb2 so_imm value?"); 00314 return Encoded; 00315 } 00316 00317 unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 00318 SmallVectorImpl<MCFixup> &Fixups, 00319 const MCSubtargetInfo &STI) const; 00320 unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 00321 SmallVectorImpl<MCFixup> &Fixups, 00322 const MCSubtargetInfo &STI) const; 00323 unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 00324 SmallVectorImpl<MCFixup> &Fixups, 00325 const MCSubtargetInfo &STI) const; 00326 unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 00327 SmallVectorImpl<MCFixup> &Fixups, 00328 const MCSubtargetInfo &STI) const; 00329 00330 /// getSORegOpValue - Return an encoded so_reg shifted register value. 00331 unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op, 00332 SmallVectorImpl<MCFixup> &Fixups, 00333 const MCSubtargetInfo &STI) const; 00334 unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op, 00335 SmallVectorImpl<MCFixup> &Fixups, 00336 const MCSubtargetInfo &STI) const; 00337 unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op, 00338 SmallVectorImpl<MCFixup> &Fixups, 00339 const MCSubtargetInfo &STI) const; 00340 00341 unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op, 00342 SmallVectorImpl<MCFixup> &Fixups, 00343 const MCSubtargetInfo &STI) const { 00344 return 64 - MI.getOperand(Op).getImm(); 00345 } 00346 00347 unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 00348 SmallVectorImpl<MCFixup> &Fixups, 00349 const MCSubtargetInfo &STI) const; 00350 00351 unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op, 00352 SmallVectorImpl<MCFixup> &Fixups, 00353 const MCSubtargetInfo &STI) const; 00354 unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 00355 SmallVectorImpl<MCFixup> &Fixups, 00356 const MCSubtargetInfo &STI) const; 00357 unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 00358 SmallVectorImpl<MCFixup> &Fixups, 00359 const MCSubtargetInfo &STI) const; 00360 unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 00361 SmallVectorImpl<MCFixup> &Fixups, 00362 const MCSubtargetInfo &STI) const; 00363 unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 00364 SmallVectorImpl<MCFixup> &Fixups, 00365 const MCSubtargetInfo &STI) const; 00366 00367 unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op, 00368 SmallVectorImpl<MCFixup> &Fixups, 00369 const MCSubtargetInfo &STI) const; 00370 unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op, 00371 SmallVectorImpl<MCFixup> &Fixups, 00372 const MCSubtargetInfo &STI) const; 00373 unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op, 00374 SmallVectorImpl<MCFixup> &Fixups, 00375 const MCSubtargetInfo &STI) const; 00376 unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op, 00377 SmallVectorImpl<MCFixup> &Fixups, 00378 const MCSubtargetInfo &STI) const; 00379 00380 unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op, 00381 SmallVectorImpl<MCFixup> &Fixups, 00382 const MCSubtargetInfo &STI) const; 00383 00384 unsigned NEONThumb2DataIPostEncoder(const MCInst &MI, 00385 unsigned EncodedValue, 00386 const MCSubtargetInfo &STI) const; 00387 unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI, 00388 unsigned EncodedValue, 00389 const MCSubtargetInfo &STI) const; 00390 unsigned NEONThumb2DupPostEncoder(const MCInst &MI, 00391 unsigned EncodedValue, 00392 const MCSubtargetInfo &STI) const; 00393 unsigned NEONThumb2V8PostEncoder(const MCInst &MI, 00394 unsigned EncodedValue, 00395 const MCSubtargetInfo &STI) const; 00396 00397 unsigned VFPThumb2PostEncoder(const MCInst &MI, 00398 unsigned EncodedValue, 00399 const MCSubtargetInfo &STI) const; 00400 00401 void EmitByte(unsigned char C, raw_ostream &OS) const { 00402 OS << (char)C; 00403 } 00404 00405 void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const { 00406 // Output the constant in little endian byte order. 00407 for (unsigned i = 0; i != Size; ++i) { 00408 unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 00409 EmitByte((Val >> Shift) & 0xff, OS); 00410 } 00411 } 00412 00413 void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 00414 SmallVectorImpl<MCFixup> &Fixups, 00415 const MCSubtargetInfo &STI) const override; 00416 }; 00417 00418 } // end anonymous namespace 00419 00420 MCCodeEmitter *llvm::createARMLEMCCodeEmitter(const MCInstrInfo &MCII, 00421 const MCRegisterInfo &MRI, 00422 const MCSubtargetInfo &STI, 00423 MCContext &Ctx) { 00424 return new ARMMCCodeEmitter(MCII, Ctx, true); 00425 } 00426 00427 MCCodeEmitter *llvm::createARMBEMCCodeEmitter(const MCInstrInfo &MCII, 00428 const MCRegisterInfo &MRI, 00429 const MCSubtargetInfo &STI, 00430 MCContext &Ctx) { 00431 return new ARMMCCodeEmitter(MCII, Ctx, false); 00432 } 00433 00434 /// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing 00435 /// instructions, and rewrite them to their Thumb2 form if we are currently in 00436 /// Thumb2 mode. 00437 unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI, 00438 unsigned EncodedValue, 00439 const MCSubtargetInfo &STI) const { 00440 if (isThumb2(STI)) { 00441 // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved 00442 // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are 00443 // set to 1111. 00444 unsigned Bit24 = EncodedValue & 0x01000000; 00445 unsigned Bit28 = Bit24 << 4; 00446 EncodedValue &= 0xEFFFFFFF; 00447 EncodedValue |= Bit28; 00448 EncodedValue |= 0x0F000000; 00449 } 00450 00451 return EncodedValue; 00452 } 00453 00454 /// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store 00455 /// instructions, and rewrite them to their Thumb2 form if we are currently in 00456 /// Thumb2 mode. 00457 unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI, 00458 unsigned EncodedValue, 00459 const MCSubtargetInfo &STI) const { 00460 if (isThumb2(STI)) { 00461 EncodedValue &= 0xF0FFFFFF; 00462 EncodedValue |= 0x09000000; 00463 } 00464 00465 return EncodedValue; 00466 } 00467 00468 /// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup 00469 /// instructions, and rewrite them to their Thumb2 form if we are currently in 00470 /// Thumb2 mode. 00471 unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI, 00472 unsigned EncodedValue, 00473 const MCSubtargetInfo &STI) const { 00474 if (isThumb2(STI)) { 00475 EncodedValue &= 0x00FFFFFF; 00476 EncodedValue |= 0xEE000000; 00477 } 00478 00479 return EncodedValue; 00480 } 00481 00482 /// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form 00483 /// if we are in Thumb2. 00484 unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI, 00485 unsigned EncodedValue, 00486 const MCSubtargetInfo &STI) const { 00487 if (isThumb2(STI)) { 00488 EncodedValue |= 0xC000000; // Set bits 27-26 00489 } 00490 00491 return EncodedValue; 00492 } 00493 00494 /// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite 00495 /// them to their Thumb2 form if we are currently in Thumb2 mode. 00496 unsigned ARMMCCodeEmitter:: 00497 VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue, 00498 const MCSubtargetInfo &STI) const { 00499 if (isThumb2(STI)) { 00500 EncodedValue &= 0x0FFFFFFF; 00501 EncodedValue |= 0xE0000000; 00502 } 00503 return EncodedValue; 00504 } 00505 00506 /// getMachineOpValue - Return binary encoding of operand. If the machine 00507 /// operand requires relocation, record the relocation and return zero. 00508 unsigned ARMMCCodeEmitter:: 00509 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 00510 SmallVectorImpl<MCFixup> &Fixups, 00511 const MCSubtargetInfo &STI) const { 00512 if (MO.isReg()) { 00513 unsigned Reg = MO.getReg(); 00514 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg); 00515 00516 // Q registers are encoded as 2x their register number. 00517 switch (Reg) { 00518 default: 00519 return RegNo; 00520 case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3: 00521 case ARM::Q4: case ARM::Q5: case ARM::Q6: case ARM::Q7: 00522 case ARM::Q8: case ARM::Q9: case ARM::Q10: case ARM::Q11: 00523 case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15: 00524 return 2 * RegNo; 00525 } 00526 } else if (MO.isImm()) { 00527 return static_cast<unsigned>(MO.getImm()); 00528 } else if (MO.isFPImm()) { 00529 return static_cast<unsigned>(APFloat(MO.getFPImm()) 00530 .bitcastToAPInt().getHiBits(32).getLimitedValue()); 00531 } 00532 00533 llvm_unreachable("Unable to encode MCOperand!"); 00534 } 00535 00536 /// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand. 00537 bool ARMMCCodeEmitter:: 00538 EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg, 00539 unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups, 00540 const MCSubtargetInfo &STI) const { 00541 const MCOperand &MO = MI.getOperand(OpIdx); 00542 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 00543 00544 Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 00545 00546 int32_t SImm = MO1.getImm(); 00547 bool isAdd = true; 00548 00549 // Special value for #-0 00550 if (SImm == INT32_MIN) { 00551 SImm = 0; 00552 isAdd = false; 00553 } 00554 00555 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 00556 if (SImm < 0) { 00557 SImm = -SImm; 00558 isAdd = false; 00559 } 00560 00561 Imm = SImm; 00562 return isAdd; 00563 } 00564 00565 /// getBranchTargetOpValue - Helper function to get the branch target operand, 00566 /// which is either an immediate or requires a fixup. 00567 static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 00568 unsigned FixupKind, 00569 SmallVectorImpl<MCFixup> &Fixups, 00570 const MCSubtargetInfo &STI) { 00571 const MCOperand &MO = MI.getOperand(OpIdx); 00572 00573 // If the destination is an immediate, we have nothing to do. 00574 if (MO.isImm()) return MO.getImm(); 00575 assert(MO.isExpr() && "Unexpected branch target type!"); 00576 const MCExpr *Expr = MO.getExpr(); 00577 MCFixupKind Kind = MCFixupKind(FixupKind); 00578 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 00579 00580 // All of the information is in the fixup. 00581 return 0; 00582 } 00583 00584 // Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are 00585 // determined by negating them and XOR'ing them with bit 23. 00586 static int32_t encodeThumbBLOffset(int32_t offset) { 00587 offset >>= 1; 00588 uint32_t S = (offset & 0x800000) >> 23; 00589 uint32_t J1 = (offset & 0x400000) >> 22; 00590 uint32_t J2 = (offset & 0x200000) >> 21; 00591 J1 = (~J1 & 0x1); 00592 J2 = (~J2 & 0x1); 00593 J1 ^= S; 00594 J2 ^= S; 00595 00596 offset &= ~0x600000; 00597 offset |= J1 << 22; 00598 offset |= J2 << 21; 00599 00600 return offset; 00601 } 00602 00603 /// getThumbBLTargetOpValue - Return encoding info for immediate branch target. 00604 uint32_t ARMMCCodeEmitter:: 00605 getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 00606 SmallVectorImpl<MCFixup> &Fixups, 00607 const MCSubtargetInfo &STI) const { 00608 const MCOperand MO = MI.getOperand(OpIdx); 00609 if (MO.isExpr()) 00610 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl, 00611 Fixups, STI); 00612 return encodeThumbBLOffset(MO.getImm()); 00613 } 00614 00615 /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate 00616 /// BLX branch target. 00617 uint32_t ARMMCCodeEmitter:: 00618 getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 00619 SmallVectorImpl<MCFixup> &Fixups, 00620 const MCSubtargetInfo &STI) const { 00621 const MCOperand MO = MI.getOperand(OpIdx); 00622 if (MO.isExpr()) 00623 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx, 00624 Fixups, STI); 00625 return encodeThumbBLOffset(MO.getImm()); 00626 } 00627 00628 /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. 00629 uint32_t ARMMCCodeEmitter:: 00630 getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, 00631 SmallVectorImpl<MCFixup> &Fixups, 00632 const MCSubtargetInfo &STI) const { 00633 const MCOperand MO = MI.getOperand(OpIdx); 00634 if (MO.isExpr()) 00635 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br, 00636 Fixups, STI); 00637 return (MO.getImm() >> 1); 00638 } 00639 00640 /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. 00641 uint32_t ARMMCCodeEmitter:: 00642 getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, 00643 SmallVectorImpl<MCFixup> &Fixups, 00644 const MCSubtargetInfo &STI) const { 00645 const MCOperand MO = MI.getOperand(OpIdx); 00646 if (MO.isExpr()) 00647 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc, 00648 Fixups, STI); 00649 return (MO.getImm() >> 1); 00650 } 00651 00652 /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. 00653 uint32_t ARMMCCodeEmitter:: 00654 getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, 00655 SmallVectorImpl<MCFixup> &Fixups, 00656 const MCSubtargetInfo &STI) const { 00657 const MCOperand MO = MI.getOperand(OpIdx); 00658 if (MO.isExpr()) 00659 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups, STI); 00660 return (MO.getImm() >> 1); 00661 } 00662 00663 /// Return true if this branch has a non-always predication 00664 static bool HasConditionalBranch(const MCInst &MI) { 00665 int NumOp = MI.getNumOperands(); 00666 if (NumOp >= 2) { 00667 for (int i = 0; i < NumOp-1; ++i) { 00668 const MCOperand &MCOp1 = MI.getOperand(i); 00669 const MCOperand &MCOp2 = MI.getOperand(i + 1); 00670 if (MCOp1.isImm() && MCOp2.isReg() && 00671 (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) { 00672 if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL) 00673 return true; 00674 } 00675 } 00676 } 00677 return false; 00678 } 00679 00680 /// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 00681 /// target. 00682 uint32_t ARMMCCodeEmitter:: 00683 getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 00684 SmallVectorImpl<MCFixup> &Fixups, 00685 const MCSubtargetInfo &STI) const { 00686 // FIXME: This really, really shouldn't use TargetMachine. We don't want 00687 // coupling between MC and TM anywhere we can help it. 00688 if (isThumb2(STI)) 00689 return 00690 ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups, STI); 00691 return getARMBranchTargetOpValue(MI, OpIdx, Fixups, STI); 00692 } 00693 00694 /// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch 00695 /// target. 00696 uint32_t ARMMCCodeEmitter:: 00697 getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 00698 SmallVectorImpl<MCFixup> &Fixups, 00699 const MCSubtargetInfo &STI) const { 00700 const MCOperand MO = MI.getOperand(OpIdx); 00701 if (MO.isExpr()) { 00702 if (HasConditionalBranch(MI)) 00703 return ::getBranchTargetOpValue(MI, OpIdx, 00704 ARM::fixup_arm_condbranch, Fixups, STI); 00705 return ::getBranchTargetOpValue(MI, OpIdx, 00706 ARM::fixup_arm_uncondbranch, Fixups, STI); 00707 } 00708 00709 return MO.getImm() >> 2; 00710 } 00711 00712 uint32_t ARMMCCodeEmitter:: 00713 getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, 00714 SmallVectorImpl<MCFixup> &Fixups, 00715 const MCSubtargetInfo &STI) const { 00716 const MCOperand MO = MI.getOperand(OpIdx); 00717 if (MO.isExpr()) { 00718 if (HasConditionalBranch(MI)) 00719 return ::getBranchTargetOpValue(MI, OpIdx, 00720 ARM::fixup_arm_condbl, Fixups, STI); 00721 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups, STI); 00722 } 00723 00724 return MO.getImm() >> 2; 00725 } 00726 00727 uint32_t ARMMCCodeEmitter:: 00728 getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, 00729 SmallVectorImpl<MCFixup> &Fixups, 00730 const MCSubtargetInfo &STI) const { 00731 const MCOperand MO = MI.getOperand(OpIdx); 00732 if (MO.isExpr()) 00733 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx, Fixups, STI); 00734 00735 return MO.getImm() >> 1; 00736 } 00737 00738 /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit 00739 /// immediate branch target. 00740 uint32_t ARMMCCodeEmitter:: 00741 getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 00742 SmallVectorImpl<MCFixup> &Fixups, 00743 const MCSubtargetInfo &STI) const { 00744 unsigned Val = 0; 00745 const MCOperand MO = MI.getOperand(OpIdx); 00746 00747 if(MO.isExpr()) 00748 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups, STI); 00749 else 00750 Val = MO.getImm() >> 1; 00751 00752 bool I = (Val & 0x800000); 00753 bool J1 = (Val & 0x400000); 00754 bool J2 = (Val & 0x200000); 00755 if (I ^ J1) 00756 Val &= ~0x400000; 00757 else 00758 Val |= 0x400000; 00759 00760 if (I ^ J2) 00761 Val &= ~0x200000; 00762 else 00763 Val |= 0x200000; 00764 00765 return Val; 00766 } 00767 00768 /// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate 00769 /// ADR label target. 00770 uint32_t ARMMCCodeEmitter:: 00771 getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 00772 SmallVectorImpl<MCFixup> &Fixups, 00773 const MCSubtargetInfo &STI) const { 00774 const MCOperand MO = MI.getOperand(OpIdx); 00775 if (MO.isExpr()) 00776 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12, 00777 Fixups, STI); 00778 int64_t offset = MO.getImm(); 00779 uint32_t Val = 0x2000; 00780 00781 int SoImmVal; 00782 if (offset == INT32_MIN) { 00783 Val = 0x1000; 00784 SoImmVal = 0; 00785 } else if (offset < 0) { 00786 Val = 0x1000; 00787 offset *= -1; 00788 SoImmVal = ARM_AM::getSOImmVal(offset); 00789 if(SoImmVal == -1) { 00790 Val = 0x2000; 00791 offset *= -1; 00792 SoImmVal = ARM_AM::getSOImmVal(offset); 00793 } 00794 } else { 00795 SoImmVal = ARM_AM::getSOImmVal(offset); 00796 if(SoImmVal == -1) { 00797 Val = 0x1000; 00798 offset *= -1; 00799 SoImmVal = ARM_AM::getSOImmVal(offset); 00800 } 00801 } 00802 00803 assert(SoImmVal != -1 && "Not a valid so_imm value!"); 00804 00805 Val |= SoImmVal; 00806 return Val; 00807 } 00808 00809 /// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label 00810 /// target. 00811 uint32_t ARMMCCodeEmitter:: 00812 getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 00813 SmallVectorImpl<MCFixup> &Fixups, 00814 const MCSubtargetInfo &STI) const { 00815 const MCOperand MO = MI.getOperand(OpIdx); 00816 if (MO.isExpr()) 00817 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, 00818 Fixups, STI); 00819 int32_t Val = MO.getImm(); 00820 if (Val == INT32_MIN) 00821 Val = 0x1000; 00822 else if (Val < 0) { 00823 Val *= -1; 00824 Val |= 0x1000; 00825 } 00826 return Val; 00827 } 00828 00829 /// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label 00830 /// target. 00831 uint32_t ARMMCCodeEmitter:: 00832 getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 00833 SmallVectorImpl<MCFixup> &Fixups, 00834 const MCSubtargetInfo &STI) const { 00835 const MCOperand MO = MI.getOperand(OpIdx); 00836 if (MO.isExpr()) 00837 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10, 00838 Fixups, STI); 00839 return MO.getImm(); 00840 } 00841 00842 /// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg' 00843 /// operand. 00844 uint32_t ARMMCCodeEmitter:: 00845 getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, 00846 SmallVectorImpl<MCFixup> &, 00847 const MCSubtargetInfo &STI) const { 00848 // [Rn, Rm] 00849 // {5-3} = Rm 00850 // {2-0} = Rn 00851 const MCOperand &MO1 = MI.getOperand(OpIdx); 00852 const MCOperand &MO2 = MI.getOperand(OpIdx + 1); 00853 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 00854 unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO2.getReg()); 00855 return (Rm << 3) | Rn; 00856 } 00857 00858 /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand. 00859 uint32_t ARMMCCodeEmitter:: 00860 getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, 00861 SmallVectorImpl<MCFixup> &Fixups, 00862 const MCSubtargetInfo &STI) const { 00863 // {17-13} = reg 00864 // {12} = (U)nsigned (add == '1', sub == '0') 00865 // {11-0} = imm12 00866 unsigned Reg, Imm12; 00867 bool isAdd = true; 00868 // If The first operand isn't a register, we have a label reference. 00869 const MCOperand &MO = MI.getOperand(OpIdx); 00870 if (!MO.isReg()) { 00871 Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 00872 Imm12 = 0; 00873 00874 if (MO.isExpr()) { 00875 const MCExpr *Expr = MO.getExpr(); 00876 isAdd = false ; // 'U' bit is set as part of the fixup. 00877 00878 MCFixupKind Kind; 00879 if (isThumb2(STI)) 00880 Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12); 00881 else 00882 Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12); 00883 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 00884 00885 ++MCNumCPRelocations; 00886 } else { 00887 Reg = ARM::PC; 00888 int32_t Offset = MO.getImm(); 00889 if (Offset == INT32_MIN) { 00890 Offset = 0; 00891 isAdd = false; 00892 } else if (Offset < 0) { 00893 Offset *= -1; 00894 isAdd = false; 00895 } 00896 Imm12 = Offset; 00897 } 00898 } else 00899 isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups, STI); 00900 00901 uint32_t Binary = Imm12 & 0xfff; 00902 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 00903 if (isAdd) 00904 Binary |= (1 << 12); 00905 Binary |= (Reg << 13); 00906 return Binary; 00907 } 00908 00909 /// getT2Imm8s4OpValue - Return encoding info for 00910 /// '+/- imm8<<2' operand. 00911 uint32_t ARMMCCodeEmitter:: 00912 getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx, 00913 SmallVectorImpl<MCFixup> &Fixups, 00914 const MCSubtargetInfo &STI) const { 00915 // FIXME: The immediate operand should have already been encoded like this 00916 // before ever getting here. The encoder method should just need to combine 00917 // the MI operands for the register and the offset into a single 00918 // representation for the complex operand in the .td file. This isn't just 00919 // style, unfortunately. As-is, we can't represent the distinct encoding 00920 // for #-0. 00921 00922 // {8} = (U)nsigned (add == '1', sub == '0') 00923 // {7-0} = imm8 00924 int32_t Imm8 = MI.getOperand(OpIdx).getImm(); 00925 bool isAdd = Imm8 >= 0; 00926 00927 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 00928 if (Imm8 < 0) 00929 Imm8 = -(uint32_t)Imm8; 00930 00931 // Scaled by 4. 00932 Imm8 /= 4; 00933 00934 uint32_t Binary = Imm8 & 0xff; 00935 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 00936 if (isAdd) 00937 Binary |= (1 << 8); 00938 return Binary; 00939 } 00940 00941 /// getT2AddrModeImm8s4OpValue - Return encoding info for 00942 /// 'reg +/- imm8<<2' operand. 00943 uint32_t ARMMCCodeEmitter:: 00944 getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, 00945 SmallVectorImpl<MCFixup> &Fixups, 00946 const MCSubtargetInfo &STI) const { 00947 // {12-9} = reg 00948 // {8} = (U)nsigned (add == '1', sub == '0') 00949 // {7-0} = imm8 00950 unsigned Reg, Imm8; 00951 bool isAdd = true; 00952 // If The first operand isn't a register, we have a label reference. 00953 const MCOperand &MO = MI.getOperand(OpIdx); 00954 if (!MO.isReg()) { 00955 Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 00956 Imm8 = 0; 00957 isAdd = false ; // 'U' bit is set as part of the fixup. 00958 00959 assert(MO.isExpr() && "Unexpected machine operand type!"); 00960 const MCExpr *Expr = MO.getExpr(); 00961 MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 00962 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 00963 00964 ++MCNumCPRelocations; 00965 } else 00966 isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI); 00967 00968 // FIXME: The immediate operand should have already been encoded like this 00969 // before ever getting here. The encoder method should just need to combine 00970 // the MI operands for the register and the offset into a single 00971 // representation for the complex operand in the .td file. This isn't just 00972 // style, unfortunately. As-is, we can't represent the distinct encoding 00973 // for #-0. 00974 uint32_t Binary = (Imm8 >> 2) & 0xff; 00975 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 00976 if (isAdd) 00977 Binary |= (1 << 8); 00978 Binary |= (Reg << 9); 00979 return Binary; 00980 } 00981 00982 /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 00983 /// 'reg + imm8<<2' operand. 00984 uint32_t ARMMCCodeEmitter:: 00985 getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, 00986 SmallVectorImpl<MCFixup> &Fixups, 00987 const MCSubtargetInfo &STI) const { 00988 // {11-8} = reg 00989 // {7-0} = imm8 00990 const MCOperand &MO = MI.getOperand(OpIdx); 00991 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 00992 unsigned Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 00993 unsigned Imm8 = MO1.getImm(); 00994 return (Reg << 8) | Imm8; 00995 } 00996 00997 uint32_t 00998 ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, 00999 SmallVectorImpl<MCFixup> &Fixups, 01000 const MCSubtargetInfo &STI) const { 01001 // {20-16} = imm{15-12} 01002 // {11-0} = imm{11-0} 01003 const MCOperand &MO = MI.getOperand(OpIdx); 01004 if (MO.isImm()) 01005 // Hi / lo 16 bits already extracted during earlier passes. 01006 return static_cast<unsigned>(MO.getImm()); 01007 01008 // Handle :upper16: and :lower16: assembly prefixes. 01009 const MCExpr *E = MO.getExpr(); 01010 MCFixupKind Kind; 01011 if (E->getKind() == MCExpr::Target) { 01012 const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E); 01013 E = ARM16Expr->getSubExpr(); 01014 01015 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(E)) { 01016 const int64_t Value = MCE->getValue(); 01017 if (Value > UINT32_MAX) 01018 report_fatal_error("constant value truncated (limited to 32-bit)"); 01019 01020 switch (ARM16Expr->getKind()) { 01021 case ARMMCExpr::VK_ARM_HI16: 01022 return (int32_t(Value) & 0xffff0000) >> 16; 01023 case ARMMCExpr::VK_ARM_LO16: 01024 return (int32_t(Value) & 0x0000ffff); 01025 default: llvm_unreachable("Unsupported ARMFixup"); 01026 } 01027 } 01028 01029 switch (ARM16Expr->getKind()) { 01030 default: llvm_unreachable("Unsupported ARMFixup"); 01031 case ARMMCExpr::VK_ARM_HI16: 01032 Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movt_hi16 01033 : ARM::fixup_arm_movt_hi16); 01034 break; 01035 case ARMMCExpr::VK_ARM_LO16: 01036 Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movw_lo16 01037 : ARM::fixup_arm_movw_lo16); 01038 break; 01039 } 01040 01041 Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc())); 01042 return 0; 01043 } 01044 // If the expression doesn't have :upper16: or :lower16: on it, 01045 // it's just a plain immediate expression, previously those evaluated to 01046 // the lower 16 bits of the expression regardless of whether 01047 // we have a movt or a movw, but that led to misleadingly results. 01048 // This is now disallowed in the the AsmParser in validateInstruction() 01049 // so this should never happen. 01050 llvm_unreachable("expression without :upper16: or :lower16:"); 01051 } 01052 01053 uint32_t ARMMCCodeEmitter:: 01054 getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, 01055 SmallVectorImpl<MCFixup> &Fixups, 01056 const MCSubtargetInfo &STI) const { 01057 const MCOperand &MO = MI.getOperand(OpIdx); 01058 const MCOperand &MO1 = MI.getOperand(OpIdx+1); 01059 const MCOperand &MO2 = MI.getOperand(OpIdx+2); 01060 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 01061 unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 01062 unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()); 01063 bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add; 01064 ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm()); 01065 unsigned SBits = getShiftOp(ShOp); 01066 01067 // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift 01068 // amount. However, it would be an easy mistake to make so check here. 01069 assert((ShImm & ~0x1f) == 0 && "Out of range shift amount"); 01070 01071 // {16-13} = Rn 01072 // {12} = isAdd 01073 // {11-0} = shifter 01074 // {3-0} = Rm 01075 // {4} = 0 01076 // {6-5} = type 01077 // {11-7} = imm 01078 uint32_t Binary = Rm; 01079 Binary |= Rn << 13; 01080 Binary |= SBits << 5; 01081 Binary |= ShImm << 7; 01082 if (isAdd) 01083 Binary |= 1 << 12; 01084 return Binary; 01085 } 01086 01087 uint32_t ARMMCCodeEmitter:: 01088 getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, 01089 SmallVectorImpl<MCFixup> &Fixups, 01090 const MCSubtargetInfo &STI) const { 01091 // {17-14} Rn 01092 // {13} 1 == imm12, 0 == Rm 01093 // {12} isAdd 01094 // {11-0} imm12/Rm 01095 const MCOperand &MO = MI.getOperand(OpIdx); 01096 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 01097 uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups, STI); 01098 Binary |= Rn << 14; 01099 return Binary; 01100 } 01101 01102 uint32_t ARMMCCodeEmitter:: 01103 getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, 01104 SmallVectorImpl<MCFixup> &Fixups, 01105 const MCSubtargetInfo &STI) const { 01106 // {13} 1 == imm12, 0 == Rm 01107 // {12} isAdd 01108 // {11-0} imm12/Rm 01109 const MCOperand &MO = MI.getOperand(OpIdx); 01110 const MCOperand &MO1 = MI.getOperand(OpIdx+1); 01111 unsigned Imm = MO1.getImm(); 01112 bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add; 01113 bool isReg = MO.getReg() != 0; 01114 uint32_t Binary = ARM_AM::getAM2Offset(Imm); 01115 // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12 01116 if (isReg) { 01117 ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm); 01118 Binary <<= 7; // Shift amount is bits [11:7] 01119 Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5] 01120 Binary |= CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); // Rm is bits [3:0] 01121 } 01122 return Binary | (isAdd << 12) | (isReg << 13); 01123 } 01124 01125 uint32_t ARMMCCodeEmitter:: 01126 getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, 01127 SmallVectorImpl<MCFixup> &Fixups, 01128 const MCSubtargetInfo &STI) const { 01129 // {4} isAdd 01130 // {3-0} Rm 01131 const MCOperand &MO = MI.getOperand(OpIdx); 01132 const MCOperand &MO1 = MI.getOperand(OpIdx+1); 01133 bool isAdd = MO1.getImm() != 0; 01134 return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()) | (isAdd << 4); 01135 } 01136 01137 uint32_t ARMMCCodeEmitter:: 01138 getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, 01139 SmallVectorImpl<MCFixup> &Fixups, 01140 const MCSubtargetInfo &STI) const { 01141 // {9} 1 == imm8, 0 == Rm 01142 // {8} isAdd 01143 // {7-4} imm7_4/zero 01144 // {3-0} imm3_0/Rm 01145 const MCOperand &MO = MI.getOperand(OpIdx); 01146 const MCOperand &MO1 = MI.getOperand(OpIdx+1); 01147 unsigned Imm = MO1.getImm(); 01148 bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 01149 bool isImm = MO.getReg() == 0; 01150 uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 01151 // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 01152 if (!isImm) 01153 Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 01154 return Imm8 | (isAdd << 8) | (isImm << 9); 01155 } 01156 01157 uint32_t ARMMCCodeEmitter:: 01158 getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, 01159 SmallVectorImpl<MCFixup> &Fixups, 01160 const MCSubtargetInfo &STI) const { 01161 // {13} 1 == imm8, 0 == Rm 01162 // {12-9} Rn 01163 // {8} isAdd 01164 // {7-4} imm7_4/zero 01165 // {3-0} imm3_0/Rm 01166 const MCOperand &MO = MI.getOperand(OpIdx); 01167 const MCOperand &MO1 = MI.getOperand(OpIdx+1); 01168 const MCOperand &MO2 = MI.getOperand(OpIdx+2); 01169 01170 // If The first operand isn't a register, we have a label reference. 01171 if (!MO.isReg()) { 01172 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 01173 01174 assert(MO.isExpr() && "Unexpected machine operand type!"); 01175 const MCExpr *Expr = MO.getExpr(); 01176 MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled); 01177 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 01178 01179 ++MCNumCPRelocations; 01180 return (Rn << 9) | (1 << 13); 01181 } 01182 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 01183 unsigned Imm = MO2.getImm(); 01184 bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add; 01185 bool isImm = MO1.getReg() == 0; 01186 uint32_t Imm8 = ARM_AM::getAM3Offset(Imm); 01187 // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 01188 if (!isImm) 01189 Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 01190 return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13); 01191 } 01192 01193 /// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands. 01194 uint32_t ARMMCCodeEmitter:: 01195 getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, 01196 SmallVectorImpl<MCFixup> &Fixups, 01197 const MCSubtargetInfo &STI) const { 01198 // [SP, #imm] 01199 // {7-0} = imm8 01200 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 01201 assert(MI.getOperand(OpIdx).getReg() == ARM::SP && 01202 "Unexpected base register!"); 01203 01204 // The immediate is already shifted for the implicit zeroes, so no change 01205 // here. 01206 return MO1.getImm() & 0xff; 01207 } 01208 01209 /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. 01210 uint32_t ARMMCCodeEmitter:: 01211 getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, 01212 SmallVectorImpl<MCFixup> &Fixups, 01213 const MCSubtargetInfo &STI) const { 01214 // [Rn, #imm] 01215 // {7-3} = imm5 01216 // {2-0} = Rn 01217 const MCOperand &MO = MI.getOperand(OpIdx); 01218 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 01219 unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 01220 unsigned Imm5 = MO1.getImm(); 01221 return ((Imm5 & 0x1f) << 3) | Rn; 01222 } 01223 01224 /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. 01225 uint32_t ARMMCCodeEmitter:: 01226 getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, 01227 SmallVectorImpl<MCFixup> &Fixups, 01228 const MCSubtargetInfo &STI) const { 01229 const MCOperand MO = MI.getOperand(OpIdx); 01230 if (MO.isExpr()) 01231 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups, STI); 01232 return (MO.getImm() >> 2); 01233 } 01234 01235 /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand. 01236 uint32_t ARMMCCodeEmitter:: 01237 getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, 01238 SmallVectorImpl<MCFixup> &Fixups, 01239 const MCSubtargetInfo &STI) const { 01240 // {12-9} = reg 01241 // {8} = (U)nsigned (add == '1', sub == '0') 01242 // {7-0} = imm8 01243 unsigned Reg, Imm8; 01244 bool isAdd; 01245 // If The first operand isn't a register, we have a label reference. 01246 const MCOperand &MO = MI.getOperand(OpIdx); 01247 if (!MO.isReg()) { 01248 Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. 01249 Imm8 = 0; 01250 isAdd = false; // 'U' bit is handled as part of the fixup. 01251 01252 assert(MO.isExpr() && "Unexpected machine operand type!"); 01253 const MCExpr *Expr = MO.getExpr(); 01254 MCFixupKind Kind; 01255 if (isThumb2(STI)) 01256 Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); 01257 else 01258 Kind = MCFixupKind(ARM::fixup_arm_pcrel_10); 01259 Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 01260 01261 ++MCNumCPRelocations; 01262 } else { 01263 EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI); 01264 isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add; 01265 } 01266 01267 uint32_t Binary = ARM_AM::getAM5Offset(Imm8); 01268 // Immediate is always encoded as positive. The 'U' bit controls add vs sub. 01269 if (isAdd) 01270 Binary |= (1 << 8); 01271 Binary |= (Reg << 9); 01272 return Binary; 01273 } 01274 01275 unsigned ARMMCCodeEmitter:: 01276 getSORegRegOpValue(const MCInst &MI, unsigned OpIdx, 01277 SmallVectorImpl<MCFixup> &Fixups, 01278 const MCSubtargetInfo &STI) const { 01279 // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be 01280 // shifted. The second is Rs, the amount to shift by, and the third specifies 01281 // the type of the shift. 01282 // 01283 // {3-0} = Rm. 01284 // {4} = 1 01285 // {6-5} = type 01286 // {11-8} = Rs 01287 // {7} = 0 01288 01289 const MCOperand &MO = MI.getOperand(OpIdx); 01290 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 01291 const MCOperand &MO2 = MI.getOperand(OpIdx + 2); 01292 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm()); 01293 01294 // Encode Rm. 01295 unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 01296 01297 // Encode the shift opcode. 01298 unsigned SBits = 0; 01299 unsigned Rs = MO1.getReg(); 01300 if (Rs) { 01301 // Set shift operand (bit[7:4]). 01302 // LSL - 0001 01303 // LSR - 0011 01304 // ASR - 0101 01305 // ROR - 0111 01306 switch (SOpc) { 01307 default: llvm_unreachable("Unknown shift opc!"); 01308 case ARM_AM::lsl: SBits = 0x1; break; 01309 case ARM_AM::lsr: SBits = 0x3; break; 01310 case ARM_AM::asr: SBits = 0x5; break; 01311 case ARM_AM::ror: SBits = 0x7; break; 01312 } 01313 } 01314 01315 Binary |= SBits << 4; 01316 01317 // Encode the shift operation Rs. 01318 // Encode Rs bit[11:8]. 01319 assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0); 01320 return Binary | (CTX.getRegisterInfo()->getEncodingValue(Rs) << ARMII::RegRsShift); 01321 } 01322 01323 unsigned ARMMCCodeEmitter:: 01324 getSORegImmOpValue(const MCInst &MI, unsigned OpIdx, 01325 SmallVectorImpl<MCFixup> &Fixups, 01326 const MCSubtargetInfo &STI) const { 01327 // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 01328 // shifted. The second is the amount to shift by. 01329 // 01330 // {3-0} = Rm. 01331 // {4} = 0 01332 // {6-5} = type 01333 // {11-7} = imm 01334 01335 const MCOperand &MO = MI.getOperand(OpIdx); 01336 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 01337 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 01338 01339 // Encode Rm. 01340 unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 01341 01342 // Encode the shift opcode. 01343 unsigned SBits = 0; 01344 01345 // Set shift operand (bit[6:4]). 01346 // LSL - 000 01347 // LSR - 010 01348 // ASR - 100 01349 // ROR - 110 01350 // RRX - 110 and bit[11:8] clear. 01351 switch (SOpc) { 01352 default: llvm_unreachable("Unknown shift opc!"); 01353 case ARM_AM::lsl: SBits = 0x0; break; 01354 case ARM_AM::lsr: SBits = 0x2; break; 01355 case ARM_AM::asr: SBits = 0x4; break; 01356 case ARM_AM::ror: SBits = 0x6; break; 01357 case ARM_AM::rrx: 01358 Binary |= 0x60; 01359 return Binary; 01360 } 01361 01362 // Encode shift_imm bit[11:7]. 01363 Binary |= SBits << 4; 01364 unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm()); 01365 assert(Offset < 32 && "Offset must be in range 0-31!"); 01366 return Binary | (Offset << 7); 01367 } 01368 01369 01370 unsigned ARMMCCodeEmitter:: 01371 getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, 01372 SmallVectorImpl<MCFixup> &Fixups, 01373 const MCSubtargetInfo &STI) const { 01374 const MCOperand &MO1 = MI.getOperand(OpNum); 01375 const MCOperand &MO2 = MI.getOperand(OpNum+1); 01376 const MCOperand &MO3 = MI.getOperand(OpNum+2); 01377 01378 // Encoded as [Rn, Rm, imm]. 01379 // FIXME: Needs fixup support. 01380 unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 01381 Value <<= 4; 01382 Value |= CTX.getRegisterInfo()->getEncodingValue(MO2.getReg()); 01383 Value <<= 2; 01384 Value |= MO3.getImm(); 01385 01386 return Value; 01387 } 01388 01389 unsigned ARMMCCodeEmitter:: 01390 getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, 01391 SmallVectorImpl<MCFixup> &Fixups, 01392 const MCSubtargetInfo &STI) const { 01393 const MCOperand &MO1 = MI.getOperand(OpNum); 01394 const MCOperand &MO2 = MI.getOperand(OpNum+1); 01395 01396 // FIXME: Needs fixup support. 01397 unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg()); 01398 01399 // Even though the immediate is 8 bits long, we need 9 bits in order 01400 // to represent the (inverse of the) sign bit. 01401 Value <<= 9; 01402 int32_t tmp = (int32_t)MO2.getImm(); 01403 if (tmp < 0) 01404 tmp = abs(tmp); 01405 else 01406 Value |= 256; // Set the ADD bit 01407 Value |= tmp & 255; 01408 return Value; 01409 } 01410 01411 unsigned ARMMCCodeEmitter:: 01412 getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, 01413 SmallVectorImpl<MCFixup> &Fixups, 01414 const MCSubtargetInfo &STI) const { 01415 const MCOperand &MO1 = MI.getOperand(OpNum); 01416 01417 // FIXME: Needs fixup support. 01418 unsigned Value = 0; 01419 int32_t tmp = (int32_t)MO1.getImm(); 01420 if (tmp < 0) 01421 tmp = abs(tmp); 01422 else 01423 Value |= 256; // Set the ADD bit 01424 Value |= tmp & 255; 01425 return Value; 01426 } 01427 01428 unsigned ARMMCCodeEmitter:: 01429 getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, 01430 SmallVectorImpl<MCFixup> &Fixups, 01431 const MCSubtargetInfo &STI) const { 01432 const MCOperand &MO1 = MI.getOperand(OpNum); 01433 01434 // FIXME: Needs fixup support. 01435 unsigned Value = 0; 01436 int32_t tmp = (int32_t)MO1.getImm(); 01437 if (tmp < 0) 01438 tmp = abs(tmp); 01439 else 01440 Value |= 4096; // Set the ADD bit 01441 Value |= tmp & 4095; 01442 return Value; 01443 } 01444 01445 unsigned ARMMCCodeEmitter:: 01446 getT2SORegOpValue(const MCInst &MI, unsigned OpIdx, 01447 SmallVectorImpl<MCFixup> &Fixups, 01448 const MCSubtargetInfo &STI) const { 01449 // Sub-operands are [reg, imm]. The first register is Rm, the reg to be 01450 // shifted. The second is the amount to shift by. 01451 // 01452 // {3-0} = Rm. 01453 // {4} = 0 01454 // {6-5} = type 01455 // {11-7} = imm 01456 01457 const MCOperand &MO = MI.getOperand(OpIdx); 01458 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 01459 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm()); 01460 01461 // Encode Rm. 01462 unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 01463 01464 // Encode the shift opcode. 01465 unsigned SBits = 0; 01466 // Set shift operand (bit[6:4]). 01467 // LSL - 000 01468 // LSR - 010 01469 // ASR - 100 01470 // ROR - 110 01471 switch (SOpc) { 01472 default: llvm_unreachable("Unknown shift opc!"); 01473 case ARM_AM::lsl: SBits = 0x0; break; 01474 case ARM_AM::lsr: SBits = 0x2; break; 01475 case ARM_AM::asr: SBits = 0x4; break; 01476 case ARM_AM::rrx: // FALLTHROUGH 01477 case ARM_AM::ror: SBits = 0x6; break; 01478 } 01479 01480 Binary |= SBits << 4; 01481 if (SOpc == ARM_AM::rrx) 01482 return Binary; 01483 01484 // Encode shift_imm bit[11:7]. 01485 return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7; 01486 } 01487 01488 unsigned ARMMCCodeEmitter:: 01489 getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, 01490 SmallVectorImpl<MCFixup> &Fixups, 01491 const MCSubtargetInfo &STI) const { 01492 // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the 01493 // msb of the mask. 01494 const MCOperand &MO = MI.getOperand(Op); 01495 uint32_t v = ~MO.getImm(); 01496 uint32_t lsb = countTrailingZeros(v); 01497 uint32_t msb = (32 - countLeadingZeros (v)) - 1; 01498 assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!"); 01499 return lsb | (msb << 5); 01500 } 01501 01502 unsigned ARMMCCodeEmitter:: 01503 getRegisterListOpValue(const MCInst &MI, unsigned Op, 01504 SmallVectorImpl<MCFixup> &Fixups, 01505 const MCSubtargetInfo &STI) const { 01506 // VLDM/VSTM: 01507 // {12-8} = Vd 01508 // {7-0} = Number of registers 01509 // 01510 // LDM/STM: 01511 // {15-0} = Bitfield of GPRs. 01512 unsigned Reg = MI.getOperand(Op).getReg(); 01513 bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg); 01514 bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg); 01515 01516 unsigned Binary = 0; 01517 01518 if (SPRRegs || DPRRegs) { 01519 // VLDM/VSTM 01520 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg); 01521 unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff; 01522 Binary |= (RegNo & 0x1f) << 8; 01523 if (SPRRegs) 01524 Binary |= NumRegs; 01525 else 01526 Binary |= NumRegs * 2; 01527 } else { 01528 for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) { 01529 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(MI.getOperand(I).getReg()); 01530 Binary |= 1 << RegNo; 01531 } 01532 } 01533 01534 return Binary; 01535 } 01536 01537 /// getAddrMode6AddressOpValue - Encode an addrmode6 register number along 01538 /// with the alignment operand. 01539 unsigned ARMMCCodeEmitter:: 01540 getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, 01541 SmallVectorImpl<MCFixup> &Fixups, 01542 const MCSubtargetInfo &STI) const { 01543 const MCOperand &Reg = MI.getOperand(Op); 01544 const MCOperand &Imm = MI.getOperand(Op + 1); 01545 01546 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 01547 unsigned Align = 0; 01548 01549 switch (Imm.getImm()) { 01550 default: break; 01551 case 2: 01552 case 4: 01553 case 8: Align = 0x01; break; 01554 case 16: Align = 0x02; break; 01555 case 32: Align = 0x03; break; 01556 } 01557 01558 return RegNo | (Align << 4); 01559 } 01560 01561 /// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number 01562 /// along with the alignment operand for use in VST1 and VLD1 with size 32. 01563 unsigned ARMMCCodeEmitter:: 01564 getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, 01565 SmallVectorImpl<MCFixup> &Fixups, 01566 const MCSubtargetInfo &STI) const { 01567 const MCOperand &Reg = MI.getOperand(Op); 01568 const MCOperand &Imm = MI.getOperand(Op + 1); 01569 01570 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 01571 unsigned Align = 0; 01572 01573 switch (Imm.getImm()) { 01574 default: break; 01575 case 8: 01576 case 16: 01577 case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes. 01578 case 2: Align = 0x00; break; 01579 case 4: Align = 0x03; break; 01580 } 01581 01582 return RegNo | (Align << 4); 01583 } 01584 01585 01586 /// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and 01587 /// alignment operand for use in VLD-dup instructions. This is the same as 01588 /// getAddrMode6AddressOpValue except for the alignment encoding, which is 01589 /// different for VLD4-dup. 01590 unsigned ARMMCCodeEmitter:: 01591 getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, 01592 SmallVectorImpl<MCFixup> &Fixups, 01593 const MCSubtargetInfo &STI) const { 01594 const MCOperand &Reg = MI.getOperand(Op); 01595 const MCOperand &Imm = MI.getOperand(Op + 1); 01596 01597 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg()); 01598 unsigned Align = 0; 01599 01600 switch (Imm.getImm()) { 01601 default: break; 01602 case 2: 01603 case 4: 01604 case 8: Align = 0x01; break; 01605 case 16: Align = 0x03; break; 01606 } 01607 01608 return RegNo | (Align << 4); 01609 } 01610 01611 unsigned ARMMCCodeEmitter:: 01612 getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, 01613 SmallVectorImpl<MCFixup> &Fixups, 01614 const MCSubtargetInfo &STI) const { 01615 const MCOperand &MO = MI.getOperand(Op); 01616 if (MO.getReg() == 0) return 0x0D; 01617 return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 01618 } 01619 01620 unsigned ARMMCCodeEmitter:: 01621 getShiftRight8Imm(const MCInst &MI, unsigned Op, 01622 SmallVectorImpl<MCFixup> &Fixups, 01623 const MCSubtargetInfo &STI) const { 01624 return 8 - MI.getOperand(Op).getImm(); 01625 } 01626 01627 unsigned ARMMCCodeEmitter:: 01628 getShiftRight16Imm(const MCInst &MI, unsigned Op, 01629 SmallVectorImpl<MCFixup> &Fixups, 01630 const MCSubtargetInfo &STI) const { 01631 return 16 - MI.getOperand(Op).getImm(); 01632 } 01633 01634 unsigned ARMMCCodeEmitter:: 01635 getShiftRight32Imm(const MCInst &MI, unsigned Op, 01636 SmallVectorImpl<MCFixup> &Fixups, 01637 const MCSubtargetInfo &STI) const { 01638 return 32 - MI.getOperand(Op).getImm(); 01639 } 01640 01641 unsigned ARMMCCodeEmitter:: 01642 getShiftRight64Imm(const MCInst &MI, unsigned Op, 01643 SmallVectorImpl<MCFixup> &Fixups, 01644 const MCSubtargetInfo &STI) const { 01645 return 64 - MI.getOperand(Op).getImm(); 01646 } 01647 01648 void ARMMCCodeEmitter:: 01649 EncodeInstruction(const MCInst &MI, raw_ostream &OS, 01650 SmallVectorImpl<MCFixup> &Fixups, 01651 const MCSubtargetInfo &STI) const { 01652 // Pseudo instructions don't get encoded. 01653 const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 01654 uint64_t TSFlags = Desc.TSFlags; 01655 if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo) 01656 return; 01657 01658 int Size; 01659 if (Desc.getSize() == 2 || Desc.getSize() == 4) 01660 Size = Desc.getSize(); 01661 else 01662 llvm_unreachable("Unexpected instruction size!"); 01663 01664 uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI); 01665 // Thumb 32-bit wide instructions need to emit the high order halfword 01666 // first. 01667 if (isThumb(STI) && Size == 4) { 01668 EmitConstant(Binary >> 16, 2, OS); 01669 EmitConstant(Binary & 0xffff, 2, OS); 01670 } else 01671 EmitConstant(Binary, Size, OS); 01672 ++MCNumEmitted; // Keep track of the # of mi's emitted. 01673 } 01674 01675 #include "ARMGenMCCodeEmitter.inc"