1 //===-- PPCMCTargetDesc.cpp - PowerPC Target Descriptions -----------------===// 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 provides PowerPC specific target descriptions. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "MCTargetDesc/PPCMCTargetDesc.h" 14 #include "MCTargetDesc/PPCInstPrinter.h" 15 #include "MCTargetDesc/PPCMCAsmInfo.h" 16 #include "PPCELFStreamer.h" 17 #include "PPCMCAsmInfo.h" 18 #include "PPCTargetStreamer.h" 19 #include "PPCXCOFFStreamer.h" 20 #include "TargetInfo/PowerPCTargetInfo.h" 21 #include "llvm/ADT/SmallPtrSet.h" 22 #include "llvm/ADT/StringRef.h" 23 #include "llvm/BinaryFormat/ELF.h" 24 #include "llvm/MC/MCAsmBackend.h" 25 #include "llvm/MC/MCAssembler.h" 26 #include "llvm/MC/MCCodeEmitter.h" 27 #include "llvm/MC/MCContext.h" 28 #include "llvm/MC/MCDwarf.h" 29 #include "llvm/MC/MCELFObjectWriter.h" 30 #include "llvm/MC/MCELFStreamer.h" 31 #include "llvm/MC/MCExpr.h" 32 #include "llvm/MC/MCInstrAnalysis.h" 33 #include "llvm/MC/MCInstrInfo.h" 34 #include "llvm/MC/MCRegisterInfo.h" 35 #include "llvm/MC/MCSectionXCOFF.h" 36 #include "llvm/MC/MCStreamer.h" 37 #include "llvm/MC/MCSubtargetInfo.h" 38 #include "llvm/MC/MCSymbol.h" 39 #include "llvm/MC/MCSymbolELF.h" 40 #include "llvm/MC/MCSymbolXCOFF.h" 41 #include "llvm/MC/MCXCOFFObjectWriter.h" 42 #include "llvm/MC/TargetRegistry.h" 43 #include "llvm/Support/Casting.h" 44 #include "llvm/Support/Compiler.h" 45 #include "llvm/Support/ErrorHandling.h" 46 #include "llvm/Support/FormattedStream.h" 47 #include "llvm/Support/raw_ostream.h" 48 #include "llvm/TargetParser/Triple.h" 49 50 using namespace llvm; 51 52 #define GET_INSTRINFO_MC_DESC 53 #define ENABLE_INSTR_PREDICATE_VERIFIER 54 #include "PPCGenInstrInfo.inc" 55 56 #define GET_SUBTARGETINFO_MC_DESC 57 #include "PPCGenSubtargetInfo.inc" 58 59 #define GET_REGINFO_MC_DESC 60 #include "PPCGenRegisterInfo.inc" 61 62 /// stripRegisterPrefix - This method strips the character prefix from a 63 /// register name so that only the number is left. Used by for linux asm. 64 const char *PPC::stripRegisterPrefix(const char *RegName) { 65 switch (RegName[0]) { 66 case 'a': 67 if (RegName[1] == 'c' && RegName[2] == 'c') 68 return RegName + 3; 69 break; 70 case 'f': 71 if (RegName[1] == 'p') 72 return RegName + 2; 73 [[fallthrough]]; 74 case 'r': 75 case 'v': 76 if (RegName[1] == 's') { 77 if (RegName[2] == 'p') 78 return RegName + 3; 79 return RegName + 2; 80 } 81 return RegName + 1; 82 case 'c': 83 if (RegName[1] == 'r') 84 return RegName + 2; 85 break; 86 case 'w': 87 // For wacc and wacc_hi 88 if (RegName[1] == 'a' && RegName[2] == 'c' && RegName[3] == 'c') { 89 if (RegName[4] == '_') 90 return RegName + 7; 91 else 92 return RegName + 4; 93 } 94 break; 95 case 'd': 96 // For dmr, dmrp, dmrrow, dmrrowp 97 if (RegName[1] == 'm' && RegName[2] == 'r') { 98 if (RegName[3] == 'r' && RegName[4] == 'o' && RegName[5] == 'w' && 99 RegName[6] == 'p') 100 return RegName + 7; 101 else if (RegName[3] == 'r' && RegName[4] == 'o' && RegName[5] == 'w') 102 return RegName + 6; 103 else if (RegName[3] == 'p') 104 return RegName + 4; 105 else 106 return RegName + 3; 107 } 108 break; 109 } 110 111 return RegName; 112 } 113 114 /// getRegNumForOperand - some operands use different numbering schemes 115 /// for the same registers. For example, a VSX instruction may have any of 116 /// vs0-vs63 allocated whereas an Altivec instruction could only have 117 /// vs32-vs63 allocated (numbered as v0-v31). This function returns the actual 118 /// register number needed for the opcode/operand number combination. 119 /// The operand number argument will be useful when we need to extend this 120 /// to instructions that use both Altivec and VSX numbering (for different 121 /// operands). 122 MCRegister PPC::getRegNumForOperand(const MCInstrDesc &Desc, MCRegister Reg, 123 unsigned OpNo) { 124 int16_t regClass = Desc.operands()[OpNo].RegClass; 125 switch (regClass) { 126 // We store F0-F31, VF0-VF31 in MCOperand and it should be F0-F31, 127 // VSX32-VSX63 during encoding/disassembling 128 case PPC::VSSRCRegClassID: 129 case PPC::VSFRCRegClassID: 130 if (PPC::isVFRegister(Reg)) 131 return PPC::VSX32 + (Reg - PPC::VF0); 132 break; 133 // We store VSL0-VSL31, V0-V31 in MCOperand and it should be VSL0-VSL31, 134 // VSX32-VSX63 during encoding/disassembling 135 case PPC::VSRCRegClassID: 136 if (PPC::isVRRegister(Reg)) 137 return PPC::VSX32 + (Reg - PPC::V0); 138 break; 139 // Other RegClass doesn't need mapping 140 default: 141 break; 142 } 143 return Reg; 144 } 145 146 PPCTargetStreamer::PPCTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} 147 148 // Pin the vtable to this file. 149 PPCTargetStreamer::~PPCTargetStreamer() = default; 150 151 static MCInstrInfo *createPPCMCInstrInfo() { 152 MCInstrInfo *X = new MCInstrInfo(); 153 InitPPCMCInstrInfo(X); 154 return X; 155 } 156 157 static MCRegisterInfo *createPPCMCRegisterInfo(const Triple &TT) { 158 bool isPPC64 = 159 (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le); 160 unsigned Flavour = isPPC64 ? 0 : 1; 161 unsigned RA = isPPC64 ? PPC::LR8 : PPC::LR; 162 163 MCRegisterInfo *X = new MCRegisterInfo(); 164 InitPPCMCRegisterInfo(X, RA, Flavour, Flavour); 165 return X; 166 } 167 168 static MCSubtargetInfo *createPPCMCSubtargetInfo(const Triple &TT, 169 StringRef CPU, StringRef FS) { 170 // Set some default feature to MC layer. 171 std::string FullFS = std::string(FS); 172 173 if (TT.isOSAIX()) { 174 if (!FullFS.empty()) 175 FullFS = "+aix," + FullFS; 176 else 177 FullFS = "+aix"; 178 } 179 180 return createPPCMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FullFS); 181 } 182 183 static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI, 184 const Triple &TheTriple, 185 const MCTargetOptions &Options) { 186 bool isPPC64 = (TheTriple.getArch() == Triple::ppc64 || 187 TheTriple.getArch() == Triple::ppc64le); 188 189 MCAsmInfo *MAI; 190 if (TheTriple.isOSBinFormatXCOFF()) 191 MAI = new PPCXCOFFMCAsmInfo(isPPC64, TheTriple); 192 else 193 MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple); 194 195 // Initial state of the frame pointer is R1. 196 unsigned Reg = isPPC64 ? PPC::X1 : PPC::R1; 197 MCCFIInstruction Inst = 198 MCCFIInstruction::cfiDefCfa(nullptr, MRI.getDwarfRegNum(Reg, true), 0); 199 MAI->addInitialFrameState(Inst); 200 201 return MAI; 202 } 203 204 namespace { 205 206 class PPCTargetAsmStreamer : public PPCTargetStreamer { 207 formatted_raw_ostream &OS; 208 209 public: 210 PPCTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS) 211 : PPCTargetStreamer(S), OS(OS) {} 212 213 void emitTCEntry(const MCSymbol &S, PPCMCExpr::Specifier Kind) override { 214 if (const MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(&S)) { 215 MCSymbolXCOFF *TCSym = 216 cast<MCSectionXCOFF>(Streamer.getCurrentSectionOnly()) 217 ->getQualNameSymbol(); 218 // On AIX, we have TLS variable offsets (symbol@({gd|ie|le|ld}) depending 219 // on the TLS access method (or model). For the general-dynamic access 220 // method, we also have region handle (symbol@m) for each variable. For 221 // local-dynamic, there is a module handle (_$TLSML[TC]@ml) for all 222 // variables. Finally for local-exec and initial-exec, we have a thread 223 // pointer, in r13 for 64-bit mode and returned by .__get_tpointer for 224 // 32-bit mode. 225 if (Kind == PPC::S_AIX_TLSGD || Kind == PPC::S_AIX_TLSGDM || 226 Kind == PPC::S_AIX_TLSIE || Kind == PPC::S_AIX_TLSLE || 227 Kind == PPC::S_AIX_TLSLD || Kind == PPC::S_AIX_TLSML) 228 OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << "@" 229 << getContext().getAsmInfo()->getSpecifierName(Kind) << '\n'; 230 else 231 OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << '\n'; 232 233 if (TCSym->hasRename()) 234 Streamer.emitXCOFFRenameDirective(TCSym, TCSym->getSymbolTableName()); 235 return; 236 } 237 238 OS << "\t.tc " << S.getName() << "[TC]," << S.getName() << '\n'; 239 } 240 241 void emitMachine(StringRef CPU) override { 242 const Triple &TT = Streamer.getContext().getTargetTriple(); 243 if (TT.isOSBinFormatXCOFF()) 244 OS << "\t.machine\t" << '\"' << CPU << '\"' << '\n'; 245 else 246 OS << "\t.machine " << CPU << '\n'; 247 } 248 249 void emitAbiVersion(int AbiVersion) override { 250 OS << "\t.abiversion " << AbiVersion << '\n'; 251 } 252 253 void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { 254 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); 255 256 OS << "\t.localentry\t"; 257 S->print(OS, MAI); 258 OS << ", "; 259 MAI->printExpr(OS, *LocalOffset); 260 OS << '\n'; 261 } 262 }; 263 264 class PPCTargetELFStreamer : public PPCTargetStreamer { 265 public: 266 PPCTargetELFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} 267 268 MCELFStreamer &getStreamer() { 269 return static_cast<MCELFStreamer &>(Streamer); 270 } 271 272 void emitTCEntry(const MCSymbol &S, PPCMCExpr::Specifier Kind) override { 273 // Creates a R_PPC64_TOC relocation 274 Streamer.emitValueToAlignment(Align(8)); 275 Streamer.emitSymbolValue(&S, 8); 276 } 277 278 void emitMachine(StringRef CPU) override { 279 // FIXME: Is there anything to do in here or does this directive only 280 // limit the parser? 281 } 282 283 void emitAbiVersion(int AbiVersion) override { 284 ELFObjectWriter &W = getStreamer().getWriter(); 285 unsigned Flags = W.getELFHeaderEFlags(); 286 Flags &= ~ELF::EF_PPC64_ABI; 287 Flags |= (AbiVersion & ELF::EF_PPC64_ABI); 288 W.setELFHeaderEFlags(Flags); 289 } 290 291 void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { 292 293 // encodePPC64LocalEntryOffset will report an error if it cannot 294 // encode LocalOffset. 295 unsigned Encoded = encodePPC64LocalEntryOffset(LocalOffset); 296 297 unsigned Other = S->getOther(); 298 Other &= ~ELF::STO_PPC64_LOCAL_MASK; 299 Other |= Encoded; 300 S->setOther(Other); 301 302 // For GAS compatibility, unless we already saw a .abiversion directive, 303 // set e_flags to indicate ELFv2 ABI. 304 ELFObjectWriter &W = getStreamer().getWriter(); 305 unsigned Flags = W.getELFHeaderEFlags(); 306 if ((Flags & ELF::EF_PPC64_ABI) == 0) 307 W.setELFHeaderEFlags(Flags | 2); 308 } 309 310 void emitAssignment(MCSymbol *S, const MCExpr *Value) override { 311 auto *Symbol = cast<MCSymbolELF>(S); 312 313 // When encoding an assignment to set symbol A to symbol B, also copy 314 // the st_other bits encoding the local entry point offset. 315 if (copyLocalEntry(Symbol, Value)) 316 UpdateOther.insert(Symbol); 317 else 318 UpdateOther.erase(Symbol); 319 } 320 321 void finish() override { 322 for (auto *Sym : UpdateOther) 323 if (Sym->isVariable()) 324 copyLocalEntry(Sym, Sym->getVariableValue()); 325 326 // Clear the set of symbols that needs to be updated so the streamer can 327 // be reused without issues. 328 UpdateOther.clear(); 329 } 330 331 private: 332 SmallPtrSet<MCSymbolELF *, 32> UpdateOther; 333 334 bool copyLocalEntry(MCSymbolELF *D, const MCExpr *S) { 335 auto *Ref = dyn_cast<const MCSymbolRefExpr>(S); 336 if (!Ref) 337 return false; 338 const auto &RhsSym = cast<MCSymbolELF>(Ref->getSymbol()); 339 unsigned Other = D->getOther(); 340 Other &= ~ELF::STO_PPC64_LOCAL_MASK; 341 Other |= RhsSym.getOther() & ELF::STO_PPC64_LOCAL_MASK; 342 D->setOther(Other); 343 return true; 344 } 345 346 unsigned encodePPC64LocalEntryOffset(const MCExpr *LocalOffset) { 347 MCAssembler &MCA = getStreamer().getAssembler(); 348 int64_t Offset; 349 if (!LocalOffset->evaluateAsAbsolute(Offset, MCA)) 350 MCA.getContext().reportError(LocalOffset->getLoc(), 351 ".localentry expression must be absolute"); 352 353 switch (Offset) { 354 default: 355 MCA.getContext().reportError( 356 LocalOffset->getLoc(), ".localentry expression must be a power of 2"); 357 return 0; 358 case 0: 359 return 0; 360 case 1: 361 return 1 << ELF::STO_PPC64_LOCAL_BIT; 362 case 4: 363 case 8: 364 case 16: 365 case 32: 366 case 64: 367 return Log2_32(Offset) << ELF::STO_PPC64_LOCAL_BIT; 368 } 369 } 370 }; 371 372 class PPCTargetMachOStreamer : public PPCTargetStreamer { 373 public: 374 PPCTargetMachOStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} 375 376 void emitTCEntry(const MCSymbol &S, PPCMCExpr::Specifier Kind) override { 377 llvm_unreachable("Unknown pseudo-op: .tc"); 378 } 379 380 void emitMachine(StringRef CPU) override { 381 // FIXME: We should update the CPUType, CPUSubType in the Object file if 382 // the new values are different from the defaults. 383 } 384 385 void emitAbiVersion(int AbiVersion) override { 386 llvm_unreachable("Unknown pseudo-op: .abiversion"); 387 } 388 389 void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { 390 llvm_unreachable("Unknown pseudo-op: .localentry"); 391 } 392 }; 393 394 class PPCTargetXCOFFStreamer : public PPCTargetStreamer { 395 public: 396 PPCTargetXCOFFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} 397 398 void emitTCEntry(const MCSymbol &S, PPCMCExpr::Specifier Kind) override { 399 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); 400 const unsigned PointerSize = MAI->getCodePointerSize(); 401 Streamer.emitValueToAlignment(Align(PointerSize)); 402 Streamer.emitValue(MCSymbolRefExpr::create(&S, Kind, Streamer.getContext()), 403 PointerSize); 404 } 405 406 void emitMachine(StringRef CPU) override { 407 static_cast<XCOFFObjectWriter &>(Streamer.getAssemblerPtr()->getWriter()) 408 .setCPU(CPU); 409 } 410 411 void emitAbiVersion(int AbiVersion) override { 412 llvm_unreachable("ABI-version pseudo-ops are invalid for XCOFF."); 413 } 414 415 void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { 416 llvm_unreachable("Local-entry pseudo-ops are invalid for XCOFF."); 417 } 418 }; 419 420 } // end anonymous namespace 421 422 static MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S, 423 formatted_raw_ostream &OS, 424 MCInstPrinter *InstPrint) { 425 return new PPCTargetAsmStreamer(S, OS); 426 } 427 428 static MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) { 429 return new PPCTargetStreamer(S); 430 } 431 432 static MCTargetStreamer * 433 createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { 434 const Triple &TT = STI.getTargetTriple(); 435 if (TT.isOSBinFormatELF()) 436 return new PPCTargetELFStreamer(S); 437 if (TT.isOSBinFormatXCOFF()) 438 return new PPCTargetXCOFFStreamer(S); 439 return new PPCTargetMachOStreamer(S); 440 } 441 442 static MCInstPrinter *createPPCMCInstPrinter(const Triple &T, 443 unsigned SyntaxVariant, 444 const MCAsmInfo &MAI, 445 const MCInstrInfo &MII, 446 const MCRegisterInfo &MRI) { 447 return new PPCInstPrinter(MAI, MII, MRI, T); 448 } 449 450 namespace { 451 452 class PPCMCInstrAnalysis : public MCInstrAnalysis { 453 public: 454 explicit PPCMCInstrAnalysis(const MCInstrInfo *Info) 455 : MCInstrAnalysis(Info) {} 456 457 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, 458 uint64_t &Target) const override { 459 unsigned NumOps = Inst.getNumOperands(); 460 if (NumOps == 0 || 461 Info->get(Inst.getOpcode()).operands()[NumOps - 1].OperandType != 462 MCOI::OPERAND_PCREL) 463 return false; 464 Target = Addr + Inst.getOperand(NumOps - 1).getImm() * Size; 465 return true; 466 } 467 }; 468 469 } // end anonymous namespace 470 471 static MCInstrAnalysis *createPPCMCInstrAnalysis(const MCInstrInfo *Info) { 472 return new PPCMCInstrAnalysis(Info); 473 } 474 475 extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void 476 LLVMInitializePowerPCTargetMC() { 477 for (Target *T : {&getThePPC32Target(), &getThePPC32LETarget(), 478 &getThePPC64Target(), &getThePPC64LETarget()}) { 479 // Register the MC asm info. 480 RegisterMCAsmInfoFn C(*T, createPPCMCAsmInfo); 481 482 // Register the MC instruction info. 483 TargetRegistry::RegisterMCInstrInfo(*T, createPPCMCInstrInfo); 484 485 // Register the MC register info. 486 TargetRegistry::RegisterMCRegInfo(*T, createPPCMCRegisterInfo); 487 488 // Register the MC subtarget info. 489 TargetRegistry::RegisterMCSubtargetInfo(*T, createPPCMCSubtargetInfo); 490 491 // Register the MC instruction analyzer. 492 TargetRegistry::RegisterMCInstrAnalysis(*T, createPPCMCInstrAnalysis); 493 494 // Register the MC Code Emitter 495 TargetRegistry::RegisterMCCodeEmitter(*T, createPPCMCCodeEmitter); 496 497 // Register the asm backend. 498 TargetRegistry::RegisterMCAsmBackend(*T, createPPCAsmBackend); 499 500 // Register the elf streamer. 501 TargetRegistry::RegisterELFStreamer(*T, createPPCELFStreamer); 502 503 // Register the XCOFF streamer. 504 TargetRegistry::RegisterXCOFFStreamer(*T, createPPCXCOFFStreamer); 505 506 // Register the object target streamer. 507 TargetRegistry::RegisterObjectTargetStreamer(*T, 508 createObjectTargetStreamer); 509 510 // Register the asm target streamer. 511 TargetRegistry::RegisterAsmTargetStreamer(*T, createAsmTargetStreamer); 512 513 // Register the null target streamer. 514 TargetRegistry::RegisterNullTargetStreamer(*T, createNullTargetStreamer); 515 516 // Register the MCInstPrinter. 517 TargetRegistry::RegisterMCInstPrinter(*T, createPPCMCInstPrinter); 518 } 519 } 520