diff options
Diffstat (limited to 'lib/Target/Sparc')
21 files changed, 189 insertions, 119 deletions
diff --git a/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp index 05f78a48badf..c7a5a1e8e6ee 100644 --- a/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ b/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -95,7 +95,6 @@ class SparcAsmParser : public MCTargetAsmParser { unsigned &RegKind); bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc); - bool parseDirectiveWord(unsigned Size, SMLoc L); bool is64Bit() const { return getSTI().getTargetTriple().getArch() == Triple::sparcv9; @@ -109,6 +108,14 @@ public: const MCInstrInfo &MII, const MCTargetOptions &Options) : MCTargetAsmParser(Options, sti, MII), Parser(parser) { + Parser.addAliasForDirective(".half", ".2byte"); + Parser.addAliasForDirective(".uahalf", ".2byte"); + Parser.addAliasForDirective(".word", ".4byte"); + Parser.addAliasForDirective(".uaword", ".4byte"); + Parser.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte"); + if (is64Bit()) + Parser.addAliasForDirective(".xword", ".8byte"); + // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); } @@ -682,21 +689,6 @@ ParseDirective(AsmToken DirectiveID) { StringRef IDVal = DirectiveID.getString(); - if (IDVal == ".byte") - return parseDirectiveWord(1, DirectiveID.getLoc()); - - if (IDVal == ".half") - return parseDirectiveWord(2, DirectiveID.getLoc()); - - if (IDVal == ".word") - return parseDirectiveWord(4, DirectiveID.getLoc()); - - if (IDVal == ".nword") - return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc()); - - if (is64Bit() && IDVal == ".xword") - return parseDirectiveWord(8, DirectiveID.getLoc()); - if (IDVal == ".register") { // For now, ignore .register directive. Parser.eatToEndOfStatement(); @@ -713,28 +705,6 @@ ParseDirective(AsmToken DirectiveID) return true; } -bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) { - if (getLexer().isNot(AsmToken::EndOfStatement)) { - while (true) { - const MCExpr *Value; - if (getParser().parseExpression(Value)) - return true; - - getParser().getStreamer().EmitValue(Value, Size); - - if (getLexer().is(AsmToken::EndOfStatement)) - break; - - // FIXME: Improve diagnostic. - if (getLexer().isNot(AsmToken::Comma)) - return Error(L, "unexpected token in directive"); - Parser.Lex(); - } - } - Parser.Lex(); - return false; -} - OperandMatchResultTy SparcAsmParser::parseMEMOperand(OperandVector &Operands) { SMLoc S, E; @@ -915,9 +885,17 @@ SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op, const MCExpr *Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); - if (isCall && getContext().getObjectFileInfo()->isPositionIndependent()) - Res = SparcMCExpr::create(SparcMCExpr::VK_Sparc_WPLT30, Res, - getContext()); + SparcMCExpr::VariantKind Kind = SparcMCExpr::VK_Sparc_13; + + if (getContext().getObjectFileInfo()->isPositionIndependent()) { + if (isCall) + Kind = SparcMCExpr::VK_Sparc_WPLT30; + else + Kind = SparcMCExpr::VK_Sparc_GOT13; + } + + Res = SparcMCExpr::create(Kind, Res, getContext()); + Op = SparcOperand::CreateImm(Res, S, E); } break; diff --git a/lib/Target/Sparc/CMakeLists.txt b/lib/Target/Sparc/CMakeLists.txt index 312215cf6cde..e60fd4a86121 100644 --- a/lib/Target/Sparc/CMakeLists.txt +++ b/lib/Target/Sparc/CMakeLists.txt @@ -1,14 +1,15 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td) -tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info) -tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info) -tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler) -tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter) -tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer) tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher) +tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer) +tablegen(LLVM SparcGenCallingConv.inc -gen-callingconv) tablegen(LLVM SparcGenDAGISel.inc -gen-dag-isel) +tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler) +tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info) +tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter) +tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info) tablegen(LLVM SparcGenSubtargetInfo.inc -gen-subtarget) -tablegen(LLVM SparcGenCallingConv.inc -gen-callingconv) + add_public_tablegen_target(SparcCommonTableGen) add_llvm_target(SparcCodeGen @@ -27,8 +28,8 @@ add_llvm_target(SparcCodeGen SparcTargetObjectFile.cpp ) -add_subdirectory(TargetInfo) -add_subdirectory(MCTargetDesc) -add_subdirectory(InstPrinter) add_subdirectory(AsmParser) add_subdirectory(Disassembler) +add_subdirectory(InstPrinter) +add_subdirectory(MCTargetDesc) +add_subdirectory(TargetInfo) diff --git a/lib/Target/Sparc/DelaySlotFiller.cpp b/lib/Target/Sparc/DelaySlotFiller.cpp index 9b1d0f5bf3c9..6290e5a15a8b 100644 --- a/lib/Target/Sparc/DelaySlotFiller.cpp +++ b/lib/Target/Sparc/DelaySlotFiller.cpp @@ -207,8 +207,8 @@ Filler::findDelayInstr(MachineBasicBlock &MBB, if (!done) --I; - // skip debug value - if (I->isDebugValue()) + // skip debug instruction + if (I->isDebugInstr()) continue; if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isPosition() || diff --git a/lib/Target/Sparc/LeonFeatures.td b/lib/Target/Sparc/LeonFeatures.td index d9efe094d078..a7dea068cb11 100755 --- a/lib/Target/Sparc/LeonFeatures.td +++ b/lib/Target/Sparc/LeonFeatures.td @@ -37,14 +37,6 @@ def LeonCASA : SubtargetFeature< "Enable CASA instruction for LEON3 and LEON4 processors" >; - -def ReplaceSDIV : SubtargetFeature< - "replacesdiv", - "PerformSDIVReplace", - "true", - "AT697E erratum fix: Do not emit SDIV, emit SDIVCC instead" ->; - def InsertNOPLoad: SubtargetFeature< "insertnopload", "InsertNOPLoad", diff --git a/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp index a38545ecf430..5f5e2ef7d45a 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -14,6 +14,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/TargetRegistry.h" @@ -53,6 +54,10 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { case Sparc::fixup_sparc_hi22: return (Value >> 10) & 0x3fffff; + case Sparc::fixup_sparc_got13: + case Sparc::fixup_sparc_13: + return Value & 0x1fff; + case Sparc::fixup_sparc_pc10: case Sparc::fixup_sparc_got10: case Sparc::fixup_sparc_tls_gd_lo10: @@ -99,14 +104,13 @@ namespace { class SparcAsmBackend : public MCAsmBackend { protected: const Target &TheTarget; - bool IsLittleEndian; bool Is64Bit; public: SparcAsmBackend(const Target &T) - : MCAsmBackend(), TheTarget(T), - IsLittleEndian(StringRef(TheTarget.getName()) == "sparcel"), - Is64Bit(StringRef(TheTarget.getName()) == "sparcv9") {} + : MCAsmBackend(StringRef(T.getName()) == "sparcel" ? support::little + : support::big), + TheTarget(T), Is64Bit(StringRef(TheTarget.getName()) == "sparcv9") {} unsigned getNumFixupKinds() const override { return Sparc::NumTargetFixupKinds; @@ -120,6 +124,7 @@ namespace { { "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_br16_2", 10, 2, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_br16_14", 18, 14, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_sparc_13", 19, 13, 0 }, { "fixup_sparc_hi22", 10, 22, 0 }, { "fixup_sparc_lo10", 22, 10, 0 }, { "fixup_sparc_h44", 10, 22, 0 }, @@ -131,6 +136,7 @@ namespace { { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_got22", 10, 22, 0 }, { "fixup_sparc_got10", 22, 10, 0 }, + { "fixup_sparc_got13", 19, 13, 0 }, { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_tls_gd_hi22", 10, 22, 0 }, { "fixup_sparc_tls_gd_lo10", 22, 10, 0 }, @@ -159,6 +165,7 @@ namespace { { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_br16_2", 20, 2, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_br16_14", 0, 14, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_sparc_13", 0, 13, 0 }, { "fixup_sparc_hi22", 0, 22, 0 }, { "fixup_sparc_lo10", 0, 10, 0 }, { "fixup_sparc_h44", 0, 22, 0 }, @@ -170,6 +177,7 @@ namespace { { "fixup_sparc_pc10", 0, 10, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_got22", 0, 22, 0 }, { "fixup_sparc_got10", 0, 10, 0 }, + { "fixup_sparc_got13", 0, 13, 0 }, { "fixup_sparc_wplt30", 0, 30, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_tls_gd_hi22", 0, 22, 0 }, { "fixup_sparc_tls_gd_lo10", 0, 10, 0 }, @@ -196,7 +204,7 @@ namespace { assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && "Invalid kind!"); - if (IsLittleEndian) + if (Endian == support::little) return InfosLE[Kind - FirstTargetFixupKind]; return InfosBE[Kind - FirstTargetFixupKind]; @@ -233,7 +241,8 @@ namespace { } } - bool mayNeedRelaxation(const MCInst &Inst) const override { + bool mayNeedRelaxation(const MCInst &Inst, + const MCSubtargetInfo &STI) const override { // FIXME. return false; } @@ -254,14 +263,14 @@ namespace { llvm_unreachable("relaxInstruction() unimplemented"); } - bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override { + bool writeNopData(raw_ostream &OS, uint64_t Count) const override { // Cannot emit NOP with size not multiple of 32 bits. if (Count % 4 != 0) return false; uint64_t NumNops = Count / 4; for (uint64_t i = 0; i != NumNops; ++i) - OW->write32(0x01000000); + support::endian::write<uint32_t>(OS, 0x01000000, Endian); return true; } @@ -275,7 +284,8 @@ namespace { void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef<char> Data, - uint64_t Value, bool IsResolved) const override { + uint64_t Value, bool IsResolved, + const MCSubtargetInfo *STI) const override { Value = adjustFixupValue(Fixup.getKind(), Value); if (!Value) return; // Doesn't change encoding. @@ -286,23 +296,23 @@ namespace { // from the fixup value. The Value has been "split up" into the // appropriate bitfields above. for (unsigned i = 0; i != 4; ++i) { - unsigned Idx = IsLittleEndian ? i : 3 - i; + unsigned Idx = Endian == support::little ? i : 3 - i; Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff); } } - std::unique_ptr<MCObjectWriter> - createObjectWriter(raw_pwrite_stream &OS) const override { + std::unique_ptr<MCObjectTargetWriter> + createObjectTargetWriter() const override { uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType); - return createSparcELFObjectWriter(OS, Is64Bit, IsLittleEndian, OSABI); + return createSparcELFObjectWriter(Is64Bit, OSABI); } }; } // end anonymous namespace MCAsmBackend *llvm::createSparcAsmBackend(const Target &T, + const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU, const MCTargetOptions &Options) { - return new ELFSparcAsmBackend(T, TT.getOS()); + return new ELFSparcAsmBackend(T, STI.getTargetTriple().getOS()); } diff --git a/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp index a204036a0975..5a730947796e 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp @@ -79,6 +79,7 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx, case FK_Data_8: return ((Fixup.getOffset() % 8) ? ELF::R_SPARC_UA64 : ELF::R_SPARC_64); + case Sparc::fixup_sparc_13: return ELF::R_SPARC_13; case Sparc::fixup_sparc_hi22: return ELF::R_SPARC_HI22; case Sparc::fixup_sparc_lo10: return ELF::R_SPARC_LO10; case Sparc::fixup_sparc_h44: return ELF::R_SPARC_H44; @@ -88,6 +89,7 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx, case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10; case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT22; case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT10; + case Sparc::fixup_sparc_got13: return ELF::R_SPARC_GOT13; case Sparc::fixup_sparc_tls_gd_hi22: return ELF::R_SPARC_TLS_GD_HI22; case Sparc::fixup_sparc_tls_gd_lo10: return ELF::R_SPARC_TLS_GD_LO10; case Sparc::fixup_sparc_tls_gd_add: return ELF::R_SPARC_TLS_GD_ADD; @@ -132,9 +134,7 @@ bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, } } -std::unique_ptr<MCObjectWriter> -llvm::createSparcELFObjectWriter(raw_pwrite_stream &OS, bool Is64Bit, - bool IsLittleEndian, uint8_t OSABI) { - auto MOTW = llvm::make_unique<SparcELFObjectWriter>(Is64Bit, OSABI); - return createELFObjectWriter(std::move(MOTW), OS, IsLittleEndian); +std::unique_ptr<MCObjectTargetWriter> +llvm::createSparcELFObjectWriter(bool Is64Bit, uint8_t OSABI) { + return llvm::make_unique<SparcELFObjectWriter>(Is64Bit, OSABI); } diff --git a/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h b/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h index 8d79396d936e..99aa63fe2290 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h +++ b/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h @@ -30,6 +30,9 @@ namespace llvm { fixup_sparc_br16_2, fixup_sparc_br16_14, + /// fixup_sparc_13 - 13-bit fixup + fixup_sparc_13, + /// fixup_sparc_hi22 - 22-bit fixup corresponding to %hi(foo) /// for sethi fixup_sparc_hi22, @@ -64,6 +67,9 @@ namespace llvm { /// fixup_sparc_got10 - 10-bit fixup corresponding to %got10(foo) fixup_sparc_got10, + /// fixup_sparc_got13 - 13-bit fixup corresponding to %got13(foo) + fixup_sparc_got13, + /// fixup_sparc_wplt30 fixup_sparc_wplt30, diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp index 684f66970dbe..647be159a151 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp @@ -98,14 +98,9 @@ void SparcMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, computeAvailableFeatures(STI.getFeatureBits())); unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI); - - if (Ctx.getAsmInfo()->isLittleEndian()) { - // Output the bits in little-endian byte order. - support::endian::Writer<support::little>(OS).write<uint32_t>(Bits); - } else { - // Output the bits in big-endian byte order. - support::endian::Writer<support::big>(OS).write<uint32_t>(Bits); - } + support::endian::write(OS, Bits, + Ctx.getAsmInfo()->isLittleEndian() ? support::little + : support::big); unsigned tlsOpNo = 0; switch (MI.getOpcode()) { default: break; diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp index a77f760d9eff..f736a37a266c 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp @@ -58,6 +58,8 @@ bool SparcMCExpr::printVariantKind(raw_ostream &OS, VariantKind Kind) // FIXME: use %got22/%got10, if system assembler supports them. case VK_Sparc_GOT22: OS << "%hi("; break; case VK_Sparc_GOT10: OS << "%lo("; break; + case VK_Sparc_GOT13: closeParen = false; break; + case VK_Sparc_13: closeParen = false; break; case VK_Sparc_WPLT30: closeParen = false; break; case VK_Sparc_R_DISP32: OS << "%r_disp32("; break; case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; break; @@ -96,6 +98,7 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name) .Case("pc10", VK_Sparc_PC10) .Case("got22", VK_Sparc_GOT22) .Case("got10", VK_Sparc_GOT10) + .Case("got13", VK_Sparc_GOT13) .Case("r_disp32", VK_Sparc_R_DISP32) .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22) .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10) @@ -132,6 +135,8 @@ Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::VariantKind Kind) { case VK_Sparc_PC10: return Sparc::fixup_sparc_pc10; case VK_Sparc_GOT22: return Sparc::fixup_sparc_got22; case VK_Sparc_GOT10: return Sparc::fixup_sparc_got10; + case VK_Sparc_GOT13: return Sparc::fixup_sparc_got13; + case VK_Sparc_13: return Sparc::fixup_sparc_13; case VK_Sparc_WPLT30: return Sparc::fixup_sparc_wplt30; case VK_Sparc_TLS_GD_HI22: return Sparc::fixup_sparc_tls_gd_hi22; case VK_Sparc_TLS_GD_LO10: return Sparc::fixup_sparc_tls_gd_lo10; @@ -193,14 +198,26 @@ static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { switch(getKind()) { default: return; + case VK_Sparc_TLS_GD_CALL: + case VK_Sparc_TLS_LDM_CALL: { + // The corresponding relocations reference __tls_get_addr, as they call it, + // but this is only implicit; we must explicitly add it to our symbol table + // to bind it for these uses. + MCSymbol *Symbol = Asm.getContext().getOrCreateSymbol("__tls_get_addr"); + Asm.registerSymbol(*Symbol); + auto ELFSymbol = cast<MCSymbolELF>(Symbol); + if (!ELFSymbol->isBindingSet()) { + ELFSymbol->setBinding(ELF::STB_GLOBAL); + ELFSymbol->setExternal(true); + } + LLVM_FALLTHROUGH; + } case VK_Sparc_TLS_GD_HI22: case VK_Sparc_TLS_GD_LO10: case VK_Sparc_TLS_GD_ADD: - case VK_Sparc_TLS_GD_CALL: case VK_Sparc_TLS_LDM_HI22: case VK_Sparc_TLS_LDM_LO10: case VK_Sparc_TLS_LDM_ADD: - case VK_Sparc_TLS_LDM_CALL: case VK_Sparc_TLS_LDO_HIX22: case VK_Sparc_TLS_LDO_LOX10: case VK_Sparc_TLS_LDO_ADD: diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h index 13f08195c764..cf2db067749c 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h @@ -36,6 +36,8 @@ public: VK_Sparc_PC10, VK_Sparc_GOT22, VK_Sparc_GOT10, + VK_Sparc_GOT13, + VK_Sparc_13, VK_Sparc_WPLT30, VK_Sparc_R_DISP32, VK_Sparc_TLS_GD_HI22, diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h b/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h index 563e6f4efbe6..3cd24104c443 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h @@ -23,7 +23,7 @@ class MCAsmBackend; class MCCodeEmitter; class MCContext; class MCInstrInfo; -class MCObjectWriter; +class MCObjectTargetWriter; class MCRegisterInfo; class MCSubtargetInfo; class MCTargetOptions; @@ -40,12 +40,11 @@ Target &getTheSparcelTarget(); MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx); -MCAsmBackend *createSparcAsmBackend(const Target &T, const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU, +MCAsmBackend *createSparcAsmBackend(const Target &T, const MCSubtargetInfo &STI, + const MCRegisterInfo &MRI, const MCTargetOptions &Options); -std::unique_ptr<MCObjectWriter> -createSparcELFObjectWriter(raw_pwrite_stream &OS, bool Is64Bit, - bool IsLIttleEndian, uint8_t OSABI); +std::unique_ptr<MCObjectTargetWriter> createSparcELFObjectWriter(bool Is64Bit, + uint8_t OSABI); } // End llvm namespace // Defines symbolic names for Sparc registers. This defines a mapping from diff --git a/lib/Target/Sparc/Sparc.td b/lib/Target/Sparc/Sparc.td index 9e0a297c8812..2f9b57f76041 100644 --- a/lib/Target/Sparc/Sparc.td +++ b/lib/Target/Sparc/Sparc.td @@ -130,7 +130,7 @@ def : Processor<"leon2", LEON2Itineraries, // LEON 2 FT (AT697E) // TO DO: Place-holder: Processor specific features will be added *very* soon here. def : Processor<"at697e", LEON2Itineraries, - [FeatureLeon, ReplaceSDIV, InsertNOPLoad]>; + [FeatureLeon, InsertNOPLoad]>; // LEON 2 FT (AT697F) // TO DO: Place-holder: Processor specific features will be added *very* soon here. @@ -176,4 +176,5 @@ def Sparc : Target { let InstructionSet = SparcInstrInfo; let AssemblyParsers = [SparcAsmParser]; let AssemblyWriters = [SparcAsmWriter]; + let AllowRegisterRenaming = 1; } diff --git a/lib/Target/Sparc/SparcFrameLowering.cpp b/lib/Target/Sparc/SparcFrameLowering.cpp index 9864aa372354..9f6c7d65592d 100644 --- a/lib/Target/Sparc/SparcFrameLowering.cpp +++ b/lib/Target/Sparc/SparcFrameLowering.cpp @@ -88,10 +88,11 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF, assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); MachineFrameInfo &MFI = MF.getFrameInfo(); + const SparcSubtarget &Subtarget = MF.getSubtarget<SparcSubtarget>(); const SparcInstrInfo &TII = - *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo()); + *static_cast<const SparcInstrInfo *>(Subtarget.getInstrInfo()); const SparcRegisterInfo &RegInfo = - *static_cast<const SparcRegisterInfo *>(MF.getSubtarget().getRegisterInfo()); + *static_cast<const SparcRegisterInfo *>(Subtarget.getRegisterInfo()); MachineBasicBlock::iterator MBBI = MBB.begin(); // Debug location must be unknown since the first debug location is used // to determine the end of the prologue. @@ -141,7 +142,7 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF, // Adds the SPARC subtarget-specific spill area to the stack // size. Also ensures target-required alignment. - NumBytes = MF.getSubtarget<SparcSubtarget>().getAdjustedFrameSize(NumBytes); + NumBytes = Subtarget.getAdjustedFrameSize(NumBytes); // Finally, ensure that the size is sufficiently aligned for the // data on the stack. @@ -176,9 +177,27 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF, .addCFIIndex(CFIIndex); if (NeedsStackRealignment) { - // andn %o6, MaxAlign-1, %o6 + int64_t Bias = Subtarget.getStackPointerBias(); + unsigned regUnbiased; + if (Bias) { + // This clobbers G1 which we always know is available here. + regUnbiased = SP::G1; + // add %o6, BIAS, %g1 + BuildMI(MBB, MBBI, dl, TII.get(SP::ADDri), regUnbiased) + .addReg(SP::O6).addImm(Bias); + } else + regUnbiased = SP::O6; + + // andn %regUnbiased, MaxAlign-1, %regUnbiased int MaxAlign = MFI.getMaxAlignment(); - BuildMI(MBB, MBBI, dl, TII.get(SP::ANDNri), SP::O6).addReg(SP::O6).addImm(MaxAlign - 1); + BuildMI(MBB, MBBI, dl, TII.get(SP::ANDNri), regUnbiased) + .addReg(regUnbiased).addImm(MaxAlign - 1); + + if (Bias) { + // add %g1, -BIAS, %o6 + BuildMI(MBB, MBBI, dl, TII.get(SP::ADDri), SP::O6) + .addReg(regUnbiased).addImm(-Bias); + } } } diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index c36e75d1b076..f845c41ede45 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -311,6 +311,8 @@ bool SparcDAGToDAGISel::tryInlineAsm(SDNode *N){ if (!Changed) return false; + SelectInlineAsmMemoryOperands(AsmNodeOperands, SDLoc(N)); + SDValue New = CurDAG->getNode(ISD::INLINEASM, SDLoc(N), CurDAG->getVTList(MVT::Other, MVT::Glue), AsmNodeOperands); New->setNodeId(-1); @@ -360,12 +362,6 @@ void SparcDAGToDAGISel::Select(SDNode *N) { // FIXME: Handle div by immediate. unsigned Opcode = N->getOpcode() == ISD::SDIV ? SP::SDIVrr : SP::UDIVrr; - // SDIV is a hardware erratum on some LEON2 processors. Replace it with SDIVcc here. - if (((SparcTargetMachine&)TM).getSubtargetImpl()->performSDIVReplace() - && - Opcode == SP::SDIVrr) { - Opcode = SP::SDIVCCrr; - } CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart); return; } diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index d9548ff90d7f..b04c6b112682 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -1450,7 +1450,7 @@ static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, const SparcSubtarget &STI) : TargetLowering(TM), Subtarget(&STI) { - MVT PtrVT = MVT::getIntegerVT(8 * TM.getPointerSize()); + MVT PtrVT = MVT::getIntegerVT(8 * TM.getPointerSize(0)); // Instructions which use registers as conditionals examine all the // bits (as does the pseudo SELECT_CC expansion). I don't think it @@ -1590,6 +1590,11 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom); setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom); + setOperationAction(ISD::ADDC, MVT::i32, Custom); + setOperationAction(ISD::ADDE, MVT::i32, Custom); + setOperationAction(ISD::SUBC, MVT::i32, Custom); + setOperationAction(ISD::SUBE, MVT::i32, Custom); + if (Subtarget->is64Bit()) { setOperationAction(ISD::ADDC, MVT::i64, Custom); setOperationAction(ISD::ADDE, MVT::i64, Custom); @@ -1700,6 +1705,9 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::UDIV, MVT::i32, Expand); setLibcallName(RTLIB::UDIV_I32, ".udiv"); + + setLibcallName(RTLIB::SREM_I32, ".rem"); + setLibcallName(RTLIB::UREM_I32, ".urem"); } if (Subtarget->is64Bit()) { @@ -1722,6 +1730,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::VAARG , MVT::Other, Custom); setOperationAction(ISD::TRAP , MVT::Other, Legal); + setOperationAction(ISD::DEBUGTRAP , MVT::Other, Legal); // Use the default implementation. setOperationAction(ISD::VACOPY , MVT::Other, Expand); @@ -1975,11 +1984,22 @@ SDValue SparcTargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const { // Handle PIC mode first. SPARC needs a got load for every variable! if (isPositionIndependent()) { - // This is the pic32 code model, the GOT is known to be smaller than 4GB. - SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_GOT22, - SparcMCExpr::VK_Sparc_GOT10, DAG); + const Module *M = DAG.getMachineFunction().getFunction().getParent(); + PICLevel::Level picLevel = M->getPICLevel(); + SDValue Idx; + + if (picLevel == PICLevel::SmallPIC) { + // This is the pic13 code model, the GOT is known to be smaller than 8KiB. + Idx = DAG.getNode(SPISD::Lo, DL, Op.getValueType(), + withTargetFlags(Op, SparcMCExpr::VK_Sparc_GOT13, DAG)); + } else { + // This is the pic32 code model, the GOT is known to be smaller than 4GB. + Idx = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_GOT22, + SparcMCExpr::VK_Sparc_GOT10, DAG); + } + SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT); - SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo); + SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, Idx); // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this // function has calls. MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); @@ -2036,7 +2056,7 @@ SDValue SparcTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const { GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op); - if (DAG.getTarget().Options.EmulatedTLS) + if (DAG.getTarget().useEmulatedTLS()) return LowerToTLSEmulatedModel(GA, DAG); SDLoc DL(GA); @@ -3513,6 +3533,22 @@ SparcTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, return TargetLowering::getRegForInlineAsmConstraint(TRI, newConstraint, VT); } + if (name.substr(0, 1).equals("f") && + !name.substr(1).getAsInteger(10, intVal) && intVal <= 63) { + std::string newConstraint; + + if (VT == MVT::f32 || VT == MVT::Other) { + newConstraint = "{f" + utostr(intVal) + "}"; + } else if (VT == MVT::f64 && (intVal % 2 == 0)) { + newConstraint = "{d" + utostr(intVal / 2) + "}"; + } else if (VT == MVT::f128 && (intVal % 4 == 0)) { + newConstraint = "{q" + utostr(intVal / 4) + "}"; + } else { + return std::make_pair(0U, nullptr); + } + return TargetLowering::getRegForInlineAsmConstraint(TRI, newConstraint, + VT); + } } return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); diff --git a/lib/Target/Sparc/SparcInstrAliases.td b/lib/Target/Sparc/SparcInstrAliases.td index df570cea8da8..352090ed92c1 100644 --- a/lib/Target/Sparc/SparcInstrAliases.td +++ b/lib/Target/Sparc/SparcInstrAliases.td @@ -474,6 +474,19 @@ def : InstAlias<"wr $simm13, %tbr", (WRTBRri G0, i32imm:$simm13), 0>; // flush -> flush %g0 def : InstAlias<"flush", (FLUSH), 0>; +def : MnemonicAlias<"iflush", "flush">; + +def : MnemonicAlias<"stub", "stb">; +def : MnemonicAlias<"stsb", "stb">; + +def : MnemonicAlias<"stuba", "stba">; +def : MnemonicAlias<"stsba", "stba">; + +def : MnemonicAlias<"stuh", "sth">; +def : MnemonicAlias<"stsh", "sth">; + +def : MnemonicAlias<"stuha", "stha">; +def : MnemonicAlias<"stsha", "stha">; def : MnemonicAlias<"lduw", "ld">, Requires<[HasV9]>; def : MnemonicAlias<"lduwa", "lda">, Requires<[HasV9]>; diff --git a/lib/Target/Sparc/SparcInstrInfo.cpp b/lib/Target/Sparc/SparcInstrInfo.cpp index ea8ed830bafc..6750763d8ee5 100644 --- a/lib/Target/Sparc/SparcInstrInfo.cpp +++ b/lib/Target/Sparc/SparcInstrInfo.cpp @@ -280,7 +280,7 @@ unsigned SparcInstrInfo::removeBranch(MachineBasicBlock &MBB, while (I != MBB.begin()) { --I; - if (I->isDebugValue()) + if (I->isDebugInstr()) continue; if (I->getOpcode() != SP::BA diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index 08bccbde0bd6..5b7fb3c485e8 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -421,7 +421,7 @@ let hasSideEffects = 1, mayStore = 1 in { def FLUSHW : F3_1<0b10, 0b101011, (outs), (ins), "flushw", [(flushw)]>, Requires<[HasV9]>; - let rd = 0, rs1 = 1, simm13 = 3 in + let rd = 8, rs1 = 0, simm13 = 3 in def TA3 : F3_2<0b10, 0b111010, (outs), (ins), "ta 3", [(flushw)]>; @@ -1009,6 +1009,9 @@ let DecoderNamespace = "SparcV9", DecoderMethod = "DecodeTRAP", Predicates = [Ha let isBarrier = 1, isTerminator = 1, rd = 0b01000, rs1 = 0, simm13 = 5 in def TA5 : F3_2<0b10, 0b111010, (outs), (ins), "ta 5", [(trap)]>; +let hasSideEffects = 1, rd = 0b01000, rs1 = 0, simm13 = 1 in + def TA1 : F3_2<0b10, 0b111010, (outs), (ins), "ta 1", [(debugtrap)]>; + // Section B.28 - Read State Register Instructions let rs2 = 0 in def RDASR : F3_1<2, 0b101000, @@ -1599,6 +1602,9 @@ let Predicates = [HasV9] in { // Non-Instruction Patterns //===----------------------------------------------------------------------===// +// Zero immediate. +def : Pat<(i32 0), + (ORrr (i32 G0), (i32 G0))>; // Small immediates. def : Pat<(i32 simm13:$val), (ORri (i32 G0), imm:$val)>; diff --git a/lib/Target/Sparc/SparcRegisterInfo.h b/lib/Target/Sparc/SparcRegisterInfo.h index 8dd2569d10de..2a279dad5ae2 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.h +++ b/lib/Target/Sparc/SparcRegisterInfo.h @@ -35,6 +35,8 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo { const TargetRegisterClass *getPointerRegClass(const MachineFunction &MF, unsigned Kind) const override; + bool enableMultipleCopyHints() const override { return true; } + void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS = nullptr) const override; diff --git a/lib/Target/Sparc/SparcSubtarget.cpp b/lib/Target/Sparc/SparcSubtarget.cpp index 01545b8d20a0..40c5683f8495 100644 --- a/lib/Target/Sparc/SparcSubtarget.cpp +++ b/lib/Target/Sparc/SparcSubtarget.cpp @@ -44,7 +44,6 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU, // Leon features HasLeonCasa = false; HasUmacSmac = false; - PerformSDIVReplace = false; InsertNOPLoad = false; FixAllFDIVSQRT = false; DetectRoundChange = false; diff --git a/lib/Target/Sparc/SparcSubtarget.h b/lib/Target/Sparc/SparcSubtarget.h index bcdc96e68103..588a6765bcdf 100644 --- a/lib/Target/Sparc/SparcSubtarget.h +++ b/lib/Target/Sparc/SparcSubtarget.h @@ -50,7 +50,6 @@ class SparcSubtarget : public SparcGenSubtargetInfo { bool InsertNOPLoad; bool FixAllFDIVSQRT; bool DetectRoundChange; - bool PerformSDIVReplace; SparcInstrInfo InstrInfo; SparcTargetLowering TLInfo; @@ -92,7 +91,6 @@ public: // Leon options bool hasUmacSmac() const { return HasUmacSmac; } - bool performSDIVReplace() const { return PerformSDIVReplace; } bool hasLeonCasa() const { return HasLeonCasa; } bool insertNOPLoad() const { return InsertNOPLoad; } bool fixAllFDIVSQRT() const { return FixAllFDIVSQRT; } |