1 //===-- PPCMCCodeEmitter.cpp - Convert PPC code to machine code -----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the PPCMCCodeEmitter class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "PPCMCCodeEmitter.h" 14 #include "MCTargetDesc/PPCFixupKinds.h" 15 #include "PPCMCTargetDesc.h" 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/ADT/Statistic.h" 18 #include "llvm/MC/MCExpr.h" 19 #include "llvm/MC/MCFixup.h" 20 #include "llvm/MC/MCInstrDesc.h" 21 #include "llvm/MC/MCRegisterInfo.h" 22 #include "llvm/Support/Casting.h" 23 #include "llvm/Support/EndianStream.h" 24 #include "llvm/Support/ErrorHandling.h" 25 #include "llvm/Support/MathExtras.h" 26 #include "llvm/TargetParser/Triple.h" 27 #include <cassert> 28 #include <cstdint> 29 30 using namespace llvm; 31 32 #define DEBUG_TYPE "mccodeemitter" 33 34 STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 35 36 MCCodeEmitter *llvm::createPPCMCCodeEmitter(const MCInstrInfo &MCII, 37 MCContext &Ctx) { 38 return new PPCMCCodeEmitter(MCII, Ctx); 39 } 40 41 unsigned PPCMCCodeEmitter:: 42 getDirectBrEncoding(const MCInst &MI, unsigned OpNo, 43 SmallVectorImpl<MCFixup> &Fixups, 44 const MCSubtargetInfo &STI) const { 45 const MCOperand &MO = MI.getOperand(OpNo); 46 47 if (MO.isReg() || MO.isImm()) 48 return getMachineOpValue(MI, MO, Fixups, STI); 49 50 // Add a fixup for the branch target. 51 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 52 (isNoTOCCallInstr(MI) 53 ? (MCFixupKind)PPC::fixup_ppc_br24_notoc 54 : (MCFixupKind)PPC::fixup_ppc_br24))); 55 return 0; 56 } 57 58 /// Check if Opcode corresponds to a call instruction that should be marked 59 /// with the NOTOC relocation. 60 bool PPCMCCodeEmitter::isNoTOCCallInstr(const MCInst &MI) const { 61 unsigned Opcode = MI.getOpcode(); 62 if (!MCII.get(Opcode).isCall()) 63 return false; 64 65 switch (Opcode) { 66 default: 67 #ifndef NDEBUG 68 llvm_unreachable("Unknown call opcode"); 69 #endif 70 return false; 71 case PPC::BL8_NOTOC: 72 case PPC::BL8_NOTOC_TLS: 73 case PPC::BL8_NOTOC_RM: 74 return true; 75 #ifndef NDEBUG 76 case PPC::BL8: 77 case PPC::BL: 78 case PPC::BL8_TLS: 79 case PPC::BL_TLS: 80 case PPC::BLA8: 81 case PPC::BLA: 82 case PPC::BCCL: 83 case PPC::BCCLA: 84 case PPC::BCL: 85 case PPC::BCLn: 86 case PPC::BL8_NOP: 87 case PPC::BL_NOP: 88 case PPC::BL8_NOP_TLS: 89 case PPC::BLA8_NOP: 90 case PPC::BCTRL8: 91 case PPC::BCTRL: 92 case PPC::BCCCTRL8: 93 case PPC::BCCCTRL: 94 case PPC::BCCTRL8: 95 case PPC::BCCTRL: 96 case PPC::BCCTRL8n: 97 case PPC::BCCTRLn: 98 case PPC::BL8_RM: 99 case PPC::BLA8_RM: 100 case PPC::BL8_NOP_RM: 101 case PPC::BLA8_NOP_RM: 102 case PPC::BCTRL8_RM: 103 case PPC::BCTRL8_LDinto_toc: 104 case PPC::BCTRL8_LDinto_toc_RM: 105 case PPC::BL8_TLS_: 106 case PPC::TCRETURNdi8: 107 case PPC::TCRETURNai8: 108 case PPC::TCRETURNri8: 109 case PPC::TAILBCTR8: 110 case PPC::TAILB8: 111 case PPC::TAILBA8: 112 case PPC::BCLalways: 113 case PPC::BLRL: 114 case PPC::BCCLRL: 115 case PPC::BCLRL: 116 case PPC::BCLRLn: 117 case PPC::BDZL: 118 case PPC::BDNZL: 119 case PPC::BDZLA: 120 case PPC::BDNZLA: 121 case PPC::BDZLp: 122 case PPC::BDNZLp: 123 case PPC::BDZLAp: 124 case PPC::BDNZLAp: 125 case PPC::BDZLm: 126 case PPC::BDNZLm: 127 case PPC::BDZLAm: 128 case PPC::BDNZLAm: 129 case PPC::BDZLRL: 130 case PPC::BDNZLRL: 131 case PPC::BDZLRLp: 132 case PPC::BDNZLRLp: 133 case PPC::BDZLRLm: 134 case PPC::BDNZLRLm: 135 case PPC::BL_RM: 136 case PPC::BLA_RM: 137 case PPC::BL_NOP_RM: 138 case PPC::BCTRL_RM: 139 case PPC::TCRETURNdi: 140 case PPC::TCRETURNai: 141 case PPC::TCRETURNri: 142 case PPC::BCTRL_LWZinto_toc: 143 case PPC::BCTRL_LWZinto_toc_RM: 144 case PPC::TAILBCTR: 145 case PPC::TAILB: 146 case PPC::TAILBA: 147 return false; 148 #endif 149 } 150 } 151 152 unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo, 153 SmallVectorImpl<MCFixup> &Fixups, 154 const MCSubtargetInfo &STI) const { 155 const MCOperand &MO = MI.getOperand(OpNo); 156 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 157 158 // Add a fixup for the branch target. 159 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 160 (MCFixupKind)PPC::fixup_ppc_brcond14)); 161 return 0; 162 } 163 164 unsigned PPCMCCodeEmitter:: 165 getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo, 166 SmallVectorImpl<MCFixup> &Fixups, 167 const MCSubtargetInfo &STI) const { 168 const MCOperand &MO = MI.getOperand(OpNo); 169 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 170 171 // Add a fixup for the branch target. 172 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 173 (MCFixupKind)PPC::fixup_ppc_br24abs)); 174 return 0; 175 } 176 177 unsigned PPCMCCodeEmitter:: 178 getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo, 179 SmallVectorImpl<MCFixup> &Fixups, 180 const MCSubtargetInfo &STI) const { 181 const MCOperand &MO = MI.getOperand(OpNo); 182 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 183 184 // Add a fixup for the branch target. 185 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 186 (MCFixupKind)PPC::fixup_ppc_brcond14abs)); 187 return 0; 188 } 189 190 unsigned 191 PPCMCCodeEmitter::getVSRpEvenEncoding(const MCInst &MI, unsigned OpNo, 192 SmallVectorImpl<MCFixup> &Fixups, 193 const MCSubtargetInfo &STI) const { 194 assert(MI.getOperand(OpNo).isReg() && "Operand should be a register"); 195 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) 196 << 1; 197 return RegBits; 198 } 199 200 unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo, 201 SmallVectorImpl<MCFixup> &Fixups, 202 const MCSubtargetInfo &STI) const { 203 const MCOperand &MO = MI.getOperand(OpNo); 204 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 205 206 // Add a fixup for the immediate field. 207 Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), 208 (MCFixupKind)PPC::fixup_ppc_half16)); 209 return 0; 210 } 211 212 uint64_t PPCMCCodeEmitter::getImm34Encoding(const MCInst &MI, unsigned OpNo, 213 SmallVectorImpl<MCFixup> &Fixups, 214 const MCSubtargetInfo &STI, 215 MCFixupKind Fixup) const { 216 const MCOperand &MO = MI.getOperand(OpNo); 217 assert(!MO.isReg() && "Not expecting a register for this operand."); 218 if (MO.isImm()) 219 return getMachineOpValue(MI, MO, Fixups, STI); 220 221 // Add a fixup for the immediate field. 222 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Fixup)); 223 return 0; 224 } 225 226 uint64_t 227 PPCMCCodeEmitter::getImm34EncodingNoPCRel(const MCInst &MI, unsigned OpNo, 228 SmallVectorImpl<MCFixup> &Fixups, 229 const MCSubtargetInfo &STI) const { 230 return getImm34Encoding(MI, OpNo, Fixups, STI, 231 (MCFixupKind)PPC::fixup_ppc_imm34); 232 } 233 234 uint64_t 235 PPCMCCodeEmitter::getImm34EncodingPCRel(const MCInst &MI, unsigned OpNo, 236 SmallVectorImpl<MCFixup> &Fixups, 237 const MCSubtargetInfo &STI) const { 238 return getImm34Encoding(MI, OpNo, Fixups, STI, 239 (MCFixupKind)PPC::fixup_ppc_pcrel34); 240 } 241 242 unsigned PPCMCCodeEmitter::getDispRIEncoding(const MCInst &MI, unsigned OpNo, 243 SmallVectorImpl<MCFixup> &Fixups, 244 const MCSubtargetInfo &STI) const { 245 const MCOperand &MO = MI.getOperand(OpNo); 246 if (MO.isImm()) 247 return getMachineOpValue(MI, MO, Fixups, STI) & 0xFFFF; 248 249 // Add a fixup for the displacement field. 250 Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), 251 (MCFixupKind)PPC::fixup_ppc_half16)); 252 return 0; 253 } 254 255 unsigned 256 PPCMCCodeEmitter::getDispRIXEncoding(const MCInst &MI, unsigned OpNo, 257 SmallVectorImpl<MCFixup> &Fixups, 258 const MCSubtargetInfo &STI) const { 259 const MCOperand &MO = MI.getOperand(OpNo); 260 if (MO.isImm()) 261 return ((getMachineOpValue(MI, MO, Fixups, STI) >> 2) & 0x3FFF); 262 263 // Add a fixup for the displacement field. 264 Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), 265 (MCFixupKind)PPC::fixup_ppc_half16ds)); 266 return 0; 267 } 268 269 unsigned 270 PPCMCCodeEmitter::getDispRIX16Encoding(const MCInst &MI, unsigned OpNo, 271 SmallVectorImpl<MCFixup> &Fixups, 272 const MCSubtargetInfo &STI) const { 273 const MCOperand &MO = MI.getOperand(OpNo); 274 if (MO.isImm()) { 275 assert(!(MO.getImm() % 16) && 276 "Expecting an immediate that is a multiple of 16"); 277 return ((getMachineOpValue(MI, MO, Fixups, STI) >> 4) & 0xFFF); 278 } 279 280 // Otherwise add a fixup for the displacement field. 281 Fixups.push_back(MCFixup::create(IsLittleEndian ? 0 : 2, MO.getExpr(), 282 (MCFixupKind)PPC::fixup_ppc_half16dq)); 283 return 0; 284 } 285 286 unsigned 287 PPCMCCodeEmitter::getDispRIHashEncoding(const MCInst &MI, unsigned OpNo, 288 SmallVectorImpl<MCFixup> &Fixups, 289 const MCSubtargetInfo &STI) const { 290 // Encode imm for the hash load/store to stack for the ROP Protection 291 // instructions. 292 const MCOperand &MO = MI.getOperand(OpNo); 293 294 assert(MO.isImm() && "Expecting an immediate operand."); 295 assert(!(MO.getImm() % 8) && "Expecting offset to be 8 byte aligned."); 296 297 unsigned DX = (MO.getImm() >> 3) & 0x3F; 298 return DX; 299 } 300 301 uint64_t 302 PPCMCCodeEmitter::getDispRI34PCRelEncoding(const MCInst &MI, unsigned OpNo, 303 SmallVectorImpl<MCFixup> &Fixups, 304 const MCSubtargetInfo &STI) const { 305 // Encode the displacement part of pc-relative memri34, which is an imm34. 306 // The 34 bit immediate can fall into one of three cases: 307 // 1) It is a relocation to be filled in by the linker represented as: 308 // (MCExpr::SymbolRef) 309 // 2) It is a relocation + SignedOffset represented as: 310 // (MCExpr::Binary(MCExpr::SymbolRef + MCExpr::Constant)) 311 // 3) It is a known value at compile time. 312 313 // If this is not a MCExpr then we are in case 3) and we are dealing with 314 // a value known at compile time, not a relocation. 315 const MCOperand &MO = MI.getOperand(OpNo); 316 if (!MO.isExpr()) 317 return (getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL; 318 319 // At this point in the function it is known that MO is of type MCExpr. 320 // Therefore we are dealing with either case 1) a symbol ref or 321 // case 2) a symbol ref plus a constant. 322 const MCExpr *Expr = MO.getExpr(); 323 switch (Expr->getKind()) { 324 default: 325 llvm_unreachable("Unsupported MCExpr for getMemRI34PCRelEncoding."); 326 case MCExpr::SymbolRef: { 327 // Relocation alone. 328 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr); 329 (void)SRE; 330 // Currently these are the only valid PCRelative Relocations. 331 assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL || 332 SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL || 333 SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL || 334 SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL || 335 SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL) && 336 "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL or " 337 "VK_PPC_GOT_TLSGD_PCREL or VK_PPC_GOT_TLSLD_PCREL or " 338 "VK_PPC_GOT_TPREL_PCREL."); 339 // Generate the fixup for the relocation. 340 Fixups.push_back( 341 MCFixup::create(0, Expr, 342 static_cast<MCFixupKind>(PPC::fixup_ppc_pcrel34))); 343 // Put zero in the location of the immediate. The linker will fill in the 344 // correct value based on the relocation. 345 return 0; 346 } 347 case MCExpr::Binary: { 348 // Relocation plus some offset. 349 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); 350 assert(BE->getOpcode() == MCBinaryExpr::Add && 351 "Binary expression opcode must be an add."); 352 353 const MCExpr *LHS = BE->getLHS(); 354 const MCExpr *RHS = BE->getRHS(); 355 356 // Need to check in both directions. Reloc+Offset and Offset+Reloc. 357 if (LHS->getKind() != MCExpr::SymbolRef) 358 std::swap(LHS, RHS); 359 360 if (LHS->getKind() != MCExpr::SymbolRef || 361 RHS->getKind() != MCExpr::Constant) 362 llvm_unreachable("Expecting to have one constant and one relocation."); 363 364 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(LHS); 365 (void)SRE; 366 assert(isInt<34>(cast<MCConstantExpr>(RHS)->getValue()) && 367 "Value must fit in 34 bits."); 368 369 // Currently these are the only valid PCRelative Relocations. 370 assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL || 371 SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL) && 372 "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL"); 373 // Generate the fixup for the relocation. 374 Fixups.push_back( 375 MCFixup::create(0, Expr, 376 static_cast<MCFixupKind>(PPC::fixup_ppc_pcrel34))); 377 // Put zero in the location of the immediate. The linker will fill in the 378 // correct value based on the relocation. 379 return 0; 380 } 381 } 382 } 383 384 uint64_t 385 PPCMCCodeEmitter::getDispRI34Encoding(const MCInst &MI, unsigned OpNo, 386 SmallVectorImpl<MCFixup> &Fixups, 387 const MCSubtargetInfo &STI) const { 388 // Encode the displacement part of a memri34. 389 const MCOperand &MO = MI.getOperand(OpNo); 390 return (getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL; 391 } 392 393 unsigned 394 PPCMCCodeEmitter::getDispSPE8Encoding(const MCInst &MI, unsigned OpNo, 395 SmallVectorImpl<MCFixup> &Fixups, 396 const MCSubtargetInfo &STI) const { 397 // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 8). 398 const MCOperand &MO = MI.getOperand(OpNo); 399 assert(MO.isImm()); 400 return getMachineOpValue(MI, MO, Fixups, STI) >> 3; 401 } 402 403 unsigned 404 PPCMCCodeEmitter::getDispSPE4Encoding(const MCInst &MI, unsigned OpNo, 405 SmallVectorImpl<MCFixup> &Fixups, 406 const MCSubtargetInfo &STI) const { 407 // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 4). 408 const MCOperand &MO = MI.getOperand(OpNo); 409 assert(MO.isImm()); 410 return getMachineOpValue(MI, MO, Fixups, STI) >> 2; 411 } 412 413 unsigned 414 PPCMCCodeEmitter::getDispSPE2Encoding(const MCInst &MI, unsigned OpNo, 415 SmallVectorImpl<MCFixup> &Fixups, 416 const MCSubtargetInfo &STI) const { 417 // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 2). 418 const MCOperand &MO = MI.getOperand(OpNo); 419 assert(MO.isImm()); 420 return getMachineOpValue(MI, MO, Fixups, STI) >> 1; 421 } 422 423 unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo, 424 SmallVectorImpl<MCFixup> &Fixups, 425 const MCSubtargetInfo &STI) const { 426 const MCOperand &MO = MI.getOperand(OpNo); 427 if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups, STI); 428 429 // Add a fixup for the TLS register, which simply provides a relocation 430 // hint to the linker that this statement is part of a relocation sequence. 431 // Return the thread-pointer register's encoding. Add a one byte displacement 432 // if using PC relative memops. 433 const MCExpr *Expr = MO.getExpr(); 434 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr); 435 bool IsPCRel = SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL; 436 Fixups.push_back(MCFixup::create(IsPCRel ? 1 : 0, Expr, 437 (MCFixupKind)PPC::fixup_ppc_nofixup)); 438 const Triple &TT = STI.getTargetTriple(); 439 bool isPPC64 = TT.isPPC64(); 440 return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2); 441 } 442 443 unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo, 444 SmallVectorImpl<MCFixup> &Fixups, 445 const MCSubtargetInfo &STI) const { 446 // For special TLS calls, we need two fixups; one for the branch target 447 // (__tls_get_addr), which we create via getDirectBrEncoding as usual, 448 // and one for the TLSGD or TLSLD symbol, which is emitted here. 449 const MCOperand &MO = MI.getOperand(OpNo+1); 450 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 451 (MCFixupKind)PPC::fixup_ppc_nofixup)); 452 return getDirectBrEncoding(MI, OpNo, Fixups, STI); 453 } 454 455 unsigned PPCMCCodeEmitter:: 456 get_crbitm_encoding(const MCInst &MI, unsigned OpNo, 457 SmallVectorImpl<MCFixup> &Fixups, 458 const MCSubtargetInfo &STI) const { 459 const MCOperand &MO = MI.getOperand(OpNo); 460 assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 || 461 MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) && 462 (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)); 463 return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 464 } 465 466 // Get the index for this operand in this instruction. This is needed for 467 // computing the register number in PPC::getRegNumForOperand() for 468 // any instructions that use a different numbering scheme for registers in 469 // different operands. 470 static unsigned getOpIdxForMO(const MCInst &MI, const MCOperand &MO) { 471 for (unsigned i = 0; i < MI.getNumOperands(); i++) { 472 const MCOperand &Op = MI.getOperand(i); 473 if (&Op == &MO) 474 return i; 475 } 476 llvm_unreachable("This operand is not part of this instruction"); 477 return ~0U; // Silence any warnings about no return. 478 } 479 480 uint64_t PPCMCCodeEmitter:: 481 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 482 SmallVectorImpl<MCFixup> &Fixups, 483 const MCSubtargetInfo &STI) const { 484 if (MO.isReg()) { 485 // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand. 486 // The GPR operand should come through here though. 487 assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 && 488 MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) || 489 MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7); 490 unsigned OpNo = getOpIdxForMO(MI, MO); 491 unsigned Reg = 492 PPC::getRegNumForOperand(MCII.get(MI.getOpcode()), MO.getReg(), OpNo); 493 return CTX.getRegisterInfo()->getEncodingValue(Reg); 494 } 495 496 assert(MO.isImm() && 497 "Relocation required in an instruction that we cannot encode!"); 498 return MO.getImm(); 499 } 500 501 void PPCMCCodeEmitter::encodeInstruction(const MCInst &MI, 502 SmallVectorImpl<char> &CB, 503 SmallVectorImpl<MCFixup> &Fixups, 504 const MCSubtargetInfo &STI) const { 505 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 506 507 // Output the constant in big/little endian byte order. 508 unsigned Size = getInstSizeInBytes(MI); 509 llvm::endianness E = 510 IsLittleEndian ? llvm::endianness::little : llvm::endianness::big; 511 switch (Size) { 512 case 0: 513 break; 514 case 4: 515 support::endian::write<uint32_t>(CB, Bits, E); 516 break; 517 case 8: 518 // If we emit a pair of instructions, the first one is 519 // always in the top 32 bits, even on little-endian. 520 support::endian::write<uint32_t>(CB, Bits >> 32, E); 521 support::endian::write<uint32_t>(CB, Bits, E); 522 break; 523 default: 524 llvm_unreachable("Invalid instruction size"); 525 } 526 527 ++MCNumEmitted; // Keep track of the # of mi's emitted. 528 } 529 530 // Get the number of bytes used to encode the given MCInst. 531 unsigned PPCMCCodeEmitter::getInstSizeInBytes(const MCInst &MI) const { 532 unsigned Opcode = MI.getOpcode(); 533 const MCInstrDesc &Desc = MCII.get(Opcode); 534 return Desc.getSize(); 535 } 536 537 bool PPCMCCodeEmitter::isPrefixedInstruction(const MCInst &MI) const { 538 return MCII.get(MI.getOpcode()).TSFlags & PPCII::Prefixed; 539 } 540 541 #include "PPCGenMCCodeEmitter.inc" 542