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 "PPCInstrInfo.h" 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/ADT/Statistic.h" 18 #include "llvm/MC/MCFixup.h" 19 #include "llvm/MC/MCInstrDesc.h" 20 #include "llvm/MC/MCRegisterInfo.h" 21 #include "llvm/Support/Endian.h" 22 #include "llvm/Support/EndianStream.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/MathExtras.h" 25 #include "llvm/Support/raw_ostream.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 const PPCInstrInfo *InstrInfo = static_cast<const PPCInstrInfo *>(&MCII); 51 unsigned Opcode = MI.getOpcode(); 52 // Add a fixup for the branch target. 53 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 54 (InstrInfo->isNoTOCCallInstr(Opcode) 55 ? (MCFixupKind)PPC::fixup_ppc_br24_notoc 56 : (MCFixupKind)PPC::fixup_ppc_br24))); 57 return 0; 58 } 59 60 unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo, 61 SmallVectorImpl<MCFixup> &Fixups, 62 const MCSubtargetInfo &STI) const { 63 const MCOperand &MO = MI.getOperand(OpNo); 64 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 65 66 // Add a fixup for the branch target. 67 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 68 (MCFixupKind)PPC::fixup_ppc_brcond14)); 69 return 0; 70 } 71 72 unsigned PPCMCCodeEmitter:: 73 getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo, 74 SmallVectorImpl<MCFixup> &Fixups, 75 const MCSubtargetInfo &STI) const { 76 const MCOperand &MO = MI.getOperand(OpNo); 77 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 78 79 // Add a fixup for the branch target. 80 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 81 (MCFixupKind)PPC::fixup_ppc_br24abs)); 82 return 0; 83 } 84 85 unsigned PPCMCCodeEmitter:: 86 getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo, 87 SmallVectorImpl<MCFixup> &Fixups, 88 const MCSubtargetInfo &STI) const { 89 const MCOperand &MO = MI.getOperand(OpNo); 90 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 91 92 // Add a fixup for the branch target. 93 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 94 (MCFixupKind)PPC::fixup_ppc_brcond14abs)); 95 return 0; 96 } 97 98 unsigned 99 PPCMCCodeEmitter::getVSRpEvenEncoding(const MCInst &MI, unsigned OpNo, 100 SmallVectorImpl<MCFixup> &Fixups, 101 const MCSubtargetInfo &STI) const { 102 assert(MI.getOperand(OpNo).isReg() && "Operand should be a register"); 103 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) 104 << 1; 105 return RegBits; 106 } 107 108 unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo, 109 SmallVectorImpl<MCFixup> &Fixups, 110 const MCSubtargetInfo &STI) const { 111 const MCOperand &MO = MI.getOperand(OpNo); 112 if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); 113 114 // Add a fixup for the immediate field. 115 Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), 116 (MCFixupKind)PPC::fixup_ppc_half16)); 117 return 0; 118 } 119 120 uint64_t PPCMCCodeEmitter::getImm34Encoding(const MCInst &MI, unsigned OpNo, 121 SmallVectorImpl<MCFixup> &Fixups, 122 const MCSubtargetInfo &STI, 123 MCFixupKind Fixup) const { 124 const MCOperand &MO = MI.getOperand(OpNo); 125 assert(!MO.isReg() && "Not expecting a register for this operand."); 126 if (MO.isImm()) 127 return getMachineOpValue(MI, MO, Fixups, STI); 128 129 // Add a fixup for the immediate field. 130 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Fixup)); 131 return 0; 132 } 133 134 uint64_t 135 PPCMCCodeEmitter::getImm34EncodingNoPCRel(const MCInst &MI, unsigned OpNo, 136 SmallVectorImpl<MCFixup> &Fixups, 137 const MCSubtargetInfo &STI) const { 138 return getImm34Encoding(MI, OpNo, Fixups, STI, 139 (MCFixupKind)PPC::fixup_ppc_imm34); 140 } 141 142 uint64_t 143 PPCMCCodeEmitter::getImm34EncodingPCRel(const MCInst &MI, unsigned OpNo, 144 SmallVectorImpl<MCFixup> &Fixups, 145 const MCSubtargetInfo &STI) const { 146 return getImm34Encoding(MI, OpNo, Fixups, STI, 147 (MCFixupKind)PPC::fixup_ppc_pcrel34); 148 } 149 150 unsigned PPCMCCodeEmitter::getDispRIEncoding(const MCInst &MI, unsigned OpNo, 151 SmallVectorImpl<MCFixup> &Fixups, 152 const MCSubtargetInfo &STI) const { 153 const MCOperand &MO = MI.getOperand(OpNo); 154 if (MO.isImm()) 155 return getMachineOpValue(MI, MO, Fixups, STI) & 0xFFFF; 156 157 // Add a fixup for the displacement field. 158 Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), 159 (MCFixupKind)PPC::fixup_ppc_half16)); 160 return 0; 161 } 162 163 unsigned 164 PPCMCCodeEmitter::getDispRIXEncoding(const MCInst &MI, unsigned OpNo, 165 SmallVectorImpl<MCFixup> &Fixups, 166 const MCSubtargetInfo &STI) const { 167 const MCOperand &MO = MI.getOperand(OpNo); 168 if (MO.isImm()) 169 return ((getMachineOpValue(MI, MO, Fixups, STI) >> 2) & 0x3FFF); 170 171 // Add a fixup for the displacement field. 172 Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), 173 (MCFixupKind)PPC::fixup_ppc_half16ds)); 174 return 0; 175 } 176 177 unsigned 178 PPCMCCodeEmitter::getDispRIX16Encoding(const MCInst &MI, unsigned OpNo, 179 SmallVectorImpl<MCFixup> &Fixups, 180 const MCSubtargetInfo &STI) const { 181 const MCOperand &MO = MI.getOperand(OpNo); 182 if (MO.isImm()) { 183 assert(!(MO.getImm() % 16) && 184 "Expecting an immediate that is a multiple of 16"); 185 return ((getMachineOpValue(MI, MO, Fixups, STI) >> 4) & 0xFFF); 186 } 187 188 // Otherwise add a fixup for the displacement field. 189 Fixups.push_back(MCFixup::create(IsLittleEndian ? 0 : 2, MO.getExpr(), 190 (MCFixupKind)PPC::fixup_ppc_half16dq)); 191 return 0; 192 } 193 194 unsigned 195 PPCMCCodeEmitter::getDispRIHashEncoding(const MCInst &MI, unsigned OpNo, 196 SmallVectorImpl<MCFixup> &Fixups, 197 const MCSubtargetInfo &STI) const { 198 // Encode imm for the hash load/store to stack for the ROP Protection 199 // instructions. 200 const MCOperand &MO = MI.getOperand(OpNo); 201 202 assert(MO.isImm() && "Expecting an immediate operand."); 203 assert(!(MO.getImm() % 8) && "Expecting offset to be 8 byte aligned."); 204 205 unsigned DX = (MO.getImm() >> 3) & 0x3F; 206 return DX; 207 } 208 209 uint64_t 210 PPCMCCodeEmitter::getDispRI34PCRelEncoding(const MCInst &MI, unsigned OpNo, 211 SmallVectorImpl<MCFixup> &Fixups, 212 const MCSubtargetInfo &STI) const { 213 // Encode the displacement part of pc-relative memri34, which is an imm34. 214 // The 34 bit immediate can fall into one of three cases: 215 // 1) It is a relocation to be filled in by the linker represented as: 216 // (MCExpr::SymbolRef) 217 // 2) It is a relocation + SignedOffset represented as: 218 // (MCExpr::Binary(MCExpr::SymbolRef + MCExpr::Constant)) 219 // 3) It is a known value at compile time. 220 221 // If this is not a MCExpr then we are in case 3) and we are dealing with 222 // a value known at compile time, not a relocation. 223 const MCOperand &MO = MI.getOperand(OpNo); 224 if (!MO.isExpr()) 225 return (getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL; 226 227 // At this point in the function it is known that MO is of type MCExpr. 228 // Therefore we are dealing with either case 1) a symbol ref or 229 // case 2) a symbol ref plus a constant. 230 const MCExpr *Expr = MO.getExpr(); 231 switch (Expr->getKind()) { 232 default: 233 llvm_unreachable("Unsupported MCExpr for getMemRI34PCRelEncoding."); 234 case MCExpr::SymbolRef: { 235 // Relocation alone. 236 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr); 237 (void)SRE; 238 // Currently these are the only valid PCRelative Relocations. 239 assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL || 240 SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL || 241 SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL || 242 SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL || 243 SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL) && 244 "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL or " 245 "VK_PPC_GOT_TLSGD_PCREL or VK_PPC_GOT_TLSLD_PCREL or " 246 "VK_PPC_GOT_TPREL_PCREL."); 247 // Generate the fixup for the relocation. 248 Fixups.push_back( 249 MCFixup::create(0, Expr, 250 static_cast<MCFixupKind>(PPC::fixup_ppc_pcrel34))); 251 // Put zero in the location of the immediate. The linker will fill in the 252 // correct value based on the relocation. 253 return 0; 254 } 255 case MCExpr::Binary: { 256 // Relocation plus some offset. 257 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); 258 assert(BE->getOpcode() == MCBinaryExpr::Add && 259 "Binary expression opcode must be an add."); 260 261 const MCExpr *LHS = BE->getLHS(); 262 const MCExpr *RHS = BE->getRHS(); 263 264 // Need to check in both directions. Reloc+Offset and Offset+Reloc. 265 if (LHS->getKind() != MCExpr::SymbolRef) 266 std::swap(LHS, RHS); 267 268 if (LHS->getKind() != MCExpr::SymbolRef || 269 RHS->getKind() != MCExpr::Constant) 270 llvm_unreachable("Expecting to have one constant and one relocation."); 271 272 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(LHS); 273 (void)SRE; 274 assert(isInt<34>(cast<MCConstantExpr>(RHS)->getValue()) && 275 "Value must fit in 34 bits."); 276 277 // Currently these are the only valid PCRelative Relocations. 278 assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL || 279 SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL) && 280 "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL"); 281 // Generate the fixup for the relocation. 282 Fixups.push_back( 283 MCFixup::create(0, Expr, 284 static_cast<MCFixupKind>(PPC::fixup_ppc_pcrel34))); 285 // Put zero in the location of the immediate. The linker will fill in the 286 // correct value based on the relocation. 287 return 0; 288 } 289 } 290 } 291 292 uint64_t 293 PPCMCCodeEmitter::getDispRI34Encoding(const MCInst &MI, unsigned OpNo, 294 SmallVectorImpl<MCFixup> &Fixups, 295 const MCSubtargetInfo &STI) const { 296 // Encode the displacement part of a memri34. 297 const MCOperand &MO = MI.getOperand(OpNo); 298 return (getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL; 299 } 300 301 unsigned 302 PPCMCCodeEmitter::getDispSPE8Encoding(const MCInst &MI, unsigned OpNo, 303 SmallVectorImpl<MCFixup> &Fixups, 304 const MCSubtargetInfo &STI) const { 305 // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 8). 306 const MCOperand &MO = MI.getOperand(OpNo); 307 assert(MO.isImm()); 308 return getMachineOpValue(MI, MO, Fixups, STI) >> 3; 309 } 310 311 unsigned 312 PPCMCCodeEmitter::getDispSPE4Encoding(const MCInst &MI, unsigned OpNo, 313 SmallVectorImpl<MCFixup> &Fixups, 314 const MCSubtargetInfo &STI) const { 315 // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 4). 316 const MCOperand &MO = MI.getOperand(OpNo); 317 assert(MO.isImm()); 318 return getMachineOpValue(MI, MO, Fixups, STI) >> 2; 319 } 320 321 unsigned 322 PPCMCCodeEmitter::getDispSPE2Encoding(const MCInst &MI, unsigned OpNo, 323 SmallVectorImpl<MCFixup> &Fixups, 324 const MCSubtargetInfo &STI) const { 325 // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 2). 326 const MCOperand &MO = MI.getOperand(OpNo); 327 assert(MO.isImm()); 328 return getMachineOpValue(MI, MO, Fixups, STI) >> 1; 329 } 330 331 unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo, 332 SmallVectorImpl<MCFixup> &Fixups, 333 const MCSubtargetInfo &STI) const { 334 const MCOperand &MO = MI.getOperand(OpNo); 335 if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups, STI); 336 337 // Add a fixup for the TLS register, which simply provides a relocation 338 // hint to the linker that this statement is part of a relocation sequence. 339 // Return the thread-pointer register's encoding. Add a one byte displacement 340 // if using PC relative memops. 341 const MCExpr *Expr = MO.getExpr(); 342 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr); 343 bool IsPCRel = SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL; 344 Fixups.push_back(MCFixup::create(IsPCRel ? 1 : 0, Expr, 345 (MCFixupKind)PPC::fixup_ppc_nofixup)); 346 const Triple &TT = STI.getTargetTriple(); 347 bool isPPC64 = TT.isPPC64(); 348 return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2); 349 } 350 351 unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo, 352 SmallVectorImpl<MCFixup> &Fixups, 353 const MCSubtargetInfo &STI) const { 354 // For special TLS calls, we need two fixups; one for the branch target 355 // (__tls_get_addr), which we create via getDirectBrEncoding as usual, 356 // and one for the TLSGD or TLSLD symbol, which is emitted here. 357 const MCOperand &MO = MI.getOperand(OpNo+1); 358 Fixups.push_back(MCFixup::create(0, MO.getExpr(), 359 (MCFixupKind)PPC::fixup_ppc_nofixup)); 360 return getDirectBrEncoding(MI, OpNo, Fixups, STI); 361 } 362 363 unsigned PPCMCCodeEmitter:: 364 get_crbitm_encoding(const MCInst &MI, unsigned OpNo, 365 SmallVectorImpl<MCFixup> &Fixups, 366 const MCSubtargetInfo &STI) const { 367 const MCOperand &MO = MI.getOperand(OpNo); 368 assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 || 369 MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) && 370 (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)); 371 return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); 372 } 373 374 // Get the index for this operand in this instruction. This is needed for 375 // computing the register number in PPCInstrInfo::getRegNumForOperand() for 376 // any instructions that use a different numbering scheme for registers in 377 // different operands. 378 static unsigned getOpIdxForMO(const MCInst &MI, const MCOperand &MO) { 379 for (unsigned i = 0; i < MI.getNumOperands(); i++) { 380 const MCOperand &Op = MI.getOperand(i); 381 if (&Op == &MO) 382 return i; 383 } 384 llvm_unreachable("This operand is not part of this instruction"); 385 return ~0U; // Silence any warnings about no return. 386 } 387 388 uint64_t PPCMCCodeEmitter:: 389 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 390 SmallVectorImpl<MCFixup> &Fixups, 391 const MCSubtargetInfo &STI) const { 392 if (MO.isReg()) { 393 // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand. 394 // The GPR operand should come through here though. 395 assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 && 396 MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) || 397 MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7); 398 unsigned OpNo = getOpIdxForMO(MI, MO); 399 unsigned Reg = 400 PPCInstrInfo::getRegNumForOperand(MCII.get(MI.getOpcode()), 401 MO.getReg(), OpNo); 402 return CTX.getRegisterInfo()->getEncodingValue(Reg); 403 } 404 405 assert(MO.isImm() && 406 "Relocation required in an instruction that we cannot encode!"); 407 return MO.getImm(); 408 } 409 410 void PPCMCCodeEmitter::encodeInstruction(const MCInst &MI, 411 SmallVectorImpl<char> &CB, 412 SmallVectorImpl<MCFixup> &Fixups, 413 const MCSubtargetInfo &STI) const { 414 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 415 416 // Output the constant in big/little endian byte order. 417 unsigned Size = getInstSizeInBytes(MI); 418 support::endianness E = IsLittleEndian ? support::little : support::big; 419 switch (Size) { 420 case 0: 421 break; 422 case 4: 423 support::endian::write<uint32_t>(CB, Bits, E); 424 break; 425 case 8: 426 // If we emit a pair of instructions, the first one is 427 // always in the top 32 bits, even on little-endian. 428 support::endian::write<uint32_t>(CB, Bits >> 32, E); 429 support::endian::write<uint32_t>(CB, Bits, E); 430 break; 431 default: 432 llvm_unreachable("Invalid instruction size"); 433 } 434 435 ++MCNumEmitted; // Keep track of the # of mi's emitted. 436 } 437 438 // Get the number of bytes used to encode the given MCInst. 439 unsigned PPCMCCodeEmitter::getInstSizeInBytes(const MCInst &MI) const { 440 unsigned Opcode = MI.getOpcode(); 441 const MCInstrDesc &Desc = MCII.get(Opcode); 442 return Desc.getSize(); 443 } 444 445 bool PPCMCCodeEmitter::isPrefixedInstruction(const MCInst &MI) const { 446 unsigned Opcode = MI.getOpcode(); 447 const PPCInstrInfo *InstrInfo = static_cast<const PPCInstrInfo*>(&MCII); 448 return InstrInfo->isPrefixed(Opcode); 449 } 450 451 #include "PPCGenMCCodeEmitter.inc" 452