diff options
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 134 |
1 files changed, 80 insertions, 54 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index a0c5498ee620..adefe3b37ee0 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -109,9 +109,9 @@ public: typedef std::tuple<unsigned, bool, uint32_t> HwasanMemaccessTuple; std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols; void LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI); - void EmitHwasanMemaccessSymbols(Module &M); + void emitHwasanMemaccessSymbols(Module &M); - void EmitSled(const MachineInstr &MI, SledKind Kind); + void emitSled(const MachineInstr &MI, SledKind Kind); /// tblgen'erated driver function for lowering simple MI->MC /// pseudo instructions. @@ -178,10 +178,10 @@ private: AArch64FunctionInfo *AArch64FI = nullptr; /// Emit the LOHs contained in AArch64FI. - void EmitLOHs(); + void emitLOHs(); /// Emit instruction to set float register to zero. - void EmitFMov0(const MachineInstr &MI); + void emitFMov0(const MachineInstr &MI); using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>; @@ -191,7 +191,32 @@ private: } // end anonymous namespace void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) { - if (!TM.getTargetTriple().isOSBinFormatELF()) + const Triple &TT = TM.getTargetTriple(); + + if (TT.isOSBinFormatCOFF()) { + // Emit an absolute @feat.00 symbol. This appears to be some kind of + // compiler features bitfield read by link.exe. + MCSymbol *S = MMI->getContext().getOrCreateSymbol(StringRef("@feat.00")); + OutStreamer->BeginCOFFSymbolDef(S); + OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC); + OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL); + OutStreamer->EndCOFFSymbolDef(); + int64_t Feat00Flags = 0; + + if (M.getModuleFlag("cfguard")) { + Feat00Flags |= 0x800; // Object is CFG-aware. + } + + if (M.getModuleFlag("ehcontguard")) { + Feat00Flags |= 0x4000; // Object also has EHCont. + } + + OutStreamer->emitSymbolAttribute(S, MCSA_Global); + OutStreamer->emitAssignment( + S, MCConstantExpr::create(Feat00Flags, MMI->getContext())); + } + + if (!TT.isOSBinFormatELF()) return; // Assemble feature flags that may require creation of a note section. @@ -235,21 +260,18 @@ void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI) return; } - EmitSled(MI, SledKind::FUNCTION_ENTER); + emitSled(MI, SledKind::FUNCTION_ENTER); } -void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI) -{ - EmitSled(MI, SledKind::FUNCTION_EXIT); +void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI) { + emitSled(MI, SledKind::FUNCTION_EXIT); } -void AArch64AsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI) -{ - EmitSled(MI, SledKind::TAIL_CALL); +void AArch64AsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI) { + emitSled(MI, SledKind::TAIL_CALL); } -void AArch64AsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) -{ +void AArch64AsmPrinter::emitSled(const MachineInstr &MI, SledKind Kind) { static const int8_t NoopsInSledCount = 7; // We want to emit the following pattern: // @@ -312,7 +334,7 @@ void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI) { .addExpr(MCSymbolRefExpr::create(Sym, OutContext))); } -void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) { +void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) { if (HwasanMemaccessSymbols.empty()) return; @@ -352,7 +374,7 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) { OutStreamer->SwitchSection(OutContext.getELFSection( ".text.hot", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, - Sym->getName())); + Sym->getName(), /*IsComdat=*/true)); OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction); OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak); @@ -539,7 +561,7 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) { } void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) { - EmitHwasanMemaccessSymbols(M); + emitHwasanMemaccessSymbols(M); const Triple &TT = TM.getTargetTriple(); if (TT.isOSBinFormatMachO()) { @@ -557,7 +579,7 @@ void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) { } -void AArch64AsmPrinter::EmitLOHs() { +void AArch64AsmPrinter::emitLOHs() { SmallVector<MCSymbol *, 3> MCArgs; for (const auto &D : AArch64FI->getLOHContainer()) { @@ -574,7 +596,7 @@ void AArch64AsmPrinter::EmitLOHs() { void AArch64AsmPrinter::emitFunctionBodyEnd() { if (!AArch64FI->getLOHRelated().empty()) - EmitLOHs(); + emitLOHs(); } /// GetCPISymbol - Return the symbol for the specified constant pool entry. @@ -768,11 +790,15 @@ void AArch64AsmPrinter::PrintDebugValueComment(const MachineInstr *MI, OS << MI->getDebugVariable()->getName(); OS << " <- "; // Frame address. Currently handles register +- offset only. - assert(MI->getDebugOperand(0).isReg() && MI->isDebugOffsetImm()); + assert(MI->isIndirectDebugValue()); OS << '['; - printOperand(MI, 0, OS); - OS << '+'; - printOperand(MI, 1, OS); + for (unsigned I = 0, E = std::distance(MI->debug_operands().begin(), + MI->debug_operands().end()); + I < E; ++I) { + if (I != 0) + OS << ", "; + printOperand(MI, I, OS); + } OS << ']'; OS << "+"; printOperand(MI, NOps - 2, OS); @@ -1059,20 +1085,19 @@ void AArch64AsmPrinter::LowerFAULTING_OP(const MachineInstr &FaultingMI) { OutStreamer->emitInstruction(MI, getSubtargetInfo()); } -void AArch64AsmPrinter::EmitFMov0(const MachineInstr &MI) { +void AArch64AsmPrinter::emitFMov0(const MachineInstr &MI) { Register DestReg = MI.getOperand(0).getReg(); if (STI->hasZeroCycleZeroingFP() && !STI->hasZeroCycleZeroingFPWorkaround()) { - // Convert H/S/D register to corresponding Q register + // Convert H/S register to corresponding D register if (AArch64::H0 <= DestReg && DestReg <= AArch64::H31) - DestReg = AArch64::Q0 + (DestReg - AArch64::H0); + DestReg = AArch64::D0 + (DestReg - AArch64::H0); else if (AArch64::S0 <= DestReg && DestReg <= AArch64::S31) - DestReg = AArch64::Q0 + (DestReg - AArch64::S0); - else { + DestReg = AArch64::D0 + (DestReg - AArch64::S0); + else assert(AArch64::D0 <= DestReg && DestReg <= AArch64::D31); - DestReg = AArch64::Q0 + (DestReg - AArch64::D0); - } + MCInst MOVI; - MOVI.setOpcode(AArch64::MOVIv2d_ns); + MOVI.setOpcode(AArch64::MOVID); MOVI.addOperand(MCOperand::createReg(DestReg)); MOVI.addOperand(MCOperand::createImm(0)); EmitToStreamer(*OutStreamer, MOVI); @@ -1185,7 +1210,8 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { } break; - case AArch64::DBG_VALUE: { + case AArch64::DBG_VALUE: + case AArch64::DBG_VALUE_LIST: { if (isVerbose() && OutStreamer->hasRawTextSupport()) { SmallString<128> TmpStr; raw_svector_ostream OS(TmpStr); @@ -1200,13 +1226,13 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { ExceptionHandlingType != ExceptionHandling::ARM) return; - if (needsCFIMoves() == CFI_M_None) + if (getFunctionCFISectionType(*MF) == CFISection::None) return; OutStreamer->emitCFIBKeyFrame(); return; } - } + } // Tail calls use pseudo instructions so they have the proper code-gen // attributes (isCall, isReturn, etc.). We lower them to the real @@ -1322,7 +1348,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { case AArch64::FMOVH0: case AArch64::FMOVS0: case AArch64::FMOVD0: - EmitFMov0(*MI); + emitFMov0(*MI); return; case TargetOpcode::STACKMAP: @@ -1355,29 +1381,29 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { return; case AArch64::SEH_StackAlloc: - TS->EmitARM64WinCFIAllocStack(MI->getOperand(0).getImm()); + TS->emitARM64WinCFIAllocStack(MI->getOperand(0).getImm()); return; case AArch64::SEH_SaveFPLR: - TS->EmitARM64WinCFISaveFPLR(MI->getOperand(0).getImm()); + TS->emitARM64WinCFISaveFPLR(MI->getOperand(0).getImm()); return; case AArch64::SEH_SaveFPLR_X: assert(MI->getOperand(0).getImm() < 0 && "Pre increment SEH opcode must have a negative offset"); - TS->EmitARM64WinCFISaveFPLRX(-MI->getOperand(0).getImm()); + TS->emitARM64WinCFISaveFPLRX(-MI->getOperand(0).getImm()); return; case AArch64::SEH_SaveReg: - TS->EmitARM64WinCFISaveReg(MI->getOperand(0).getImm(), + TS->emitARM64WinCFISaveReg(MI->getOperand(0).getImm(), MI->getOperand(1).getImm()); return; case AArch64::SEH_SaveReg_X: assert(MI->getOperand(1).getImm() < 0 && "Pre increment SEH opcode must have a negative offset"); - TS->EmitARM64WinCFISaveRegX(MI->getOperand(0).getImm(), - -MI->getOperand(1).getImm()); + TS->emitARM64WinCFISaveRegX(MI->getOperand(0).getImm(), + -MI->getOperand(1).getImm()); return; case AArch64::SEH_SaveRegP: @@ -1385,13 +1411,13 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { MI->getOperand(0).getImm() <= 28) { assert((MI->getOperand(0).getImm() - 19) % 2 == 0 && "Register paired with LR must be odd"); - TS->EmitARM64WinCFISaveLRPair(MI->getOperand(0).getImm(), + TS->emitARM64WinCFISaveLRPair(MI->getOperand(0).getImm(), MI->getOperand(2).getImm()); return; } assert((MI->getOperand(1).getImm() - MI->getOperand(0).getImm() == 1) && "Non-consecutive registers not allowed for save_regp"); - TS->EmitARM64WinCFISaveRegP(MI->getOperand(0).getImm(), + TS->emitARM64WinCFISaveRegP(MI->getOperand(0).getImm(), MI->getOperand(2).getImm()); return; @@ -1400,26 +1426,26 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { "Non-consecutive registers not allowed for save_regp_x"); assert(MI->getOperand(2).getImm() < 0 && "Pre increment SEH opcode must have a negative offset"); - TS->EmitARM64WinCFISaveRegPX(MI->getOperand(0).getImm(), + TS->emitARM64WinCFISaveRegPX(MI->getOperand(0).getImm(), -MI->getOperand(2).getImm()); return; case AArch64::SEH_SaveFReg: - TS->EmitARM64WinCFISaveFReg(MI->getOperand(0).getImm(), + TS->emitARM64WinCFISaveFReg(MI->getOperand(0).getImm(), MI->getOperand(1).getImm()); return; case AArch64::SEH_SaveFReg_X: assert(MI->getOperand(1).getImm() < 0 && "Pre increment SEH opcode must have a negative offset"); - TS->EmitARM64WinCFISaveFRegX(MI->getOperand(0).getImm(), + TS->emitARM64WinCFISaveFRegX(MI->getOperand(0).getImm(), -MI->getOperand(1).getImm()); return; case AArch64::SEH_SaveFRegP: assert((MI->getOperand(1).getImm() - MI->getOperand(0).getImm() == 1) && "Non-consecutive registers not allowed for save_regp"); - TS->EmitARM64WinCFISaveFRegP(MI->getOperand(0).getImm(), + TS->emitARM64WinCFISaveFRegP(MI->getOperand(0).getImm(), MI->getOperand(2).getImm()); return; @@ -1428,32 +1454,32 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { "Non-consecutive registers not allowed for save_regp_x"); assert(MI->getOperand(2).getImm() < 0 && "Pre increment SEH opcode must have a negative offset"); - TS->EmitARM64WinCFISaveFRegPX(MI->getOperand(0).getImm(), + TS->emitARM64WinCFISaveFRegPX(MI->getOperand(0).getImm(), -MI->getOperand(2).getImm()); return; case AArch64::SEH_SetFP: - TS->EmitARM64WinCFISetFP(); + TS->emitARM64WinCFISetFP(); return; case AArch64::SEH_AddFP: - TS->EmitARM64WinCFIAddFP(MI->getOperand(0).getImm()); + TS->emitARM64WinCFIAddFP(MI->getOperand(0).getImm()); return; case AArch64::SEH_Nop: - TS->EmitARM64WinCFINop(); + TS->emitARM64WinCFINop(); return; case AArch64::SEH_PrologEnd: - TS->EmitARM64WinCFIPrologEnd(); + TS->emitARM64WinCFIPrologEnd(); return; case AArch64::SEH_EpilogStart: - TS->EmitARM64WinCFIEpilogStart(); + TS->emitARM64WinCFIEpilogStart(); return; case AArch64::SEH_EpilogEnd: - TS->EmitARM64WinCFIEpilogEnd(); + TS->emitARM64WinCFIEpilogEnd(); return; } |