diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 |
commit | 91bc56ed825ba56b3cc264aa5c95ab84f86832ab (patch) | |
tree | 4df130b28021d86e13bf4565ef58c1c5a5e093b4 /contrib/llvm/lib/Target/Sparc | |
parent | 9efc7e72bb1daf5d6019871d9c93a1c488a11229 (diff) | |
parent | 5ca98fd98791947eba83a1ed3f2c8191ef7afa6c (diff) |
Merge llvm 3.5.0 release from ^/vendor/llvm/dist, resolve conflicts, and
preserve our customizations, where necessary.
Notes
Notes:
svn path=/projects/clang350-import/; revision=274968
Diffstat (limited to 'contrib/llvm/lib/Target/Sparc')
46 files changed, 2063 insertions, 770 deletions
diff --git a/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp index e7addd75113e..9df005401897 100644 --- a/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ b/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -12,9 +12,11 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/Support/TargetRegistry.h" @@ -45,38 +47,40 @@ class SparcAsmParser : public MCTargetAsmParser { // public interface of the MCTargetAsmParser. bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, - SmallVectorImpl<MCParsedAsmOperand*> &Operands, - MCStreamer &Out, unsigned &ErrorInfo, - bool MatchingInlineAsm); - bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); + OperandVector &Operands, MCStreamer &Out, + unsigned &ErrorInfo, + bool MatchingInlineAsm) override; + bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, - SMLoc NameLoc, - SmallVectorImpl<MCParsedAsmOperand*> &Operands); - bool ParseDirective(AsmToken DirectiveID); + SMLoc NameLoc, OperandVector &Operands) override; + bool ParseDirective(AsmToken DirectiveID) override; - virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op, - unsigned Kind); + unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, + unsigned Kind) override; // Custom parse functions for Sparc specific operands. - OperandMatchResultTy - parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + OperandMatchResultTy parseMEMOperand(OperandVector &Operands); - OperandMatchResultTy - parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, - StringRef Name); + OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name); OperandMatchResultTy - parseSparcAsmOperand(SparcOperand *&Operand); + parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand, + bool isCall = false); + + OperandMatchResultTy parseBranchModifiers(OperandVector &Operands); // returns true if Tok is matched to a register and returns register in RegNo. bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, unsigned &RegKind); bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc); + bool parseDirectiveWord(unsigned Size, SMLoc L); + bool is64Bit() const { return STI.getTargetTriple().startswith("sparcv9"); } public: SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, - const MCInstrInfo &MII) + const MCInstrInfo &MII, + const MCTargetOptions &Options) : MCTargetAsmParser(), STI(sti), Parser(parser) { // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); @@ -145,8 +149,6 @@ private: SMLoc StartLoc, EndLoc; - SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} - struct Token { const char *Data; unsigned Length; @@ -174,10 +176,12 @@ private: struct MemOp Mem; }; public: - bool isToken() const { return Kind == k_Token; } - bool isReg() const { return Kind == k_Register; } - bool isImm() const { return Kind == k_Immediate; } - bool isMem() const { return isMEMrr() || isMEMri(); } + SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} + + bool isToken() const override { return Kind == k_Token; } + bool isReg() const override { return Kind == k_Register; } + bool isImm() const override { return Kind == k_Immediate; } + bool isMem() const override { return isMEMrr() || isMEMri(); } bool isMEMrr() const { return Kind == k_MemoryReg; } bool isMEMri() const { return Kind == k_MemoryImm; } @@ -196,7 +200,7 @@ public: return StringRef(Tok.Data, Tok.Length); } - unsigned getReg() const { + unsigned getReg() const override { assert((Kind == k_Register) && "Invalid access!"); return Reg.RegNum; } @@ -222,22 +226,22 @@ public: } /// getStartLoc - Get the location of the first token of this operand. - SMLoc getStartLoc() const { + SMLoc getStartLoc() const override { return StartLoc; } /// getEndLoc - Get the location of the last token of this operand. - SMLoc getEndLoc() const { + SMLoc getEndLoc() const override { return EndLoc; } - virtual void print(raw_ostream &OS) const { + void print(raw_ostream &OS) const override { switch (Kind) { case k_Token: OS << "Token: " << getToken() << "\n"; break; case k_Register: OS << "Reg: #" << getReg() << "\n"; break; case k_Immediate: OS << "Imm: " << getImm() << "\n"; break; case k_MemoryReg: OS << "Mem: " << getMemBase() << "+" << getMemOffsetReg() << "\n"; break; - case k_MemoryImm: assert(getMemOff() != 0); + case k_MemoryImm: assert(getMemOff() != nullptr); OS << "Mem: " << getMemBase() << "+" << *getMemOff() << "\n"; break; @@ -257,7 +261,7 @@ public: void addExpr(MCInst &Inst, const MCExpr *Expr) const{ // Add as immediate when possible. Null MCExpr = 0. - if (Expr == 0) + if (!Expr) Inst.addOperand(MCOperand::CreateImm(0)); else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) Inst.addOperand(MCOperand::CreateImm(CE->getValue())); @@ -283,8 +287,8 @@ public: addExpr(Inst, Expr); } - static SparcOperand *CreateToken(StringRef Str, SMLoc S) { - SparcOperand *Op = new SparcOperand(k_Token); + static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) { + auto Op = make_unique<SparcOperand>(k_Token); Op->Tok.Data = Str.data(); Op->Tok.Length = Str.size(); Op->StartLoc = S; @@ -292,10 +296,9 @@ public: return Op; } - static SparcOperand *CreateReg(unsigned RegNum, - unsigned Kind, - SMLoc S, SMLoc E) { - SparcOperand *Op = new SparcOperand(k_Register); + static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind, + SMLoc S, SMLoc E) { + auto Op = make_unique<SparcOperand>(k_Register); Op->Reg.RegNum = RegNum; Op->Reg.Kind = (SparcOperand::RegisterKind)Kind; Op->StartLoc = S; @@ -303,61 +306,62 @@ public: return Op; } - static SparcOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { - SparcOperand *Op = new SparcOperand(k_Immediate); + static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S, + SMLoc E) { + auto Op = make_unique<SparcOperand>(k_Immediate); Op->Imm.Val = Val; Op->StartLoc = S; Op->EndLoc = E; return Op; } - static SparcOperand *MorphToDoubleReg(SparcOperand *Op) { - unsigned Reg = Op->getReg(); - assert(Op->Reg.Kind == rk_FloatReg); + static bool MorphToDoubleReg(SparcOperand &Op) { + unsigned Reg = Op.getReg(); + assert(Op.Reg.Kind == rk_FloatReg); unsigned regIdx = Reg - Sparc::F0; if (regIdx % 2 || regIdx > 31) - return 0; - Op->Reg.RegNum = DoubleRegs[regIdx / 2]; - Op->Reg.Kind = rk_DoubleReg; - return Op; + return false; + Op.Reg.RegNum = DoubleRegs[regIdx / 2]; + Op.Reg.Kind = rk_DoubleReg; + return true; } - static SparcOperand *MorphToQuadReg(SparcOperand *Op) { - unsigned Reg = Op->getReg(); + static bool MorphToQuadReg(SparcOperand &Op) { + unsigned Reg = Op.getReg(); unsigned regIdx = 0; - switch (Op->Reg.Kind) { - default: assert(0 && "Unexpected register kind!"); + switch (Op.Reg.Kind) { + default: llvm_unreachable("Unexpected register kind!"); case rk_FloatReg: regIdx = Reg - Sparc::F0; if (regIdx % 4 || regIdx > 31) - return 0; + return false; Reg = QuadFPRegs[regIdx / 4]; break; case rk_DoubleReg: regIdx = Reg - Sparc::D0; if (regIdx % 2 || regIdx > 31) - return 0; + return false; Reg = QuadFPRegs[regIdx / 2]; break; } - Op->Reg.RegNum = Reg; - Op->Reg.Kind = rk_QuadReg; - return Op; + Op.Reg.RegNum = Reg; + Op.Reg.Kind = rk_QuadReg; + return true; } - static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) { + static std::unique_ptr<SparcOperand> + MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) { unsigned offsetReg = Op->getReg(); Op->Kind = k_MemoryReg; Op->Mem.Base = Base; Op->Mem.OffsetReg = offsetReg; - Op->Mem.Off = 0; + Op->Mem.Off = nullptr; return Op; } - static SparcOperand *CreateMEMri(unsigned Base, - const MCExpr *Off, - SMLoc S, SMLoc E) { - SparcOperand *Op = new SparcOperand(k_MemoryImm); + static std::unique_ptr<SparcOperand> + CreateMEMri(unsigned Base, const MCExpr *Off, SMLoc S, SMLoc E) { + auto Op = make_unique<SparcOperand>(k_MemoryImm); Op->Mem.Base = Base; Op->Mem.OffsetReg = 0; Op->Mem.Off = Off; @@ -366,7 +370,8 @@ public: return Op; } - static SparcOperand *MorphToMEMri(unsigned Base, SparcOperand *Op) { + static std::unique_ptr<SparcOperand> + MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) { const MCExpr *Imm = Op->getImm(); Op->Kind = k_MemoryImm; Op->Mem.Base = Base; @@ -378,11 +383,11 @@ public: } // end namespace -bool SparcAsmParser:: -MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, - SmallVectorImpl<MCParsedAsmOperand*> &Operands, - MCStreamer &Out, unsigned &ErrorInfo, - bool MatchingInlineAsm) { +bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, + OperandVector &Operands, + MCStreamer &Out, + unsigned &ErrorInfo, + bool MatchingInlineAsm) { MCInst Inst; SmallVector<MCInst, 8> Instructions; unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, @@ -393,7 +398,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_Success: { Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst); + Out.EmitInstruction(Inst, STI); return false; } @@ -407,7 +412,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, if (ErrorInfo >= Operands.size()) return Error(IDLoc, "too few operands for instruction"); - ErrorLoc = ((SparcOperand*) Operands[ErrorInfo])->getStartLoc(); + ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc(); if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; } @@ -415,7 +420,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return Error(ErrorLoc, "invalid operand for instruction"); } case Match_MnemonicFail: - return Error(IDLoc, "invalid instruction"); + return Error(IDLoc, "invalid instruction mnemonic"); } return true; } @@ -439,21 +444,28 @@ ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) return Error(StartLoc, "invalid register name"); } -bool SparcAsmParser:: -ParseInstruction(ParseInstructionInfo &Info, StringRef Name, - SMLoc NameLoc, - SmallVectorImpl<MCParsedAsmOperand*> &Operands) -{ - // Check if we have valid mnemonic. - if (!mnemonicIsValid(Name, 0)) { - Parser.eatToEndOfStatement(); - return Error(NameLoc, "Unknown instruction"); - } +static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features, + unsigned VariantID); + +bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info, + StringRef Name, SMLoc NameLoc, + OperandVector &Operands) { + // First operand in MCInst is instruction mnemonic. Operands.push_back(SparcOperand::CreateToken(Name, NameLoc)); + // apply mnemonic aliases, if any, so that we can parse operands correctly. + applyMnemonicAliases(Name, getAvailableFeatures(), 0); + if (getLexer().isNot(AsmToken::EndOfStatement)) { // Read the first operand. + if (getLexer().is(AsmToken::Comma)) { + if (parseBranchModifiers(Operands) != MatchOperand_Success) { + SMLoc Loc = getLexer().getLoc(); + Parser.eatToEndOfStatement(); + return Error(Loc, "unexpected token"); + } + } if (parseOperand(Operands, Name) != MatchOperand_Success) { SMLoc Loc = getLexer().getLoc(); Parser.eatToEndOfStatement(); @@ -482,14 +494,57 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, bool SparcAsmParser:: ParseDirective(AsmToken DirectiveID) { - // Ignore all directives for now. - Parser.eatToEndOfStatement(); + 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(); + return false; + } + + // Let the MC layer to handle other directives. + return true; +} + +bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) { + if (getLexer().isNot(AsmToken::EndOfStatement)) { + for (;;) { + 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; } -SparcAsmParser::OperandMatchResultTy SparcAsmParser:: -parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) -{ +SparcAsmParser::OperandMatchResultTy +SparcAsmParser::parseMEMOperand(OperandVector &Operands) { SMLoc S, E; unsigned BaseReg = 0; @@ -504,7 +559,7 @@ parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) case AsmToken::Comma: case AsmToken::RBrac: case AsmToken::EndOfStatement: - Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E)); + Operands.push_back(SparcOperand::CreateMEMri(BaseReg, nullptr, S, E)); return MatchOperand_Success; case AsmToken:: Plus: @@ -514,23 +569,20 @@ parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) break; } - SparcOperand *Offset = 0; + std::unique_ptr<SparcOperand> Offset; OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset); if (ResTy != MatchOperand_Success || !Offset) return MatchOperand_NoMatch; - Offset = (Offset->isImm() - ? SparcOperand::MorphToMEMri(BaseReg, Offset) - : SparcOperand::MorphToMEMrr(BaseReg, Offset)); + Operands.push_back( + Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset)) + : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset))); - Operands.push_back(Offset); return MatchOperand_Success; } -SparcAsmParser::OperandMatchResultTy SparcAsmParser:: -parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, - StringRef Mnemonic) -{ +SparcAsmParser::OperandMatchResultTy +SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); @@ -576,26 +628,27 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, return MatchOperand_Success; } - SparcOperand *Op = 0; - ResTy = parseSparcAsmOperand(Op); + std::unique_ptr<SparcOperand> Op; + + ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call")); if (ResTy != MatchOperand_Success || !Op) return MatchOperand_ParseFail; // Push the parsed operand into the list of operands - Operands.push_back(Op); + Operands.push_back(std::move(Op)); return MatchOperand_Success; } SparcAsmParser::OperandMatchResultTy -SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op) -{ +SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op, + bool isCall) { SMLoc S = Parser.getTok().getLoc(); SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); const MCExpr *EVal; - Op = 0; + Op = nullptr; switch (getLexer().getKind()) { default: break; @@ -621,11 +674,6 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op) else Op = SparcOperand::CreateToken("%icc", S); break; - - case Sparc::FCC: - assert(name == "fcc0" && "Cannot handle %fcc other than %fcc0 yet"); - Op = SparcOperand::CreateToken("%fcc0", S); - break; } break; } @@ -649,6 +697,10 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op) const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); + if (isCall && + getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) + Res = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_WPLT30, Res, + getContext()); Op = SparcOperand::CreateImm(Res, S, E); } break; @@ -657,6 +709,27 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op) return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; } +SparcAsmParser::OperandMatchResultTy +SparcAsmParser::parseBranchModifiers(OperandVector &Operands) { + + // parse (,a|,pn|,pt)+ + + while (getLexer().is(AsmToken::Comma)) { + + Parser.Lex(); // Eat the comma + + if (!getLexer().is(AsmToken::Identifier)) + return MatchOperand_ParseFail; + StringRef modName = Parser.getTok().getString(); + if (modName == "a" || modName == "pn" || modName == "pt") { + Operands.push_back(SparcOperand::CreateToken(modName, + Parser.getTok().getLoc())); + Parser.Lex(); // eat the identifier. + } + } + return MatchOperand_Success; +} + bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, unsigned &RegNo, unsigned &RegKind) @@ -704,7 +777,7 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, && !name.substr(3).getAsInteger(10, intVal) && intVal < 4) { // FIXME: check 64bit and handle %fcc1 - %fcc3 - RegNo = Sparc::FCC; + RegNo = Sparc::FCC0 + intVal; RegKind = SparcOperand::rk_CCReg; return true; } @@ -767,6 +840,31 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, return false; } +static bool hasGOTReference(const MCExpr *Expr) { + switch (Expr->getKind()) { + case MCExpr::Target: + if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr)) + return hasGOTReference(SE->getSubExpr()); + break; + + case MCExpr::Constant: + break; + + case MCExpr::Binary: { + const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); + return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS()); + } + + case MCExpr::SymbolRef: { + const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr); + return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_"); + } + + case MCExpr::Unary: + return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr()); + } + return false; +} bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc) @@ -790,6 +888,23 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal, const MCExpr *subExpr; if (Parser.parseParenExpression(subExpr, EndLoc)) return false; + + bool isPIC = getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_; + + switch(VK) { + default: break; + case SparcMCExpr::VK_Sparc_LO: + VK = (hasGOTReference(subExpr) + ? SparcMCExpr::VK_Sparc_PC10 + : (isPIC ? SparcMCExpr::VK_Sparc_GOT10 : VK)); + break; + case SparcMCExpr::VK_Sparc_HI: + VK = (hasGOTReference(subExpr) + ? SparcMCExpr::VK_Sparc_PC22 + : (isPIC ? SparcMCExpr::VK_Sparc_GOT22 : VK)); + break; + } + EVal = SparcMCExpr::Create(VK, subExpr, getContext()); return true; } @@ -804,18 +919,14 @@ extern "C" void LLVMInitializeSparcAsmParser() { #define GET_MATCHER_IMPLEMENTATION #include "SparcGenAsmMatcher.inc" - - -unsigned SparcAsmParser:: -validateTargetOperandClass(MCParsedAsmOperand *GOp, - unsigned Kind) -{ - SparcOperand *Op = (SparcOperand*)GOp; - if (Op->isFloatOrDoubleReg()) { +unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp, + unsigned Kind) { + SparcOperand &Op = (SparcOperand &)GOp; + if (Op.isFloatOrDoubleReg()) { switch (Kind) { default: break; case MCK_DFPRegs: - if (!Op->isFloatReg() || SparcOperand::MorphToDoubleReg(Op)) + if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op)) return MCTargetAsmParser::Match_Success; break; case MCK_QFPRegs: diff --git a/contrib/llvm/lib/Target/Sparc/DelaySlotFiller.cpp b/contrib/llvm/lib/Target/Sparc/DelaySlotFiller.cpp index f23ddc24eab7..f3441ffcf6a6 100644 --- a/contrib/llvm/lib/Target/Sparc/DelaySlotFiller.cpp +++ b/contrib/llvm/lib/Target/Sparc/DelaySlotFiller.cpp @@ -12,7 +12,6 @@ // NOP is placed. //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "delay-slot-filler" #include "Sparc.h" #include "SparcSubtarget.h" #include "llvm/ADT/SmallSet.h" @@ -27,6 +26,8 @@ using namespace llvm; +#define DEBUG_TYPE "delay-slot-filler" + STATISTIC(FilledSlots, "Number of delay slots filled"); static cl::opt<bool> DisableDelaySlotFiller( @@ -49,12 +50,12 @@ namespace { Subtarget(&TM.getSubtarget<SparcSubtarget>()) { } - virtual const char *getPassName() const { + const char *getPassName() const override { return "SPARC Delay Slot Filler"; } bool runOnMachineBasicBlock(MachineBasicBlock &MBB); - bool runOnMachineFunction(MachineFunction &F) { + bool runOnMachineFunction(MachineFunction &F) override { bool Changed = false; // This pass invalidates liveness information when it reorders @@ -211,12 +212,8 @@ Filler::findDelayInstr(MachineBasicBlock &MBB, if (I->isDebugValue()) continue; - - if (I->hasUnmodeledSideEffects() - || I->isInlineAsm() - || I->isLabel() - || I->hasDelaySlot() - || I->isBundledWithSucc()) + if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isPosition() || + I->hasDelaySlot() || I->isBundledWithSucc()) break; if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) { @@ -479,7 +476,7 @@ bool Filler::tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB, && MBBI->getOperand(1).getReg() == SP::G0 && MBBI->getOperand(2).getReg() == SP::G0); - MachineBasicBlock::iterator PrevInst = llvm::prior(MBBI); + MachineBasicBlock::iterator PrevInst = std::prev(MBBI); // It cannot be combined with a bundled instruction. if (PrevInst->isBundledWithSucc()) diff --git a/contrib/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/contrib/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index 6233805431c1..4df09904c9f6 100644 --- a/contrib/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/contrib/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -11,8 +11,6 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sparc-disassembler" - #include "Sparc.h" #include "SparcRegisterInfo.h" #include "SparcSubtarget.h" @@ -23,6 +21,8 @@ using namespace llvm; +#define DEBUG_TYPE "sparc-disassembler" + typedef MCDisassembler::DecodeStatus DecodeStatus; namespace { @@ -32,22 +32,18 @@ class SparcDisassembler : public MCDisassembler { public: /// Constructor - Initializes the disassembler. /// - SparcDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) : - MCDisassembler(STI), RegInfo(Info) + SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) : + MCDisassembler(STI, Ctx) {} virtual ~SparcDisassembler() {} - const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } - /// getInstruction - See MCDisassembler. - virtual DecodeStatus getInstruction(MCInst &instr, - uint64_t &size, - const MemoryObject ®ion, - uint64_t address, - raw_ostream &vStream, - raw_ostream &cStream) const; -private: - OwningPtr<const MCRegisterInfo> RegInfo; + DecodeStatus getInstruction(MCInst &instr, + uint64_t &size, + const MemoryObject ®ion, + uint64_t address, + raw_ostream &vStream, + raw_ostream &cStream) const override; }; } @@ -58,8 +54,9 @@ namespace llvm { static MCDisassembler *createSparcDisassembler( const Target &T, - const MCSubtargetInfo &STI) { - return new SparcDisassembler(STI, T.createMCRegInfo("")); + const MCSubtargetInfo &STI, + MCContext &Ctx) { + return new SparcDisassembler(STI, Ctx); } @@ -113,6 +110,9 @@ static const unsigned QFPRegDecoderTable[] = { SP::Q6, SP::Q14, ~0U, ~0U, SP::Q7, SP::Q15, ~0U, ~0U } ; +static const unsigned FCCRegDecoderTable[] = { + SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 }; + static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -174,6 +174,42 @@ static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 3) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::CreateReg(FCCRegDecoderTable[RegNo])); + return MCDisassembler::Success; +} + + +static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder); +static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder); +static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder); +static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder); +static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder); +static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, + const void *Decoder); +static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder); #include "SparcGenDisassemblerTables.inc" @@ -226,3 +262,219 @@ SparcDisassembler::getInstruction(MCInst &instr, return MCDisassembler::Fail; } + + +typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address, + const void *Decoder, + bool isLoad, DecodeFunc DecodeRD) { + unsigned rd = fieldFromInstruction(insn, 25, 5); + unsigned rs1 = fieldFromInstruction(insn, 14, 5); + bool isImm = fieldFromInstruction(insn, 13, 1); + unsigned rs2 = 0; + unsigned simm13 = 0; + if (isImm) + simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); + else + rs2 = fieldFromInstruction(insn, 0, 5); + + DecodeStatus status; + if (isLoad) { + status = DecodeRD(MI, rd, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + } + + // Decode rs1. + status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + + // Decode imm|rs2. + if (isImm) + MI.addOperand(MCOperand::CreateImm(simm13)); + else { + status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + } + + if (!isLoad) { + status = DecodeRD(MI, rd, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + } + return MCDisassembler::Success; +} + +static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder) { + return DecodeMem(Inst, insn, Address, Decoder, true, + DecodeIntRegsRegisterClass); +} + +static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder) { + return DecodeMem(Inst, insn, Address, Decoder, true, + DecodeFPRegsRegisterClass); +} + +static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder) { + return DecodeMem(Inst, insn, Address, Decoder, true, + DecodeDFPRegsRegisterClass); +} + +static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder) { + return DecodeMem(Inst, insn, Address, Decoder, true, + DecodeQFPRegsRegisterClass); +} + +static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, + uint64_t Address, const void *Decoder) { + return DecodeMem(Inst, insn, Address, Decoder, false, + DecodeIntRegsRegisterClass); +} + +static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder) { + return DecodeMem(Inst, insn, Address, Decoder, false, + DecodeFPRegsRegisterClass); +} + +static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, + uint64_t Address, const void *Decoder) { + return DecodeMem(Inst, insn, Address, Decoder, false, + DecodeDFPRegsRegisterClass); +} + +static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, + uint64_t Address, const void *Decoder) { + return DecodeMem(Inst, insn, Address, Decoder, false, + DecodeQFPRegsRegisterClass); +} + +static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, + uint64_t Address, uint64_t Offset, + uint64_t Width, MCInst &MI, + const void *Decoder) { + const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); + return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, + Offset, Width); +} + +static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, + uint64_t Address, const void *Decoder) { + unsigned tgt = fieldFromInstruction(insn, 0, 30); + tgt <<= 2; + if (!tryAddingSymbolicOperand(tgt+Address, false, Address, + 0, 30, MI, Decoder)) + MI.addOperand(MCOperand::CreateImm(tgt)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, + uint64_t Address, const void *Decoder) { + unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); + MI.addOperand(MCOperand::CreateImm(tgt)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address, + const void *Decoder) { + + unsigned rd = fieldFromInstruction(insn, 25, 5); + unsigned rs1 = fieldFromInstruction(insn, 14, 5); + unsigned isImm = fieldFromInstruction(insn, 13, 1); + unsigned rs2 = 0; + unsigned simm13 = 0; + if (isImm) + simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); + else + rs2 = fieldFromInstruction(insn, 0, 5); + + // Decode RD. + DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + + // Decode RS1. + status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + + // Decode RS1 | SIMM13. + if (isImm) + MI.addOperand(MCOperand::CreateImm(simm13)); + else { + status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + } + return MCDisassembler::Success; +} + +static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, + const void *Decoder) { + + unsigned rs1 = fieldFromInstruction(insn, 14, 5); + unsigned isImm = fieldFromInstruction(insn, 13, 1); + unsigned rs2 = 0; + unsigned simm13 = 0; + if (isImm) + simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); + else + rs2 = fieldFromInstruction(insn, 0, 5); + + // Decode RS1. + DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + + // Decode RS2 | SIMM13. + if (isImm) + MI.addOperand(MCOperand::CreateImm(simm13)); + else { + status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + } + return MCDisassembler::Success; +} + +static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address, + const void *Decoder) { + + unsigned rd = fieldFromInstruction(insn, 25, 5); + unsigned rs1 = fieldFromInstruction(insn, 14, 5); + unsigned isImm = fieldFromInstruction(insn, 13, 1); + unsigned rs2 = 0; + unsigned simm13 = 0; + if (isImm) + simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); + else + rs2 = fieldFromInstruction(insn, 0, 5); + + // Decode RD. + DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + + // Decode RS1. + status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + + // Decode RS1 | SIMM13. + if (isImm) + MI.addOperand(MCOperand::CreateImm(simm13)); + else { + status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); + if (status != MCDisassembler::Success) + return status; + } + return MCDisassembler::Success; +} diff --git a/contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp b/contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp index 6d7457ae040b..5975a517994a 100644 --- a/contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp +++ b/contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp @@ -11,20 +11,33 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "asm-printer" #include "SparcInstPrinter.h" - #include "Sparc.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +#define DEBUG_TYPE "asm-printer" + +// The generated AsmMatcher SparcGenAsmWriter uses "Sparc" as the target +// namespace. But SPARC backend uses "SP" as its namespace. +namespace llvm { +namespace Sparc { + using namespace SP; +} +} + #define GET_INSTRUCTION_NAME #define PRINT_ALIAS_INSTR #include "SparcGenAsmWriter.inc" +bool SparcInstPrinter::isV9() const { + return (STI.getFeatureBits() & Sparc::FeatureV9) != 0; +} + void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { OS << '%' << StringRef(getRegisterName(RegNo)).lower(); @@ -50,7 +63,15 @@ bool SparcInstPrinter::printSparcAliasInstr(const MCInst *MI, raw_ostream &O) return false; switch (MI->getOperand(0).getReg()) { default: return false; - case SP::G0: // jmp $addr + case SP::G0: // jmp $addr | ret | retl + if (MI->getOperand(2).isImm() && + MI->getOperand(2).getImm() == 8) { + switch(MI->getOperand(1).getReg()) { + default: break; + case SP::I7: O << "\tret"; return true; + case SP::O7: O << "\tretl"; return true; + } + } O << "\tjmp "; printMemOperand(MI, 1, O); return true; case SP::O7: // call $addr @@ -58,6 +79,28 @@ bool SparcInstPrinter::printSparcAliasInstr(const MCInst *MI, raw_ostream &O) return true; } } + case SP::V9FCMPS: case SP::V9FCMPD: case SP::V9FCMPQ: + case SP::V9FCMPES: case SP::V9FCMPED: case SP::V9FCMPEQ: { + if (isV9() + || (MI->getNumOperands() != 3) + || (!MI->getOperand(0).isReg()) + || (MI->getOperand(0).getReg() != SP::FCC0)) + return false; + // if V8, skip printing %fcc0. + switch(MI->getOpcode()) { + default: + case SP::V9FCMPS: O << "\tfcmps "; break; + case SP::V9FCMPD: O << "\tfcmpd "; break; + case SP::V9FCMPQ: O << "\tfcmpq "; break; + case SP::V9FCMPES: O << "\tfcmpes "; break; + case SP::V9FCMPED: O << "\tfcmped "; break; + case SP::V9FCMPEQ: O << "\tfcmpeq "; break; + } + printOperand(MI, 1, O); + O << ", "; + printOperand(MI, 2, O); + return true; + } } } @@ -110,11 +153,17 @@ void SparcInstPrinter::printCCOperand(const MCInst *MI, int opNum, switch (MI->getOpcode()) { default: break; case SP::FBCOND: - case SP::MOVFCCrr: - case SP::MOVFCCri: - case SP::FMOVS_FCC: - case SP::FMOVD_FCC: - case SP::FMOVQ_FCC: // Make sure CC is a fp conditional flag. + case SP::FBCONDA: + case SP::BPFCC: + case SP::BPFCCA: + case SP::BPFCCNT: + case SP::BPFCCANT: + case SP::MOVFCCrr: case SP::V9MOVFCCrr: + case SP::MOVFCCri: case SP::V9MOVFCCri: + case SP::FMOVS_FCC: case SP::V9FMOVS_FCC: + case SP::FMOVD_FCC: case SP::V9FMOVD_FCC: + case SP::FMOVQ_FCC: case SP::V9FMOVQ_FCC: + // Make sure CC is a fp conditional flag. CC = (CC < 16) ? (CC + 16) : CC; break; } @@ -124,6 +173,6 @@ void SparcInstPrinter::printCCOperand(const MCInst *MI, int opNum, bool SparcInstPrinter::printGetPCX(const MCInst *MI, unsigned opNum, raw_ostream &O) { - assert(0 && "FIXME: Implement SparcInstPrinter::printGetPCX."); + llvm_unreachable("FIXME: Implement SparcInstPrinter::printGetPCX."); return true; } diff --git a/contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.h b/contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.h index 63ed41a4c12c..8fe4075d137f 100644 --- a/contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.h +++ b/contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.h @@ -15,30 +15,36 @@ #define SparcINSTPRINTER_H #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCSubtargetInfo.h" namespace llvm { class MCOperand; class SparcInstPrinter : public MCInstPrinter { + const MCSubtargetInfo &STI; public: SparcInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, - const MCRegisterInfo &MRI) - : MCInstPrinter(MAI, MII, MRI) {} + const MCRegisterInfo &MRI, + const MCSubtargetInfo &sti) + : MCInstPrinter(MAI, MII, MRI), STI(sti) {} - virtual void printRegName(raw_ostream &OS, unsigned RegNo) const; - virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot); + void printRegName(raw_ostream &OS, unsigned RegNo) const override; + void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot) override; bool printSparcAliasInstr(const MCInst *MI, raw_ostream &OS); + bool isV9() const; // Autogenerated by tblgen. void printInstruction(const MCInst *MI, raw_ostream &O); bool printAliasInstr(const MCInst *MI, raw_ostream &O); + void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx, + unsigned PrintMethodIdx, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); void printOperand(const MCInst *MI, int opNum, raw_ostream &OS); void printMemOperand(const MCInst *MI, int opNum, raw_ostream &OS, - const char *Modifier = 0); + const char *Modifier = nullptr); void printCCOperand(const MCInst *MI, int opNum, raw_ostream &OS); bool printGetPCX(const MCInst *MI, unsigned OpNo, raw_ostream &OS); diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp index 6d2dd8309a05..dcd81e3d6249 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -8,11 +8,13 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCAsmBackend.h" -#include "MCTargetDesc/SparcMCTargetDesc.h" #include "MCTargetDesc/SparcFixupKinds.h" +#include "MCTargetDesc/SparcMCTargetDesc.h" #include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCValue.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; @@ -37,6 +39,12 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { case Sparc::fixup_sparc_br19: return (Value >> 2) & 0x7ffff; + case Sparc::fixup_sparc_br16_2: + return (Value >> 2) & 0xc000; + + case Sparc::fixup_sparc_br16_14: + return (Value >> 2) & 0x3fff; + case Sparc::fixup_sparc_pc22: case Sparc::fixup_sparc_got22: case Sparc::fixup_sparc_tls_gd_hi22: @@ -94,16 +102,18 @@ namespace { public: SparcAsmBackend(const Target &T) : MCAsmBackend(), TheTarget(T) {} - unsigned getNumFixupKinds() const { + unsigned getNumFixupKinds() const override { return Sparc::NumTargetFixupKinds; } - const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = { // name offset bits flags { "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel }, { "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_hi22", 10, 22, 0 }, { "fixup_sparc_lo10", 22, 10, 0 }, { "fixup_sparc_h44", 10, 22, 0 }, @@ -144,16 +154,15 @@ namespace { return Infos[Kind - FirstTargetFixupKind]; } - void processFixupValue(const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFixup &Fixup, - const MCFragment *DF, - MCValue & Target, - uint64_t &Value, - bool &IsResolved) { + void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFixup &Fixup, const MCFragment *DF, + const MCValue &Target, uint64_t &Value, + bool &IsResolved) override { switch ((Sparc::Fixups)Fixup.getKind()) { default: break; case Sparc::fixup_sparc_wplt30: + if (Target.getSymA()->getSymbol().isTemporary()) + return; case Sparc::fixup_sparc_tls_gd_hi22: case Sparc::fixup_sparc_tls_gd_lo10: case Sparc::fixup_sparc_tls_gd_add: @@ -175,7 +184,7 @@ namespace { } } - bool mayNeedRelaxation(const MCInst &Inst) const { + bool mayNeedRelaxation(const MCInst &Inst) const override { // FIXME. return false; } @@ -185,20 +194,25 @@ namespace { bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, - const MCAsmLayout &Layout) const { + const MCAsmLayout &Layout) const override { // FIXME. - assert(0 && "fixupNeedsRelaxation() unimplemented"); + llvm_unreachable("fixupNeedsRelaxation() unimplemented"); return false; } - void relaxInstruction(const MCInst &Inst, MCInst &Res) const { + void relaxInstruction(const MCInst &Inst, MCInst &Res) const override { // FIXME. - assert(0 && "relaxInstruction() unimplemented"); + llvm_unreachable("relaxInstruction() unimplemented"); } - bool writeNopData(uint64_t Count, MCObjectWriter *OW) const { - // FIXME: Zero fill for now. - for (uint64_t i = 0; i != Count; ++i) - OW->Write8(0); + bool writeNopData(uint64_t Count, MCObjectWriter *OW) 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); + return true; } @@ -215,7 +229,7 @@ namespace { SparcAsmBackend(T), OSType(OSType) { } void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, - uint64_t Value) const { + uint64_t Value, bool IsPCRel) const override { Value = adjustFixupValue(Fixup.getKind(), Value); if (!Value) return; // Doesn't change encoding. @@ -230,14 +244,10 @@ namespace { } - MCObjectWriter *createObjectWriter(raw_ostream &OS) const { + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType); return createSparcELFObjectWriter(OS, is64Bit(), OSABI); } - - virtual bool doesSectionRequireSymbols(const MCSection &Section) const { - return false; - } }; } // end anonymous namespace diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp index 3a9929bc4c03..5ba82f137b8b 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp @@ -28,24 +28,14 @@ namespace { virtual ~SparcELFObjectWriter() {} protected: - virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, - bool IsPCRel, bool IsRelocWithSymbol, - int64_t Addend) const; - - virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, - const MCValue &Target, - const MCFragment &F, - const MCFixup &Fixup, - bool IsPCRel) const; + unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, + bool IsPCRel) const override; }; } - unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target, const MCFixup &Fixup, - bool IsPCRel, - bool IsRelocWithSymbol, - int64_t Addend) const { + bool IsPCRel) const { if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Fixup.getValue())) { if (SExpr->getKind() == SparcMCExpr::VK_Sparc_R_DISP32) @@ -114,23 +104,6 @@ unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target, return ELF::R_SPARC_NONE; } -const MCSymbol *SparcELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, - const MCValue &Target, - const MCFragment &F, - const MCFixup &Fixup, - bool IsPCRel) const { - - if (!Target.getSymA()) - return NULL; - switch((unsigned)Fixup.getKind()) { - default: break; - case Sparc::fixup_sparc_got22: - case Sparc::fixup_sparc_got10: - return &Target.getSymA()->getSymbol().AliasedSymbol(); - } - return NULL; -} - MCObjectWriter *llvm::createSparcELFObjectWriter(raw_ostream &OS, bool Is64Bit, uint8_t OSABI) { diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h index 005a0242dc90..d42bcee6b3c0 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h @@ -26,6 +26,10 @@ namespace llvm { /// branches on icc/xcc fixup_sparc_br19, + /// fixup_sparc_bpr - 16-bit fixup for bpr + fixup_sparc_br16_2, + fixup_sparc_br16_14, + /// fixup_sparc_hi22 - 22-bit fixup corresponding to %hi(foo) /// for sethi fixup_sparc_hi22, diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp index 8d0dfeccf8cf..df66ca9006b8 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp @@ -32,7 +32,7 @@ SparcELFMCAsmInfo::SparcELFMCAsmInfo(StringRef TT) { Data16bitsDirective = "\t.half\t"; Data32bitsDirective = "\t.word\t"; // .xword is only supported by V9. - Data64bitsDirective = (isV9) ? "\t.xword\t" : 0; + Data64bitsDirective = (isV9) ? "\t.xword\t" : nullptr; ZeroDirective = "\t.skip\t"; CommentString = "!"; HasLEB128 = true; @@ -43,7 +43,9 @@ SparcELFMCAsmInfo::SparcELFMCAsmInfo(StringRef TT) { SunStyleELFSectionSwitchSyntax = true; UsesELFSectionDirectiveForBSS = true; - PrivateGlobalPrefix = ".L"; + if (TheTriple.getOS() == llvm::Triple::Solaris || + TheTriple.getOS() == llvm::Triple::OpenBSD) + UseIntegratedAssembler = true; } const MCExpr* diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h index d53d09deee47..e126b687afdb 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h @@ -20,15 +20,15 @@ namespace llvm { class StringRef; class SparcELFMCAsmInfo : public MCAsmInfoELF { - virtual void anchor(); + void anchor() override; public: explicit SparcELFMCAsmInfo(StringRef TT); - virtual const MCExpr* getExprForPersonalitySymbol(const MCSymbol *Sym, - unsigned Encoding, - MCStreamer &Streamer) const; - virtual const MCExpr* getExprForFDESymbol(const MCSymbol *Sym, - unsigned Encoding, - MCStreamer &Streamer) const; + const MCExpr* + getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding, + MCStreamer &Streamer) const override; + const MCExpr* getExprForFDESymbol(const MCSymbol *Sym, + unsigned Encoding, + MCStreamer &Streamer) const override; }; diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp index ed756d96d513..eea9626c17b0 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp @@ -11,21 +11,22 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "mccodeemitter" #include "SparcMCExpr.h" -#include "SparcMCTargetDesc.h" #include "MCTargetDesc/SparcFixupKinds.h" +#include "SparcMCTargetDesc.h" +#include "llvm/ADT/Statistic.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/ADT/Statistic.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +#define DEBUG_TYPE "mccodeemitter" + STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); namespace { @@ -40,22 +41,33 @@ public: ~SparcMCCodeEmitter() {} void EncodeInstruction(const MCInst &MI, raw_ostream &OS, - SmallVectorImpl<MCFixup> &Fixups) const; + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const override; // getBinaryCodeForInstr - TableGen'erated function for getting the // binary encoding for an instruction. uint64_t getBinaryCodeForInstr(const MCInst &MI, - SmallVectorImpl<MCFixup> &Fixups) const; + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; /// getMachineOpValue - Return binary encoding of operand. If the machine /// operand requires relocation, record the relocation and return zero. unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, - SmallVectorImpl<MCFixup> &Fixups) const; + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups) const; + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups) const; + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; }; } // end anonymous namespace @@ -69,8 +81,9 @@ MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII, void SparcMCCodeEmitter:: EncodeInstruction(const MCInst &MI, raw_ostream &OS, - SmallVectorImpl<MCFixup> &Fixups) const { - unsigned Bits = getBinaryCodeForInstr(MI, Fixups); + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI); // Output the constant in big endian byte order. for (unsigned i = 0; i != 4; ++i) { @@ -88,7 +101,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, } if (tlsOpNo != 0) { const MCOperand &MO = MI.getOperand(tlsOpNo); - uint64_t op = getMachineOpValue(MI, MO, Fixups); + uint64_t op = getMachineOpValue(MI, MO, Fixups, STI); assert(op == 0 && "Unexpected operand value!"); (void)op; // suppress warning. } @@ -99,7 +112,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, unsigned SparcMCCodeEmitter:: getMachineOpValue(const MCInst &MI, const MCOperand &MO, - SmallVectorImpl<MCFixup> &Fixups) const { + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { if (MO.isReg()) return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); @@ -119,16 +133,17 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO, if (Expr->EvaluateAsAbsolute(Res)) return Res; - assert(0 && "Unhandled expression!"); + llvm_unreachable("Unhandled expression!"); return 0; } unsigned SparcMCCodeEmitter:: getCallTargetOpValue(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups) const { + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { const MCOperand &MO = MI.getOperand(OpNo); if (MO.isReg() || MO.isImm()) - return getMachineOpValue(MI, MO, Fixups); + return getMachineOpValue(MI, MO, Fixups, STI); if (MI.getOpcode() == SP::TLS_CALL) { // No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in @@ -159,18 +174,45 @@ getCallTargetOpValue(const MCInst &MI, unsigned OpNo, unsigned SparcMCCodeEmitter:: getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups) const { + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { const MCOperand &MO = MI.getOperand(OpNo); if (MO.isReg() || MO.isImm()) - return getMachineOpValue(MI, MO, Fixups); + return getMachineOpValue(MI, MO, Fixups, STI); - Sparc::Fixups fixup = Sparc::fixup_sparc_br22; - if (MI.getOpcode() == SP::BPXCC) - fixup = Sparc::fixup_sparc_br19; + Fixups.push_back(MCFixup::Create(0, MO.getExpr(), + (MCFixupKind)Sparc::fixup_sparc_br22)); + return 0; +} +unsigned SparcMCCodeEmitter:: +getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isReg() || MO.isImm()) + return getMachineOpValue(MI, MO, Fixups, STI); + + Fixups.push_back(MCFixup::Create(0, MO.getExpr(), + (MCFixupKind)Sparc::fixup_sparc_br19)); + return 0; +} +unsigned SparcMCCodeEmitter:: +getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isReg() || MO.isImm()) + return getMachineOpValue(MI, MO, Fixups, STI); + + Fixups.push_back(MCFixup::Create(0, MO.getExpr(), + (MCFixupKind)Sparc::fixup_sparc_br16_2)); Fixups.push_back(MCFixup::Create(0, MO.getExpr(), - (MCFixupKind)fixup)); + (MCFixupKind)Sparc::fixup_sparc_br16_14)); + return 0; } + + #include "SparcGenMCCodeEmitter.inc" diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp index 0337c09f5692..7f01ab06879f 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp @@ -12,17 +12,19 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sparcmcexpr" #include "SparcMCExpr.h" -#include "llvm/MC/MCContext.h" #include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCELF.h" +#include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Object/ELF.h" using namespace llvm; +#define DEBUG_TYPE "sparcmcexpr" + const SparcMCExpr* SparcMCExpr::Create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx) { @@ -123,7 +125,7 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name) Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::VariantKind Kind) { switch (Kind) { - default: assert(0 && "Unhandled SparcMCExpr::VariantKind"); + default: llvm_unreachable("Unhandled SparcMCExpr::VariantKind"); case VK_Sparc_LO: return Sparc::fixup_sparc_lo10; case VK_Sparc_HI: return Sparc::fixup_sparc_hi22; case VK_Sparc_H44: return Sparc::fixup_sparc_h44; @@ -160,9 +162,7 @@ Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::VariantKind Kind) { bool SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout) const { - if (!Layout) - return false; - return getSubExpr()->EvaluateAsRelocatable(Res, *Layout); + return getSubExpr()->EvaluateAsRelocatable(Res, Layout); } static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { @@ -220,35 +220,6 @@ void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm); } -// FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps -// that method should be made public? -// FIXME: really do above: now that at least three other backends are using it. -static void AddValueSymbolsImpl(const MCExpr *Value, MCAssembler *Asm) { - switch (Value->getKind()) { - case MCExpr::Target: - llvm_unreachable("Can't handle nested target expr!"); - break; - - case MCExpr::Constant: - break; - - case MCExpr::Binary: { - const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); - AddValueSymbolsImpl(BE->getLHS(), Asm); - AddValueSymbolsImpl(BE->getRHS(), Asm); - break; - } - - case MCExpr::SymbolRef: - Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); - break; - - case MCExpr::Unary: - AddValueSymbolsImpl(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm); - break; - } -} - -void SparcMCExpr::AddValueSymbols(MCAssembler *Asm) const { - AddValueSymbolsImpl(getSubExpr(), Asm); +void SparcMCExpr::visitUsedExpr(MCStreamer &Streamer) const { + Streamer.visitUsedExpr(*getSubExpr()); } diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h index be6526e8ade8..f0d0ef363ad8 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h @@ -85,15 +85,15 @@ public: Sparc::Fixups getFixupKind() const { return getFixupKind(Kind); } /// @} - void PrintImpl(raw_ostream &OS) const; + void PrintImpl(raw_ostream &OS) const override; bool EvaluateAsRelocatableImpl(MCValue &Res, - const MCAsmLayout *Layout) const; - void AddValueSymbols(MCAssembler *) const; - const MCSection *FindAssociatedSection() const { + const MCAsmLayout *Layout) const override; + void visitUsedExpr(MCStreamer &Streamer) const override; + const MCSection *FindAssociatedSection() const override { return getSubExpr()->FindAssociatedSection(); } - void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const; + void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override; static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Target; diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp index 2832a71ab709..571017dbf679 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp @@ -12,9 +12,9 @@ //===----------------------------------------------------------------------===// #include "SparcMCTargetDesc.h" +#include "InstPrinter/SparcInstPrinter.h" #include "SparcMCAsmInfo.h" #include "SparcTargetStreamer.h" -#include "InstPrinter/SparcInstPrinter.h" #include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" @@ -22,6 +22,8 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" +using namespace llvm; + #define GET_INSTRINFO_MC_DESC #include "SparcGenInstrInfo.inc" @@ -31,14 +33,11 @@ #define GET_REGINFO_MC_DESC #include "SparcGenRegisterInfo.inc" -using namespace llvm; - - static MCAsmInfo *createSparcMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { MCAsmInfo *MAI = new SparcELFMCAsmInfo(TT); unsigned Reg = MRI.getDwarfRegNum(SP::O6, true); - MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 0); + MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 0); MAI->addInitialFrameState(Inst); return MAI; } @@ -47,7 +46,7 @@ static MCAsmInfo *createSparcV9MCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { MCAsmInfo *MAI = new SparcELFMCAsmInfo(TT); unsigned Reg = MRI.getDwarfRegNum(SP::O6, true); - MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 2047); + MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 2047); MAI->addInitialFrameState(Inst); return MAI; } @@ -67,6 +66,9 @@ static MCRegisterInfo *createSparcMCRegisterInfo(StringRef TT) { static MCSubtargetInfo *createSparcMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) { MCSubtargetInfo *X = new MCSubtargetInfo(); + Triple TheTriple(TT); + if (CPU.empty()) + CPU = (TheTriple.getArch() == Triple::sparcv9) ? "v9" : "v8"; InitSparcMCSubtargetInfo(X, TT, CPU, FS); return X; } @@ -123,21 +125,24 @@ static MCCodeGenInfo *createSparcV9MCCodeGenInfo(StringRef TT, Reloc::Model RM, static MCStreamer *createMCStreamer(const Target &T, StringRef TT, MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool NoExecStack) { - SparcTargetELFStreamer *S = new SparcTargetELFStreamer(); - return createELFStreamer(Context, S, MAB, OS, Emitter, RelaxAll, NoExecStack); + const MCSubtargetInfo &STI, bool RelaxAll, + bool NoExecStack) { + MCStreamer *S = + createELFStreamer(Context, MAB, OS, Emitter, RelaxAll, NoExecStack); + new SparcTargetELFStreamer(*S); + return S; } static MCStreamer * createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, - bool isVerboseAsm, bool useLoc, bool useCFI, - bool useDwarfDirectory, MCInstPrinter *InstPrint, - MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) { - SparcTargetAsmStreamer *S = new SparcTargetAsmStreamer(OS); - - return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI, - useDwarfDirectory, InstPrint, CE, TAB, - ShowInst); + bool isVerboseAsm, bool useDwarfDirectory, + MCInstPrinter *InstPrint, MCCodeEmitter *CE, + MCAsmBackend *TAB, bool ShowInst) { + + MCStreamer *S = llvm::createAsmStreamer( + Ctx, OS, isVerboseAsm, useDwarfDirectory, InstPrint, CE, TAB, ShowInst); + new SparcTargetAsmStreamer(*S, OS); + return S; } static MCInstPrinter *createSparcMCInstPrinter(const Target &T, @@ -146,7 +151,7 @@ static MCInstPrinter *createSparcMCInstPrinter(const Target &T, const MCInstrInfo &MII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI) { - return new SparcInstPrinter(MAI, MII, MRI); + return new SparcInstPrinter(MAI, MII, MRI, STI); } extern "C" void LLVMInitializeSparcTargetMC() { diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp index 01043aed5eee..94af791e0e75 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp @@ -18,10 +18,13 @@ using namespace llvm; // pin vtable to this file +SparcTargetStreamer::SparcTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} + void SparcTargetStreamer::anchor() {} -SparcTargetAsmStreamer::SparcTargetAsmStreamer(formatted_raw_ostream &OS) - : OS(OS) {} +SparcTargetAsmStreamer::SparcTargetAsmStreamer(MCStreamer &S, + formatted_raw_ostream &OS) + : SparcTargetStreamer(S), OS(OS) {} void SparcTargetAsmStreamer::emitSparcRegisterIgnore(unsigned reg) { OS << "\t.register " @@ -35,6 +38,9 @@ void SparcTargetAsmStreamer::emitSparcRegisterScratch(unsigned reg) { << ", #scratch\n"; } +SparcTargetELFStreamer::SparcTargetELFStreamer(MCStreamer &S) + : SparcTargetStreamer(S) {} + MCELFStreamer &SparcTargetELFStreamer::getStreamer() { - return static_cast<MCELFStreamer &>(*Streamer); + return static_cast<MCELFStreamer &>(Streamer); } diff --git a/contrib/llvm/lib/Target/Sparc/Sparc.h b/contrib/llvm/lib/Target/Sparc/Sparc.h index 8d46c60255e9..de20aaa5db5d 100644 --- a/contrib/llvm/lib/Target/Sparc/Sparc.h +++ b/contrib/llvm/lib/Target/Sparc/Sparc.h @@ -42,8 +42,8 @@ namespace llvm { // values must be kept in sync with the ones in the .td file. namespace SPCC { enum CondCodes { - //ICC_A = 8 , // Always - //ICC_N = 0 , // Never + ICC_A = 8 , // Always + ICC_N = 0 , // Never ICC_NE = 9 , // Not Equal ICC_E = 1 , // Equal ICC_G = 10 , // Greater @@ -59,8 +59,8 @@ namespace llvm { ICC_VC = 15 , // Overflow Clear ICC_VS = 7 , // Overflow Set - //FCC_A = 8+16, // Always - //FCC_N = 0+16, // Never + FCC_A = 8+16, // Always + FCC_N = 0+16, // Never FCC_U = 7+16, // Unordered FCC_G = 6+16, // Greater FCC_UG = 5+16, // Unordered or Greater @@ -80,6 +80,8 @@ namespace llvm { inline static const char *SPARCCondCodeToString(SPCC::CondCodes CC) { switch (CC) { + case SPCC::ICC_A: return "a"; + case SPCC::ICC_N: return "n"; case SPCC::ICC_NE: return "ne"; case SPCC::ICC_E: return "e"; case SPCC::ICC_G: return "g"; @@ -94,6 +96,8 @@ namespace llvm { case SPCC::ICC_NEG: return "neg"; case SPCC::ICC_VC: return "vc"; case SPCC::ICC_VS: return "vs"; + case SPCC::FCC_A: return "a"; + case SPCC::FCC_N: return "n"; case SPCC::FCC_U: return "u"; case SPCC::FCC_G: return "g"; case SPCC::FCC_UG: return "ug"; diff --git a/contrib/llvm/lib/Target/Sparc/Sparc.td b/contrib/llvm/lib/Target/Sparc/Sparc.td index 05ff996a452e..3159a4651ac9 100644 --- a/contrib/llvm/lib/Target/Sparc/Sparc.td +++ b/contrib/llvm/lib/Target/Sparc/Sparc.td @@ -29,6 +29,12 @@ def FeatureV8Deprecated def FeatureVIS : SubtargetFeature<"vis", "IsVIS", "true", "Enable UltraSPARC Visual Instruction Set extensions">; +def FeatureVIS2 + : SubtargetFeature<"vis2", "IsVIS2", "true", + "Enable Visual Instruction Set extensions II">; +def FeatureVIS3 + : SubtargetFeature<"vis3", "IsVIS3", "true", + "Enable Visual Instruction Set extensions III">; def FeatureHardQuad : SubtargetFeature<"hard-quad-float", "HasHardQuad", "true", @@ -69,17 +75,18 @@ def : Proc<"sparclite86x", []>; def : Proc<"sparclet", []>; def : Proc<"tsc701", []>; def : Proc<"v9", [FeatureV9]>; -def : Proc<"ultrasparc", [FeatureV9, FeatureV8Deprecated]>; -def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated]>; -def : Proc<"niagara", [FeatureV9, FeatureV8Deprecated]>; -def : Proc<"niagara2", [FeatureV9, FeatureV8Deprecated, UsePopc]>; -def : Proc<"niagara3", [FeatureV9, FeatureV8Deprecated, UsePopc]>; -def : Proc<"niagara4", [FeatureV9, FeatureV8Deprecated, UsePopc]>; - -def SparcAsmWriter : AsmWriter { - string AsmWriterClassName = "InstPrinter"; - bit isMCAsmWriter = 1; -} +def : Proc<"ultrasparc", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>; +def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated, FeatureVIS, + FeatureVIS2]>; +def : Proc<"niagara", [FeatureV9, FeatureV8Deprecated, FeatureVIS, + FeatureVIS2]>; +def : Proc<"niagara2", [FeatureV9, FeatureV8Deprecated, UsePopc, + FeatureVIS, FeatureVIS2]>; +def : Proc<"niagara3", [FeatureV9, FeatureV8Deprecated, UsePopc, + FeatureVIS, FeatureVIS2]>; +def : Proc<"niagara4", [FeatureV9, FeatureV8Deprecated, UsePopc, + FeatureVIS, FeatureVIS2, FeatureVIS3]>; + //===----------------------------------------------------------------------===// // Declare the target which we are implementing @@ -89,6 +96,4 @@ def Sparc : Target { // Pull in Instruction Info: let InstructionSet = SparcInstrInfo; let AssemblyParsers = [SparcAsmParser]; - - let AssemblyWriters = [SparcAsmWriter]; } diff --git a/contrib/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp b/contrib/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp index b2c536d43961..1b7330e8c5b4 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp @@ -12,19 +12,19 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "asm-printer" #include "Sparc.h" +#include "InstPrinter/SparcInstPrinter.h" +#include "MCTargetDesc/SparcMCExpr.h" #include "SparcInstrInfo.h" #include "SparcTargetMachine.h" #include "SparcTargetStreamer.h" -#include "InstPrinter/SparcInstPrinter.h" -#include "MCTargetDesc/SparcMCExpr.h" #include "llvm/ADT/SmallString.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" +#include "llvm/IR/Mangler.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInst.h" @@ -32,30 +32,32 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/Mangler.h" using namespace llvm; +#define DEBUG_TYPE "asm-printer" + namespace { class SparcAsmPrinter : public AsmPrinter { SparcTargetStreamer &getTargetStreamer() { - return static_cast<SparcTargetStreamer&>(OutStreamer.getTargetStreamer()); + return static_cast<SparcTargetStreamer &>( + *OutStreamer.getTargetStreamer()); } public: explicit SparcAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) : AsmPrinter(TM, Streamer) {} - virtual const char *getPassName() const { + const char *getPassName() const override { return "Sparc Assembly Printer"; } void printOperand(const MachineInstr *MI, int opNum, raw_ostream &OS); void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &OS, - const char *Modifier = 0); + const char *Modifier = nullptr); void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &OS); - virtual void EmitFunctionBodyStart(); - virtual void EmitInstruction(const MachineInstr *MI); - virtual void EmitEndOfAsmFile(Module &M); + void EmitFunctionBodyStart() override; + void EmitInstruction(const MachineInstr *MI) override; + void EmitEndOfAsmFile(Module &M) override; static const char *getRegisterName(unsigned RegNo) { return SparcInstPrinter::getRegisterName(RegNo); @@ -63,12 +65,13 @@ namespace { bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, - raw_ostream &O); + raw_ostream &O) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, - raw_ostream &O); + raw_ostream &O) override; - void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI); + void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI, + const MCSubtargetInfo &STI); }; } // end of anonymous namespace @@ -105,48 +108,54 @@ static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind, } static void EmitCall(MCStreamer &OutStreamer, - MCOperand &Callee) + MCOperand &Callee, + const MCSubtargetInfo &STI) { MCInst CallInst; CallInst.setOpcode(SP::CALL); CallInst.addOperand(Callee); - OutStreamer.EmitInstruction(CallInst); + OutStreamer.EmitInstruction(CallInst, STI); } static void EmitSETHI(MCStreamer &OutStreamer, - MCOperand &Imm, MCOperand &RD) + MCOperand &Imm, MCOperand &RD, + const MCSubtargetInfo &STI) { MCInst SETHIInst; SETHIInst.setOpcode(SP::SETHIi); SETHIInst.addOperand(RD); SETHIInst.addOperand(Imm); - OutStreamer.EmitInstruction(SETHIInst); + OutStreamer.EmitInstruction(SETHIInst, STI); } static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode, - MCOperand &RS1, MCOperand &Src2, MCOperand &RD) + MCOperand &RS1, MCOperand &Src2, MCOperand &RD, + const MCSubtargetInfo &STI) { MCInst Inst; Inst.setOpcode(Opcode); Inst.addOperand(RD); Inst.addOperand(RS1); Inst.addOperand(Src2); - OutStreamer.EmitInstruction(Inst); + OutStreamer.EmitInstruction(Inst, STI); } static void EmitOR(MCStreamer &OutStreamer, - MCOperand &RS1, MCOperand &Imm, MCOperand &RD) { - EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD); + MCOperand &RS1, MCOperand &Imm, MCOperand &RD, + const MCSubtargetInfo &STI) { + EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD, STI); } static void EmitADD(MCStreamer &OutStreamer, - MCOperand &RS1, MCOperand &RS2, MCOperand &RD) { - EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD); + MCOperand &RS1, MCOperand &RS2, MCOperand &RD, + const MCSubtargetInfo &STI) { + EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD, STI); } static void EmitSHL(MCStreamer &OutStreamer, - MCOperand &RS1, MCOperand &Imm, MCOperand &RD) { - EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD); + MCOperand &RS1, MCOperand &Imm, MCOperand &RD, + const MCSubtargetInfo &STI) { + EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD, STI); } @@ -154,15 +163,17 @@ static void EmitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym, SparcMCExpr::VariantKind HiKind, SparcMCExpr::VariantKind LoKind, MCOperand &RD, - MCContext &OutContext) { + MCContext &OutContext, + const MCSubtargetInfo &STI) { MCOperand hi = createSparcMCOperand(HiKind, GOTSym, OutContext); MCOperand lo = createSparcMCOperand(LoKind, GOTSym, OutContext); - EmitSETHI(OutStreamer, hi, RD); - EmitOR(OutStreamer, RD, lo, RD); + EmitSETHI(OutStreamer, hi, RD, STI); + EmitOR(OutStreamer, RD, lo, RD, STI); } -void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI) +void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI, + const MCSubtargetInfo &STI) { MCSymbol *GOTLabel = OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_")); @@ -182,33 +193,33 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI) case CodeModel::Small: EmitHiLo(OutStreamer, GOTLabel, SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO, - MCRegOP, OutContext); + MCRegOP, OutContext, STI); break; case CodeModel::Medium: { EmitHiLo(OutStreamer, GOTLabel, SparcMCExpr::VK_Sparc_H44, SparcMCExpr::VK_Sparc_M44, - MCRegOP, OutContext); + MCRegOP, OutContext, STI); MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(12, OutContext)); - EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP); + EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP, STI); MCOperand lo = createSparcMCOperand(SparcMCExpr::VK_Sparc_L44, GOTLabel, OutContext); - EmitOR(OutStreamer, MCRegOP, lo, MCRegOP); + EmitOR(OutStreamer, MCRegOP, lo, MCRegOP, STI); break; } case CodeModel::Large: { EmitHiLo(OutStreamer, GOTLabel, SparcMCExpr::VK_Sparc_HH, SparcMCExpr::VK_Sparc_HM, - MCRegOP, OutContext); + MCRegOP, OutContext, STI); MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(32, OutContext)); - EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP); + EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP, STI); // Use register %o7 to load the lower 32 bits. MCOperand RegO7 = MCOperand::CreateReg(SP::O7); EmitHiLo(OutStreamer, GOTLabel, SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO, - RegO7, OutContext); - EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP); + RegO7, OutContext, STI); + EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP, STI); } } return; @@ -230,18 +241,18 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI) OutStreamer.EmitLabel(StartLabel); MCOperand Callee = createPCXCallOP(EndLabel, OutContext); - EmitCall(OutStreamer, Callee); + EmitCall(OutStreamer, Callee, STI); OutStreamer.EmitLabel(SethiLabel); MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC22, GOTLabel, StartLabel, SethiLabel, OutContext); - EmitSETHI(OutStreamer, hiImm, MCRegOP); + EmitSETHI(OutStreamer, hiImm, MCRegOP, STI); OutStreamer.EmitLabel(EndLabel); MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC10, GOTLabel, StartLabel, EndLabel, OutContext); - EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP); - EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP); + EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP, STI); + EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP, STI); } void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI) @@ -253,7 +264,7 @@ void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI) // FIXME: Debug Value. return; case SP::GETPCX: - LowerGETPCXAndEmitMCInsts(MI); + LowerGETPCXAndEmitMCInsts(MI, getSubtargetInfo()); return; } MachineBasicBlock::const_instr_iterator I = MI; @@ -261,7 +272,7 @@ void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI) do { MCInst TmpInst; LowerSparcMachineInstrToMCInst(I, TmpInst, *this); - OutStreamer.EmitInstruction(TmpInst); + EmitToStreamer(OutStreamer, TmpInst); } while ((++I != E) && I->isInsideBundle()); // Delay slot check. } @@ -285,6 +296,7 @@ void SparcAsmPrinter::EmitFunctionBodyStart() { void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum, raw_ostream &O) { + const DataLayout *DL = TM.getDataLayout(); const MachineOperand &MO = MI->getOperand (opNum); SparcMCExpr::VariantKind TF = (SparcMCExpr::VariantKind) MO.getTargetFlags(); @@ -361,7 +373,7 @@ void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum, O << MO.getSymbolName(); break; case MachineOperand::MO_ConstantPoolIndex: - O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" + O << DL->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" << MO.getIndex(); break; default: diff --git a/contrib/llvm/lib/Target/Sparc/SparcCodeEmitter.cpp b/contrib/llvm/lib/Target/Sparc/SparcCodeEmitter.cpp index b7b2182fc21b..247da2a95797 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcCodeEmitter.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcCodeEmitter.cpp @@ -12,7 +12,6 @@ // //===---------------------------------------------------------------------===// -#define DEBUG_TYPE "jit" #include "Sparc.h" #include "MCTargetDesc/SparcMCExpr.h" #include "SparcRelocations.h" @@ -25,6 +24,8 @@ using namespace llvm; +#define DEBUG_TYPE "jit" + STATISTIC(NumEmitted, "Number of machine instructions emitted"); namespace { @@ -39,7 +40,7 @@ class SparcCodeEmitter : public MachineFunctionPass { const std::vector<MachineConstantPoolEntry> *MCPEs; bool IsPIC; - void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<MachineModuleInfo> (); MachineFunctionPass::getAnalysisUsage(AU); } @@ -48,13 +49,13 @@ class SparcCodeEmitter : public MachineFunctionPass { public: SparcCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) - : MachineFunctionPass(ID), JTI(0), II(0), TD(0), - TM(tm), MCE(mce), MCPEs(0), + : MachineFunctionPass(ID), JTI(nullptr), II(nullptr), TD(nullptr), + TM(tm), MCE(mce), MCPEs(nullptr), IsPIC(TM.getRelocationModel() == Reloc::PIC_) {} - bool runOnMachineFunction(MachineFunction &MF); + bool runOnMachineFunction(MachineFunction &MF) override; - virtual const char *getPassName() const { + const char *getPassName() const override { return "Sparc Machine Code Emitter"; } @@ -76,6 +77,10 @@ private: unsigned) const; unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned) const; + unsigned getBranchPredTargetOpValue(const MachineInstr &MI, + unsigned) const; + unsigned getBranchOnRegTargetOpValue(const MachineInstr &MI, + unsigned) const; void emitWord(unsigned Word); @@ -141,7 +146,8 @@ void SparcCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI, } break; } - case TargetOpcode::PROLOG_LABEL: + case TargetOpcode::CFI_INSTRUCTION: + break; case TargetOpcode::EH_LABEL: { MCE.emitLabel(MI->getOperand(0).getMCSymbol()); break; @@ -198,6 +204,18 @@ unsigned SparcCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI, return getMachineOpValue(MI, MO); } +unsigned SparcCodeEmitter::getBranchPredTargetOpValue(const MachineInstr &MI, + unsigned opIdx) const { + const MachineOperand MO = MI.getOperand(opIdx); + return getMachineOpValue(MI, MO); +} + +unsigned SparcCodeEmitter::getBranchOnRegTargetOpValue(const MachineInstr &MI, + unsigned opIdx) const { + const MachineOperand MO = MI.getOperand(opIdx); + return getMachineOpValue(MI, MO); +} + unsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI, const MachineOperand &MO) const { diff --git a/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.cpp b/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.cpp index c75998a36e0d..3cdfda3e059a 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.cpp @@ -14,6 +14,7 @@ #include "SparcFrameLowering.h" #include "SparcInstrInfo.h" #include "SparcMachineFunctionInfo.h" +#include "SparcSubtarget.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -32,6 +33,9 @@ DisableLeafProc("disable-sparc-leaf-proc", cl::desc("Disable Sparc leaf procedure optimization."), cl::Hidden); +SparcFrameLowering::SparcFrameLowering(const SparcSubtarget &ST) + : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, + ST.is64Bit() ? 16 : 8, 0, ST.is64Bit() ? 16 : 8) {} void SparcFrameLowering::emitSPAdjustment(MachineFunction &MF, MachineBasicBlock &MBB, @@ -99,28 +103,33 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF) const { SAVEri = SP::ADDri; SAVErr = SP::ADDrr; } - NumBytes = - SubTarget.getAdjustedFrameSize(NumBytes); + NumBytes = + -MF.getTarget().getSubtarget<SparcSubtarget>().getAdjustedFrameSize( + NumBytes); emitSPAdjustment(MF, MBB, MBBI, NumBytes, SAVErr, SAVEri); MachineModuleInfo &MMI = MF.getMMI(); const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); - MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, TII.get(SP::PROLOG_LABEL)).addSym(FrameLabel); - unsigned regFP = MRI->getDwarfRegNum(SP::I6, true); // Emit ".cfi_def_cfa_register 30". - MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(FrameLabel, - regFP)); + unsigned CFIIndex = + MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, regFP)); + BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex); + // Emit ".cfi_window_save". - MMI.addFrameInst(MCCFIInstruction::createWindowSave(FrameLabel)); + CFIIndex = MMI.addFrameInst(MCCFIInstruction::createWindowSave(nullptr)); + BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex); unsigned regInRA = MRI->getDwarfRegNum(SP::I7, true); unsigned regOutRA = MRI->getDwarfRegNum(SP::O7, true); // Emit ".cfi_register 15, 31". - MMI.addFrameInst(MCCFIInstruction::createRegister(FrameLabel, - regOutRA, - regInRA)); + CFIIndex = MMI.addFrameInst( + MCCFIInstruction::createRegister(nullptr, regOutRA, regInRA)); + BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex); } void SparcFrameLowering:: @@ -159,7 +168,8 @@ void SparcFrameLowering::emitEpilogue(MachineFunction &MF, if (NumBytes == 0) return; - NumBytes = SubTarget.getAdjustedFrameSize(NumBytes); + NumBytes = MF.getTarget().getSubtarget<SparcSubtarget>().getAdjustedFrameSize( + NumBytes); emitSPAdjustment(MF, MBB, MBBI, NumBytes, SP::ADDrr, SP::ADDri); } diff --git a/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.h b/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.h index 072fde393833..a7d1b8902dcd 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.h +++ b/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.h @@ -15,33 +15,29 @@ #define SPARC_FRAMEINFO_H #include "Sparc.h" -#include "SparcSubtarget.h" #include "llvm/Target/TargetFrameLowering.h" namespace llvm { - class SparcSubtarget; +class SparcSubtarget; class SparcFrameLowering : public TargetFrameLowering { - const SparcSubtarget &SubTarget; public: - explicit SparcFrameLowering(const SparcSubtarget &ST) - : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, - ST.is64Bit() ? 16 : 8, 0, ST.is64Bit() ? 16 : 8), - SubTarget(ST) {} + explicit SparcFrameLowering(const SparcSubtarget &ST); /// emitProlog/emitEpilog - These methods insert prolog and epilog code into /// the function. - void emitPrologue(MachineFunction &MF) const; - void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; + void emitPrologue(MachineFunction &MF) const override; + void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; - void eliminateCallFramePseudoInstr(MachineFunction &MF, - MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const; + void + eliminateCallFramePseudoInstr(MachineFunction &MF, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const override; - bool hasReservedCallFrame(const MachineFunction &MF) const; - bool hasFP(const MachineFunction &MF) const; + bool hasReservedCallFrame(const MachineFunction &MF) const override; + bool hasFP(const MachineFunction &MF) const override; void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, - RegScavenger *RS = NULL) const; + RegScavenger *RS = nullptr) const override; private: // Remap input registers to output registers for leaf procedure. diff --git a/contrib/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/contrib/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp index b012bfdb0102..2fade27f2d5d 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -41,7 +41,7 @@ public: TM(tm) { } - SDNode *Select(SDNode *N); + SDNode *Select(SDNode *N) override; // Complex Pattern Selectors. bool SelectADDRrr(SDValue N, SDValue &R1, SDValue &R2); @@ -49,11 +49,11 @@ public: /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for /// inline asm expressions. - virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, - char ConstraintCode, - std::vector<SDValue> &OutOps); + bool SelectInlineAsmMemoryOperand(const SDValue &Op, + char ConstraintCode, + std::vector<SDValue> &OutOps) override; - virtual const char *getPassName() const { + const char *getPassName() const override { return "SPARC DAG->DAG Pattern Instruction Selection"; } @@ -143,7 +143,7 @@ SDNode *SparcDAGToDAGISel::Select(SDNode *N) { SDLoc dl(N); if (N->isMachineOpcode()) { N->setNodeId(-1); - return NULL; // Already selected. + return nullptr; // Already selected. } switch (N->getOpcode()) { diff --git a/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp index abe2de61527d..990f52a97275 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -53,7 +53,7 @@ static bool CC_Sparc_Assign_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State) { - static const uint16_t RegList[] = { + static const MCPhysReg RegList[] = { SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5 }; // Try to get first reg. @@ -235,8 +235,7 @@ SparcTargetLowering::LowerReturn_32(SDValue Chain, if (Flag.getNode()) RetOps.push_back(Flag); - return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, - &RetOps[0], RetOps.size()); + return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, RetOps); } // Lower return values for the 64-bit ABI. @@ -272,6 +271,7 @@ SparcTargetLowering::LowerReturn_64(SDValue Chain, // Integer return values must be sign or zero extended by the callee. switch (VA.getLocInfo()) { + case CCValAssign::Full: break; case CCValAssign::SExt: OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal); break; @@ -280,8 +280,9 @@ SparcTargetLowering::LowerReturn_64(SDValue Chain, break; case CCValAssign::AExt: OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal); - default: break; + default: + llvm_unreachable("Unknown loc info!"); } // The custom bit on an i32 return value indicates that it should be passed @@ -313,8 +314,7 @@ SparcTargetLowering::LowerReturn_64(SDValue Chain, if (Flag.getNode()) RetOps.push_back(Flag); - return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, - &RetOps[0], RetOps.size()); + return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, RetOps); } SDValue SparcTargetLowering:: @@ -355,10 +355,13 @@ LowerFormalArguments_32(SDValue Chain, const unsigned StackOffset = 92; - for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { + unsigned InIdx = 0; + for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i, ++InIdx) { CCValAssign &VA = ArgLocs[i]; - if (i == 0 && Ins[i].Flags.isSRet()) { + if (Ins[InIdx].Flags.isSRet()) { + if (InIdx != 0) + report_fatal_error("sparc only supports sret on the first parameter"); // Get SRet from [%fp+64]. int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, 64, true); SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); @@ -491,11 +494,11 @@ LowerFormalArguments_32(SDValue Chain, // Store remaining ArgRegs to the stack if this is a varargs function. if (isVarArg) { - static const uint16_t ArgRegs[] = { + static const MCPhysReg ArgRegs[] = { SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5 }; unsigned NumAllocated = CCInfo.getFirstUnallocated(ArgRegs, 6); - const uint16_t *CurArgReg = ArgRegs+NumAllocated, *ArgRegEnd = ArgRegs+6; + const MCPhysReg *CurArgReg = ArgRegs+NumAllocated, *ArgRegEnd = ArgRegs+6; unsigned ArgOffset = CCInfo.getNextStackOffset(); if (NumAllocated == 6) ArgOffset += StackOffset; @@ -526,8 +529,7 @@ LowerFormalArguments_32(SDValue Chain, if (!OutChains.empty()) { OutChains.push_back(Chain); - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &OutChains[0], OutChains.size()); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); } } @@ -642,8 +644,7 @@ LowerFormalArguments_64(SDValue Chain, } if (!OutChains.empty()) - Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, - &OutChains[0], OutChains.size()); + Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains); return Chain; } @@ -661,7 +662,7 @@ static bool hasReturnsTwiceAttr(SelectionDAG &DAG, SDValue Callee, if (CS) return CS->hasFnAttr(Attribute::ReturnsTwice); - const Function *CalleeFn = 0; + const Function *CalleeFn = nullptr; if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { CalleeFn = dyn_cast<Function>(G->getGlobal()); } else if (ExternalSymbolSDNode *E = @@ -875,8 +876,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI, // Emit all stores, make sure the occur before any copies into physregs. if (!MemOpChains.empty()) - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &MemOpChains[0], MemOpChains.size()); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains); // Build a sequence of copy-to-reg nodes chained together with token // chain and flag operands which copy the outgoing args into registers. @@ -925,7 +925,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI, if (InFlag.getNode()) Ops.push_back(InFlag); - Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); + Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, Ops); InFlag = Chain.getValue(1); Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true), @@ -959,9 +959,9 @@ static bool isFP128ABICall(const char *CalleeName) "_Q_sqrt", "_Q_neg", "_Q_itoq", "_Q_stoq", "_Q_dtoq", "_Q_utoq", "_Q_lltoq", "_Q_ulltoq", - 0 + nullptr }; - for (const char * const *I = ABICalls; *I != 0; ++I) + for (const char * const *I = ABICalls; *I != nullptr; ++I) if (strcmp(CalleeName, *I) == 0) return true; return false; @@ -970,7 +970,7 @@ static bool isFP128ABICall(const char *CalleeName) unsigned SparcTargetLowering::getSRetArgSize(SelectionDAG &DAG, SDValue Callee) const { - const Function *CalleeFn = 0; + const Function *CalleeFn = nullptr; if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { CalleeFn = dyn_cast<Function>(G->getGlobal()); } else if (ExternalSymbolSDNode *E = @@ -1192,8 +1192,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI, // Emit all stores, make sure they occur before the call. if (!MemOpChains.empty()) - Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, - &MemOpChains[0], MemOpChains.size()); + Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains); // Build a sequence of CopyToReg nodes glued together with token chain and // glue operands which copy the outgoing args into registers. The InGlue is @@ -1243,7 +1242,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI, // Now the call itself. SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); - Chain = DAG.getNode(SPISD::CALL, DL, NodeTys, &Ops[0], Ops.size()); + Chain = DAG.getNode(SPISD::CALL, DL, NodeTys, Ops); InGlue = Chain.getValue(1); // Revert the stack pointer immediately after the call. @@ -1261,7 +1260,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI, // Set inreg flag manually for codegen generated library calls that // return float. - if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && CLI.CS == 0) + if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && CLI.CS == nullptr) CLI.Ins[0].Flags.setInReg(); RVInfo.AnalyzeCallResult(CLI.Ins, RetCC_Sparc64); @@ -1675,7 +1674,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM) const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { - default: return 0; + default: return nullptr; case SPISD::CMPICC: return "SPISD::CMPICC"; case SPISD::CMPFCC: return "SPISD::CMPFCC"; case SPISD::BRICC: return "SPISD::BRICC"; @@ -1709,7 +1708,7 @@ EVT SparcTargetLowering::getSetCCResultType(LLVMContext &, EVT VT) const { /// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to /// be zero. Op is expected to be a target specific node. Used by DAG /// combiner. -void SparcTargetLowering::computeMaskedBitsForTargetNode +void SparcTargetLowering::computeKnownBitsForTargetNode (const SDValue Op, APInt &KnownZero, APInt &KnownOne, @@ -1723,10 +1722,8 @@ void SparcTargetLowering::computeMaskedBitsForTargetNode case SPISD::SELECT_ICC: case SPISD::SELECT_XCC: case SPISD::SELECT_FCC: - DAG.ComputeMaskedBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); - DAG.ComputeMaskedBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1); - assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); - assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); + DAG.computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); + DAG.computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1); // Only known if known in both the LHS and RHS. KnownOne &= KnownOne2; @@ -1912,7 +1909,7 @@ SDValue SparcTargetLowering::LowerGlobalTLSAddress(SDValue Op, assert(Mask && "Missing call preserved mask for calling convention"); Ops.push_back(DAG.getRegisterMask(Mask)); Ops.push_back(InFlag); - Chain = DAG.getNode(SPISD::TLS_CALL, DL, NodeTys, &Ops[0], Ops.size()); + Chain = DAG.getNode(SPISD::TLS_CALL, DL, NodeTys, Ops); InFlag = Chain.getValue(1); Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(1, true), DAG.getIntPtrConstant(0, true), InFlag, DL); @@ -2031,13 +2028,10 @@ SparcTargetLowering::LowerF128Op(SDValue Op, SelectionDAG &DAG, for (unsigned i = 0, e = numArgs; i != e; ++i) { Chain = LowerF128_LibCallArg(Chain, Args, Op.getOperand(i), SDLoc(Op), DAG); } - TargetLowering:: - CallLoweringInfo CLI(Chain, - RetTyABI, - false, false, false, false, - 0, CallingConv::C, - false, false, true, - Callee, Args, DAG, SDLoc(Op)); + TargetLowering::CallLoweringInfo CLI(DAG); + CLI.setDebugLoc(SDLoc(Op)).setChain(Chain) + .setCallee(CallingConv::C, RetTyABI, Callee, std::move(Args), 0); + std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI); // chain is in second result. @@ -2063,7 +2057,7 @@ SparcTargetLowering::LowerF128Compare(SDValue LHS, SDValue RHS, SDLoc DL, SelectionDAG &DAG) const { - const char *LibCall = 0; + const char *LibCall = nullptr; bool is64Bit = Subtarget->is64Bit(); switch(SPCC) { default: llvm_unreachable("Unhandled conditional code!"); @@ -2090,13 +2084,9 @@ SparcTargetLowering::LowerF128Compare(SDValue LHS, SDValue RHS, Chain = LowerF128_LibCallArg(Chain, Args, LHS, DL, DAG); Chain = LowerF128_LibCallArg(Chain, Args, RHS, DL, DAG); - TargetLowering:: - CallLoweringInfo CLI(Chain, - RetTy, - false, false, false, false, - 0, CallingConv::C, - false, false, true, - Callee, Args, DAG, DL); + TargetLowering::CallLoweringInfo CLI(DAG); + CLI.setDebugLoc(DL).setChain(Chain) + .setCallee(CallingConv::C, RetTy, Callee, std::move(Args), 0); std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI); @@ -2172,7 +2162,7 @@ LowerF128_FPEXTEND(SDValue Op, SelectionDAG &DAG, TLI.getLibcallName(RTLIB::FPEXT_F32_F128), 1); llvm_unreachable("fpextend with non-float operand!"); - return SDValue(0, 0); + return SDValue(); } static SDValue @@ -2190,7 +2180,7 @@ LowerF128_FPROUND(SDValue Op, SelectionDAG &DAG, TLI.getLibcallName(RTLIB::FPROUND_F128_F32), 1); llvm_unreachable("fpround to non-float!"); - return SDValue(0, 0); + return SDValue(); } static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG, @@ -2211,7 +2201,7 @@ static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG, // Expand if the resulting type is illegal. if (!TLI.isTypeLegal(VT)) - return SDValue(0, 0); + return SDValue(); // Otherwise, Convert the fp value to integer in an FP register. if (VT == MVT::i32) @@ -2242,7 +2232,7 @@ static SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG, // Expand if the operand type is illegal. if (!TLI.isTypeLegal(OpVT)) - return SDValue(0, 0); + return SDValue(); // Otherwise, Convert the int value to FP in an FP register. SDValue Tmp = DAG.getNode(ISD::BITCAST, dl, floatVT, Op.getOperand(0)); @@ -2260,7 +2250,7 @@ static SDValue LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG, // quad floating point instructions and the resulting type is legal. if (Op.getOperand(0).getValueType() != MVT::f128 || (hasHardQuad && TLI.isTypeLegal(VT))) - return SDValue(0, 0); + return SDValue(); assert(VT == MVT::i32 || VT == MVT::i64); @@ -2281,7 +2271,7 @@ static SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG, // Expand if it does not involve f128 or the target has support for // quad floating point instructions and the operand type is legal. if (Op.getValueType() != MVT::f128 || (hasHardQuad && TLI.isTypeLegal(OpVT))) - return SDValue(0, 0); + return SDValue(); return TLI.LowerF128Op(Op, DAG, TLI.getLibcallName(OpVT == MVT::i32 @@ -2426,7 +2416,7 @@ static SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG, SDValue NewVal = DAG.getNode(ISD::ADD, dl, VT, NewSP, DAG.getConstant(regSpillArea, VT)); SDValue Ops[2] = { NewVal, Chain }; - return DAG.getMergeValues(Ops, 2, dl); + return DAG.getMergeValues(Ops, dl); } @@ -2492,6 +2482,9 @@ static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG, MachineFrameInfo *MFI = MF.getFrameInfo(); MFI->setReturnAddressIsTaken(true); + if (TLI.verifyReturnAddressArgumentIsConstant(Op, DAG)) + return SDValue(); + EVT VT = Op.getValueType(); SDLoc dl(Op); uint64_t depth = Op.getConstantOperandVal(0); @@ -2592,10 +2585,9 @@ static SDValue LowerF128Load(SDValue Op, SelectionDAG &DAG) SubRegOdd); SDValue OutChains[2] = { SDValue(Hi64.getNode(), 1), SDValue(Lo64.getNode(), 1) }; - SDValue OutChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &OutChains[0], 2); + SDValue OutChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); SDValue Ops[2] = {SDValue(InFP128,0), OutChain}; - return DAG.getMergeValues(Ops, 2, dl); + return DAG.getMergeValues(Ops, dl); } // Lower a f128 store into two f64 stores. @@ -2639,12 +2631,12 @@ static SDValue LowerF128Store(SDValue Op, SelectionDAG &DAG) { LoPtr, MachinePointerInfo(), false, false, alignment); - return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &OutChains[0], 2); + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); } static SDValue LowerFNEGorFABS(SDValue Op, SelectionDAG &DAG, bool isV9) { - assert((Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS) && "invalid"); + assert((Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS) + && "invalid opcode"); if (Op.getValueType() == MVT::f64) return LowerF64Op(Op, DAG, Op.getOpcode()); @@ -2720,7 +2712,7 @@ static SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op, SelectionDAG &DAG) { SDValue Dst = DAG.getNode(ISD::OR, dl, MVT::i64, Hi, Lo); SDValue Ops[2] = { Dst, Carry }; - return DAG.getMergeValues(Ops, 2, dl); + return DAG.getMergeValues(Ops, dl); } // Custom lower UMULO/SMULO for SPARC. This code is similar to ExpandNode() @@ -2767,7 +2759,7 @@ static SDValue LowerUMULO_SMULO(SDValue Op, SelectionDAG &DAG, DAG.DeleteNode(MulResult.getNode()); SDValue Ops[2] = { BottomHalf, TopHalf } ; - return DAG.getMergeValues(Ops, 2, dl); + return DAG.getMergeValues(Ops, dl); } static SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG) { @@ -2934,7 +2926,7 @@ SparcTargetLowering::expandSelectCC(MachineInstr *MI, // Transfer the remainder of BB and its successor edges to sinkMBB. sinkMBB->splice(sinkMBB->begin(), BB, - llvm::next(MachineBasicBlock::iterator(MI)), + std::next(MachineBasicBlock::iterator(MI)), BB->end()); sinkMBB->transferSuccessorsAndUpdatePHIs(BB); @@ -3086,7 +3078,7 @@ getSingleConstraintMatchWeight(AsmOperandInfo &info, Value *CallOperandVal = info.CallOperandVal; // If we don't have a value, we can't do a match, // but allow it at the lowest weight. - if (CallOperandVal == NULL) + if (!CallOperandVal) return CW_Default; // Look at the constraint type. @@ -3111,7 +3103,7 @@ LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector<SDValue> &Ops, SelectionDAG &DAG) const { - SDValue Result(0, 0); + SDValue Result(nullptr, 0); // Only support length 1 constraints for now. if (Constraint.length() > 1) diff --git a/contrib/llvm/lib/Target/Sparc/SparcISelLowering.h b/contrib/llvm/lib/Target/Sparc/SparcISelLowering.h index f7b45d0677f7..a24cc82eecb4 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcISelLowering.h +++ b/contrib/llvm/lib/Target/Sparc/SparcISelLowering.h @@ -55,47 +55,47 @@ namespace llvm { const SparcSubtarget *Subtarget; public: SparcTargetLowering(TargetMachine &TM); - virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; - /// computeMaskedBitsForTargetNode - Determine which of the bits specified + /// computeKnownBitsForTargetNode - Determine which of the bits specified /// in Mask are known to be either zero or one and return them in the /// KnownZero/KnownOne bitsets. - virtual void computeMaskedBitsForTargetNode(const SDValue Op, - APInt &KnownZero, - APInt &KnownOne, - const SelectionDAG &DAG, - unsigned Depth = 0) const; + void computeKnownBitsForTargetNode(const SDValue Op, + APInt &KnownZero, + APInt &KnownOne, + const SelectionDAG &DAG, + unsigned Depth = 0) const override; - virtual MachineBasicBlock * + MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *MBB) const; + MachineBasicBlock *MBB) const override; - virtual const char *getTargetNodeName(unsigned Opcode) const; + const char *getTargetNodeName(unsigned Opcode) const override; - ConstraintType getConstraintType(const std::string &Constraint) const; + ConstraintType getConstraintType(const std::string &Constraint) const override; ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, - const char *constraint) const; + const char *constraint) const override; void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector<SDValue> &Ops, - SelectionDAG &DAG) const; + SelectionDAG &DAG) const override; std::pair<unsigned, const TargetRegisterClass*> - getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const; + getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const override; - virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; - virtual MVT getScalarShiftAmountTy(EVT LHSTy) const { return MVT::i32; } + bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; + MVT getScalarShiftAmountTy(EVT LHSTy) const override { return MVT::i32; } /// getSetCCResultType - Return the ISD::SETCC ValueType - virtual EVT getSetCCResultType(LLVMContext &Context, EVT VT) const; + EVT getSetCCResultType(LLVMContext &Context, EVT VT) const override; - virtual SDValue + SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) const; + SmallVectorImpl<SDValue> &InVals) const override; SDValue LowerFormalArguments_32(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, @@ -109,20 +109,20 @@ namespace llvm { SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; - virtual SDValue + SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, - SmallVectorImpl<SDValue> &InVals) const; + SmallVectorImpl<SDValue> &InVals) const override; SDValue LowerCall_32(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const; SDValue LowerCall_64(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const; - virtual SDValue + SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, - SDLoc dl, SelectionDAG &DAG) const; + SDLoc dl, SelectionDAG &DAG) const override; SDValue LowerReturn_32(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, @@ -156,15 +156,15 @@ namespace llvm { SDLoc DL, SelectionDAG &DAG) const; - bool ShouldShrinkFPConstant(EVT VT) const { + bool ShouldShrinkFPConstant(EVT VT) const override { // Do not shrink FP constpool if VT == MVT::f128. // (ldd, call _Q_fdtoq) is more expensive than two ldds. return VT != MVT::f128; } - virtual void ReplaceNodeResults(SDNode *N, + void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>& Results, - SelectionDAG &DAG) const; + SelectionDAG &DAG) const override; MachineBasicBlock *expandSelectCC(MachineInstr *MI, MachineBasicBlock *BB, unsigned BROpcode) const; diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td b/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td index a5b48f903407..54d824064fba 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td +++ b/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td @@ -235,7 +235,8 @@ def UDIVXri : F3_2<2, 0b001101, let Predicates = [Is64Bit] in { // 64-bit loads. -defm LDX : Load<"ldx", 0b001011, load, I64Regs, i64>; +let DecoderMethod = "DecodeLoadInt" in + defm LDX : Load<"ldx", 0b001011, load, I64Regs, i64>; let mayLoad = 1, isCodeGenOnly = 1, isAsmParserOnly = 1 in def TLS_LDXrr : F3_1<3, 0b001011, @@ -270,10 +271,12 @@ def : Pat<(i64 (extloadi32 ADDRrr:$addr)), (LDrr ADDRrr:$addr)>; def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>; // Sign-extending load of i32 into i64 is a new SPARC v9 instruction. -defm LDSW : Load<"ldsw", 0b001000, sextloadi32, I64Regs, i64>; +let DecoderMethod = "DecodeLoadInt" in + defm LDSW : Load<"ldsw", 0b001000, sextloadi32, I64Regs, i64>; // 64-bit stores. -defm STX : Store<"stx", 0b001110, store, I64Regs, i64>; +let DecoderMethod = "DecodeStoreInt" in + defm STX : Store<"stx", 0b001110, store, I64Regs, i64>; // Truncating stores from i64 are identical to the i32 stores. def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>; @@ -294,14 +297,6 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADDRri:$dst, (i64 G0))>; // 64-bit Conditionals. //===----------------------------------------------------------------------===// -// Conditional branch class on %xcc: -class XBranchSP<dag ins, string asmstr, list<dag> pattern> - : F2_3<0b001, 0b10, (outs), ins, asmstr, pattern> { - let isBranch = 1; - let isTerminator = 1; - let hasDelaySlot = 1; -} - // // Flag-setting instructions like subcc and addcc set both icc and xcc flags. // The icc flags correspond to the 32-bit result, and the xcc are for the @@ -312,14 +307,12 @@ class XBranchSP<dag ins, string asmstr, list<dag> pattern> let Predicates = [Is64Bit] in { -let Uses = [ICC] in -def BPXCC : XBranchSP<(ins brtarget:$imm19, CCOp:$cond), - "b$cond %xcc, $imm19", - [(SPbrxcc bb:$imm19, imm:$cond)]>; +let Uses = [ICC], cc = 0b10 in + defm BPX : IPredBranch<"%xcc", [(SPbrxcc bb:$imm19, imm:$cond)]>; // Conditional moves on %xcc. let Uses = [ICC], Constraints = "$f = $rd" in { -let cc = 0b110 in { +let intcc = 1, cc = 0b10 in { def MOVXCCrr : F4_1<0b101100, (outs IntRegs:$rd), (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond), "mov$cond %xcc, $rs2, $rd", @@ -332,7 +325,7 @@ def MOVXCCri : F4_2<0b101100, (outs IntRegs:$rd), (SPselectxcc simm11:$simm11, i32:$f, imm:$cond))]>; } // cc -let opf_cc = 0b110 in { +let intcc = 1, opf_cc = 0b10 in { def FMOVS_XCC : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond), "fmovs$cond %xcc, $rs2, $rd", @@ -351,6 +344,84 @@ def FMOVQ_XCC : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), } // opf_cc } // Uses, Constraints +// Branch On integer register with Prediction (BPr). +let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in +multiclass BranchOnReg<bits<3> cond, string OpcStr> { + def napt : F2_4<cond, 0, 1, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16), + !strconcat(OpcStr, " $rs1, $imm16"), []>; + def apt : F2_4<cond, 1, 1, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16), + !strconcat(OpcStr, ",a $rs1, $imm16"), []>; + def napn : F2_4<cond, 0, 0, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16), + !strconcat(OpcStr, ",pn $rs1, $imm16"), []>; + def apn : F2_4<cond, 1, 0, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16), + !strconcat(OpcStr, ",a,pn $rs1, $imm16"), []>; +} + +multiclass bpr_alias<string OpcStr, Instruction NAPT, Instruction APT> { + def : InstAlias<!strconcat(OpcStr, ",pt $rs1, $imm16"), + (NAPT I64Regs:$rs1, bprtarget16:$imm16), 0>; + def : InstAlias<!strconcat(OpcStr, ",a,pt $rs1, $imm16"), + (APT I64Regs:$rs1, bprtarget16:$imm16), 0>; +} + +defm BPZ : BranchOnReg<0b001, "brz">; +defm BPLEZ : BranchOnReg<0b010, "brlez">; +defm BPLZ : BranchOnReg<0b011, "brlz">; +defm BPNZ : BranchOnReg<0b101, "brnz">; +defm BPGZ : BranchOnReg<0b110, "brgz">; +defm BPGEZ : BranchOnReg<0b111, "brgez">; + +defm : bpr_alias<"brz", BPZnapt, BPZapt >; +defm : bpr_alias<"brlez", BPLEZnapt, BPLEZapt>; +defm : bpr_alias<"brlz", BPLZnapt, BPLZapt >; +defm : bpr_alias<"brnz", BPNZnapt, BPNZapt >; +defm : bpr_alias<"brgz", BPGZnapt, BPGZapt >; +defm : bpr_alias<"brgez", BPGEZnapt, BPGEZapt>; + +// Move integer register on register condition (MOVr). +multiclass MOVR< bits<3> rcond, string OpcStr> { + def rr : F4_4r<0b101111, 0b00000, rcond, (outs I64Regs:$rd), + (ins I64Regs:$rs1, IntRegs:$rs2), + !strconcat(OpcStr, " $rs1, $rs2, $rd"), []>; + + def ri : F4_4i<0b101111, rcond, (outs I64Regs:$rd), + (ins I64Regs:$rs1, i64imm:$simm10), + !strconcat(OpcStr, " $rs1, $simm10, $rd"), []>; +} + +defm MOVRRZ : MOVR<0b001, "movrz">; +defm MOVRLEZ : MOVR<0b010, "movrlez">; +defm MOVRLZ : MOVR<0b011, "movrlz">; +defm MOVRNZ : MOVR<0b101, "movrnz">; +defm MOVRGZ : MOVR<0b110, "movrgz">; +defm MOVRGEZ : MOVR<0b111, "movrgez">; + +// Move FP register on integer register condition (FMOVr). +multiclass FMOVR<bits<3> rcond, string OpcStr> { + + def S : F4_4r<0b110101, 0b00101, rcond, + (outs FPRegs:$rd), (ins I64Regs:$rs1, FPRegs:$rs2), + !strconcat(!strconcat("fmovrs", OpcStr)," $rs1, $rs2, $rd"), + []>; + def D : F4_4r<0b110101, 0b00110, rcond, + (outs FPRegs:$rd), (ins I64Regs:$rs1, FPRegs:$rs2), + !strconcat(!strconcat("fmovrd", OpcStr)," $rs1, $rs2, $rd"), + []>; + def Q : F4_4r<0b110101, 0b00111, rcond, + (outs FPRegs:$rd), (ins I64Regs:$rs1, FPRegs:$rs2), + !strconcat(!strconcat("fmovrq", OpcStr)," $rs1, $rs2, $rd"), + []>, Requires<[HasHardQuad]>; +} + +let Predicates = [HasV9] in { + defm FMOVRZ : FMOVR<0b001, "z">; + defm FMOVRLEZ : FMOVR<0b010, "lez">; + defm FMOVRLZ : FMOVR<0b011, "lz">; + defm FMOVRNZ : FMOVR<0b101, "nz">; + defm FMOVRGZ : FMOVR<0b110, "gz">; + defm FMOVRGEZ : FMOVR<0b111, "gez">; +} + //===----------------------------------------------------------------------===// // 64-bit Floating Point Conversions. //===----------------------------------------------------------------------===// @@ -471,6 +542,9 @@ def ATOMIC_SWAP_64 : Pseudo<(outs I64Regs:$rd), [(set i64:$rd, (atomic_swap_64 iPTR:$addr, i64:$rs2))]>; +let Predicates = [Is64Bit], hasSideEffects = 1, Uses = [ICC], cc = 0b10 in + defm TXCC : TRAP<"%xcc">; + // Global addresses, constant pool entries let Predicates = [Is64Bit] in { diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstrAliases.td b/contrib/llvm/lib/Target/Sparc/SparcInstrAliases.td index 7242c59059ab..d36f67b94204 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstrAliases.td +++ b/contrib/llvm/lib/Target/Sparc/SparcInstrAliases.td @@ -13,31 +13,52 @@ // Instruction aliases for conditional moves. // mov<cond> <ccreg> rs2, rd -multiclass cond_mov_alias<string cond, int condVal, string ccreg, +multiclass intcond_mov_alias<string cond, int condVal, string ccreg, Instruction movrr, Instruction movri, Instruction fmovs, Instruction fmovd> { - // mov<cond> (%icc|%xcc|%fcc0), rs2, rd + // mov<cond> (%icc|%xcc), rs2, rd def : InstAlias<!strconcat(!strconcat(!strconcat("mov", cond), ccreg), ", $rs2, $rd"), (movrr IntRegs:$rd, IntRegs:$rs2, condVal)>; - // mov<cond> (%icc|%xcc|%fcc0), simm11, rd + // mov<cond> (%icc|%xcc), simm11, rd def : InstAlias<!strconcat(!strconcat(!strconcat("mov", cond), ccreg), ", $simm11, $rd"), (movri IntRegs:$rd, i32imm:$simm11, condVal)>; - // fmovs<cond> (%icc|%xcc|%fcc0), $rs2, $rd + // fmovs<cond> (%icc|%xcc), $rs2, $rd def : InstAlias<!strconcat(!strconcat(!strconcat("fmovs", cond), ccreg), ", $rs2, $rd"), (fmovs FPRegs:$rd, FPRegs:$rs2, condVal)>; - // fmovd<cond> (%icc|%xcc|%fcc0), $rs2, $rd + // fmovd<cond> (%icc|%xcc), $rs2, $rd def : InstAlias<!strconcat(!strconcat(!strconcat("fmovd", cond), ccreg), ", $rs2, $rd"), (fmovd DFPRegs:$rd, DFPRegs:$rs2, condVal)>; } +// mov<cond> <ccreg> rs2, rd +multiclass fpcond_mov_alias<string cond, int condVal, + Instruction movrr, Instruction movri, + Instruction fmovs, Instruction fmovd> { + + // mov<cond> %fcc[0-3], rs2, rd + def : InstAlias<!strconcat(!strconcat("mov", cond), " $cc, $rs2, $rd"), + (movrr IntRegs:$rd, FCCRegs:$cc, IntRegs:$rs2, condVal)>; + + // mov<cond> %fcc[0-3], simm11, rd + def : InstAlias<!strconcat(!strconcat("mov", cond), " $cc, $simm11, $rd"), + (movri IntRegs:$rd, FCCRegs:$cc, i32imm:$simm11, condVal)>; + + // fmovs<cond> %fcc[0-3], $rs2, $rd + def : InstAlias<!strconcat(!strconcat("fmovs", cond), " $cc, $rs2, $rd"), + (fmovs FPRegs:$rd, FCCRegs:$cc, FPRegs:$rs2, condVal)>; + + // fmovd<cond> %fcc[0-3], $rs2, $rd + def : InstAlias<!strconcat(!strconcat("fmovd", cond), " $cc, $rs2, $rd"), + (fmovd DFPRegs:$rd, FCCRegs:$cc, DFPRegs:$rs2, condVal)>; +} // Instruction aliases for integer conditional branches and moves. multiclass int_cond_alias<string cond, int condVal> { @@ -46,15 +67,64 @@ multiclass int_cond_alias<string cond, int condVal> { def : InstAlias<!strconcat(!strconcat("b", cond), " $imm"), (BCOND brtarget:$imm, condVal)>; + // b<cond>,a $imm + def : InstAlias<!strconcat(!strconcat("b", cond), ",a $imm"), + (BCONDA brtarget:$imm, condVal)>; + + // b<cond> %icc, $imm + def : InstAlias<!strconcat(!strconcat("b", cond), " %icc, $imm"), + (BPICC brtarget:$imm, condVal)>, Requires<[HasV9]>; + + // b<cond>,pt %icc, $imm + def : InstAlias<!strconcat(!strconcat("b", cond), ",pt %icc, $imm"), + (BPICC brtarget:$imm, condVal)>, Requires<[HasV9]>; + + // b<cond>,a %icc, $imm + def : InstAlias<!strconcat(!strconcat("b", cond), ",a %icc, $imm"), + (BPICCA brtarget:$imm, condVal)>, Requires<[HasV9]>; + + // b<cond>,a,pt %icc, $imm + def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pt %icc, $imm"), + (BPICCA brtarget:$imm, condVal)>, Requires<[HasV9]>; + + // b<cond>,pn %icc, $imm + def : InstAlias<!strconcat(!strconcat("b", cond), ",pn %icc, $imm"), + (BPICCNT brtarget:$imm, condVal)>, Requires<[HasV9]>; + + // b<cond>,a,pn %icc, $imm + def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pn %icc, $imm"), + (BPICCANT brtarget:$imm, condVal)>, Requires<[HasV9]>; + // b<cond> %xcc, $imm def : InstAlias<!strconcat(!strconcat("b", cond), " %xcc, $imm"), (BPXCC brtarget:$imm, condVal)>, Requires<[Is64Bit]>; - defm : cond_mov_alias<cond, condVal, " %icc", + // b<cond>,pt %xcc, $imm + def : InstAlias<!strconcat(!strconcat("b", cond), ",pt %xcc, $imm"), + (BPXCC brtarget:$imm, condVal)>, Requires<[Is64Bit]>; + + // b<cond>,a %xcc, $imm + def : InstAlias<!strconcat(!strconcat("b", cond), ",a %xcc, $imm"), + (BPXCCA brtarget:$imm, condVal)>, Requires<[Is64Bit]>; + + // b<cond>,a,pt %xcc, $imm + def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pt %xcc, $imm"), + (BPXCCA brtarget:$imm, condVal)>, Requires<[Is64Bit]>; + + // b<cond>,pn %xcc, $imm + def : InstAlias<!strconcat(!strconcat("b", cond), ",pn %xcc, $imm"), + (BPXCCNT brtarget:$imm, condVal)>, Requires<[Is64Bit]>; + + // b<cond>,a,pn %xcc, $imm + def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pn %xcc, $imm"), + (BPXCCANT brtarget:$imm, condVal)>, Requires<[Is64Bit]>; + + + defm : intcond_mov_alias<cond, condVal, " %icc", MOVICCrr, MOVICCri, FMOVS_ICC, FMOVD_ICC>, Requires<[HasV9]>; - defm : cond_mov_alias<cond, condVal, " %xcc", + defm : intcond_mov_alias<cond, condVal, " %xcc", MOVXCCrr, MOVXCCri, FMOVS_XCC, FMOVD_XCC>, Requires<[Is64Bit]>; @@ -66,6 +136,59 @@ multiclass int_cond_alias<string cond, int condVal> { (FMOVQ_XCC QFPRegs:$rd, QFPRegs:$rs2, condVal)>, Requires<[Is64Bit, HasHardQuad]>; + // t<cond> %icc, rs1 + rs2 + def : InstAlias<!strconcat(!strconcat("t", cond), " %icc, $rs1 + $rs2"), + (TICCrr IntRegs:$rs1, IntRegs:$rs2, condVal)>, + Requires<[HasV9]>; + + // t<cond> %icc, rs => t<cond> %icc, G0 + rs + def : InstAlias<!strconcat(!strconcat("t", cond), " %icc, $rs2"), + (TICCrr G0, IntRegs:$rs2, condVal)>, + Requires<[HasV9]>; + + // t<cond> %xcc, rs1 + rs2 + def : InstAlias<!strconcat(!strconcat("t", cond), " %xcc, $rs1 + $rs2"), + (TXCCrr IntRegs:$rs1, IntRegs:$rs2, condVal)>, + Requires<[HasV9]>; + + // t<cond> %xcc, rs => t<cond> %xcc, G0 + rs + def : InstAlias<!strconcat(!strconcat("t", cond), " %xcc, $rs2"), + (TXCCrr G0, IntRegs:$rs2, condVal)>, + Requires<[HasV9]>; + + // t<cond> rs1 + rs2 => t<cond> %icc, rs1 + rs2 + def : InstAlias<!strconcat(!strconcat("t", cond), " $rs1 + $rs2"), + (TICCrr IntRegs:$rs1, IntRegs:$rs2, condVal)>; + + // t<cond> rs=> t<cond> %icc, G0 + rs2 + def : InstAlias<!strconcat(!strconcat("t", cond), " $rs2"), + (TICCrr G0, IntRegs:$rs2, condVal)>; + + // t<cond> %icc, rs1 + imm + def : InstAlias<!strconcat(!strconcat("t", cond), " %icc, $rs1 + $imm"), + (TICCri IntRegs:$rs1, i32imm:$imm, condVal)>, + Requires<[HasV9]>; + // t<cond> %icc, imm => t<cond> %icc, G0 + imm + def : InstAlias<!strconcat(!strconcat("t", cond), " %icc, $imm"), + (TICCri G0, i32imm:$imm, condVal)>, + Requires<[HasV9]>; + // t<cond> %xcc, rs1 + imm + def : InstAlias<!strconcat(!strconcat("t", cond), " %xcc, $rs1 + $imm"), + (TXCCri IntRegs:$rs1, i32imm:$imm, condVal)>, + Requires<[HasV9]>; + // t<cond> %xcc, imm => t<cond> %xcc, G0 + imm + def : InstAlias<!strconcat(!strconcat("t", cond), " %xcc, $imm"), + (TXCCri G0, i32imm:$imm, condVal)>, + Requires<[HasV9]>; + + // t<cond> rs1 + imm => t<cond> %icc, rs1 + imm + def : InstAlias<!strconcat(!strconcat("t", cond), " $rs1 + $imm"), + (TICCri IntRegs:$rs1, i32imm:$imm, condVal)>; + + // t<cond> imm => t<cond> %icc, G0 + imm + def : InstAlias<!strconcat(!strconcat("t", cond), " $imm"), + (TICCri G0, i32imm:$imm, condVal)>; + } @@ -76,13 +199,48 @@ multiclass fp_cond_alias<string cond, int condVal> { def : InstAlias<!strconcat(!strconcat("fb", cond), " $imm"), (FBCOND brtarget:$imm, condVal), 0>; - defm : cond_mov_alias<cond, condVal, " %fcc0", - MOVFCCrr, MOVFCCri, - FMOVS_FCC, FMOVD_FCC>, Requires<[HasV9]>; + // fb<cond>,a $imm + def : InstAlias<!strconcat(!strconcat("fb", cond), ",a $imm"), + (FBCONDA brtarget:$imm, condVal), 0>; + + // fb<cond> %fcc0, $imm + def : InstAlias<!strconcat(!strconcat("fb", cond), " $cc, $imm"), + (BPFCC brtarget:$imm, condVal, FCCRegs:$cc)>, + Requires<[HasV9]>; + + // fb<cond>,pt %fcc0, $imm + def : InstAlias<!strconcat(!strconcat("fb", cond), ",pt $cc, $imm"), + (BPFCC brtarget:$imm, condVal, FCCRegs:$cc)>, + Requires<[HasV9]>; + + // fb<cond>,a %fcc0, $imm + def : InstAlias<!strconcat(!strconcat("fb", cond), ",a $cc, $imm"), + (BPFCCA brtarget:$imm, condVal, FCCRegs:$cc)>, + Requires<[HasV9]>; + + // fb<cond>,a,pt %fcc0, $imm + def : InstAlias<!strconcat(!strconcat("fb", cond), ",a,pt $cc, $imm"), + (BPFCCA brtarget:$imm, condVal, FCCRegs:$cc)>, + Requires<[HasV9]>; + + // fb<cond>,pn %fcc0, $imm + def : InstAlias<!strconcat(!strconcat("fb", cond), ",pn $cc, $imm"), + (BPFCCNT brtarget:$imm, condVal, FCCRegs:$cc)>, + Requires<[HasV9]>; + + // fb<cond>,a,pn %fcc0, $imm + def : InstAlias<!strconcat(!strconcat("fb", cond), ",a,pn $cc, $imm"), + (BPFCCANT brtarget:$imm, condVal, FCCRegs:$cc)>, + Requires<[HasV9]>; + + defm : fpcond_mov_alias<cond, condVal, + V9MOVFCCrr, V9MOVFCCri, + V9FMOVS_FCC, V9FMOVD_FCC>, Requires<[HasV9]>; // fmovq<cond> %fcc0, $rs2, $rd - def : InstAlias<!strconcat(!strconcat("fmovq", cond), " %fcc0, $rs2, $rd"), - (FMOVQ_ICC QFPRegs:$rd, QFPRegs:$rs2, condVal)>, + def : InstAlias<!strconcat(!strconcat("fmovq", cond), " $cc, $rs2, $rd"), + (V9FMOVQ_FCC QFPRegs:$rd, FCCRegs:$cc, QFPRegs:$rs2, + condVal)>, Requires<[HasV9, HasHardQuad]>; } @@ -103,6 +261,8 @@ defm : int_cond_alias<"neg", 0b0110>; defm : int_cond_alias<"vc", 0b1111>; defm : int_cond_alias<"vs", 0b0111>; +defm : fp_cond_alias<"a", 0b0000>; +defm : fp_cond_alias<"n", 0b1000>; defm : fp_cond_alias<"u", 0b0111>; defm : fp_cond_alias<"g", 0b0110>; defm : fp_cond_alias<"ug", 0b0101>; @@ -118,16 +278,15 @@ defm : fp_cond_alias<"le", 0b1101>; defm : fp_cond_alias<"ule", 0b1110>; defm : fp_cond_alias<"o", 0b1111>; - // Instruction aliases for JMPL. // jmp addr -> jmpl addr, %g0 -def : InstAlias<"jmp $addr", (JMPLrr G0, MEMrr:$addr)>; -def : InstAlias<"jmp $addr", (JMPLri G0, MEMri:$addr)>; +def : InstAlias<"jmp $addr", (JMPLrr G0, MEMrr:$addr), 0>; +def : InstAlias<"jmp $addr", (JMPLri G0, MEMri:$addr), 0>; // call addr -> jmpl addr, %o7 -def : InstAlias<"call $addr", (JMPLrr O7, MEMrr:$addr)>; -def : InstAlias<"call $addr", (JMPLri O7, MEMri:$addr)>; +def : InstAlias<"call $addr", (JMPLrr O7, MEMrr:$addr), 0>; +def : InstAlias<"call $addr", (JMPLri O7, MEMri:$addr), 0>; // retl -> RETL 8 def : InstAlias<"retl", (RETL 8)>; @@ -140,3 +299,27 @@ def : InstAlias<"mov $rs2, $rd", (ORrr IntRegs:$rd, G0, IntRegs:$rs2)>; // mov simm13, rd -> or %g0, simm13, rd def : InstAlias<"mov $simm13, $rd", (ORri IntRegs:$rd, G0, i32imm:$simm13)>; + +// restore -> restore %g0, %g0, %g0 +def : InstAlias<"restore", (RESTORErr G0, G0, G0)>; + +def : MnemonicAlias<"return", "rett">, Requires<[HasV9]>; + +def : MnemonicAlias<"addc", "addx">, Requires<[HasV9]>; +def : MnemonicAlias<"addccc", "addxcc">, Requires<[HasV9]>; + +def : MnemonicAlias<"subc", "subx">, Requires<[HasV9]>; +def : MnemonicAlias<"subccc", "subxcc">, Requires<[HasV9]>; + + +def : InstAlias<"fcmps $rs1, $rs2", (V9FCMPS FCC0, FPRegs:$rs1, FPRegs:$rs2)>; +def : InstAlias<"fcmpd $rs1, $rs2", (V9FCMPD FCC0, DFPRegs:$rs1, DFPRegs:$rs2)>; +def : InstAlias<"fcmpq $rs1, $rs2", (V9FCMPQ FCC0, QFPRegs:$rs1, QFPRegs:$rs2)>, + Requires<[HasHardQuad]>; + +def : InstAlias<"fcmpes $rs1, $rs2", (V9FCMPES FCC0, FPRegs:$rs1, FPRegs:$rs2)>; +def : InstAlias<"fcmped $rs1, $rs2", (V9FCMPED FCC0, DFPRegs:$rs1, + DFPRegs:$rs2)>; +def : InstAlias<"fcmpeq $rs1, $rs2", (V9FCMPEQ FCC0, QFPRegs:$rs1, + QFPRegs:$rs2)>, + Requires<[HasHardQuad]>; diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstrFormats.td b/contrib/llvm/lib/Target/Sparc/SparcInstrFormats.td index b38a663bd3ca..3b5e2389932b 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstrFormats.td +++ b/contrib/llvm/lib/Target/Sparc/SparcInstrFormats.td @@ -51,38 +51,51 @@ class F2_1<bits<3> op2Val, dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{29-25} = rd; } -class F2_2<bits<3> op2Val, dag outs, dag ins, string asmstr, +class F2_2<bits<3> op2Val, bit annul, dag outs, dag ins, string asmstr, list<dag> pattern> : F2<outs, ins, asmstr, pattern> { bits<4> cond; - bit annul = 0; // currently unused - let op2 = op2Val; let Inst{29} = annul; let Inst{28-25} = cond; } -class F2_3<bits<3> op2Val, bits<2> ccVal, dag outs, dag ins, string asmstr, - list<dag> pattern> - : InstSP<outs, ins, asmstr, pattern> { - bit annul; +class F2_3<bits<3> op2Val, bit annul, bit pred, + dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSP<outs, ins, asmstr, pattern> { + bits<2> cc; bits<4> cond; - bit pred; bits<19> imm19; let op = 0; // op = 0 - bit annul = 0; // currently unused - let pred = 1; // default is predict taken - let Inst{29} = annul; let Inst{28-25} = cond; let Inst{24-22} = op2Val; - let Inst{21-20} = ccVal; + let Inst{21-20} = cc; let Inst{19} = pred; let Inst{18-0} = imm19; } +class F2_4<bits<3> cond, bit annul, bit pred, + dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSP<outs, ins, asmstr, pattern> { + bits<16> imm16; + bits<5> rs1; + + let op = 0; // op = 0 + + let Inst{29} = annul; + let Inst{28} = 0; + let Inst{27-25} = cond; + let Inst{24-22} = 0b011; + let Inst{21-20} = imm16{15-14}; + let Inst{19} = pred; + let Inst{18-14} = rs1; + let Inst{13-0} = imm16{13-0}; +} + + //===----------------------------------------------------------------------===// // Format #3 instruction classes in the Sparc //===----------------------------------------------------------------------===// @@ -159,7 +172,6 @@ class F3_3c<bits<2> opVal, bits<6> op3val, bits<9> opfval, dag outs, dag ins, let op = opVal; let op3 = op3val; - let rd = 0; let Inst{13-5} = opfval; // fp opcode let Inst{4-0} = rs2; @@ -218,44 +230,101 @@ class F4_1<bits<6> op3, dag outs, dag ins, string asmstr, list<dag> pattern> : F4<op3, outs, ins, asmstr, pattern> { - bits<3> cc; + bit intcc; + bits<2> cc; bits<4> cond; bits<5> rs2; let Inst{4-0} = rs2; - let Inst{11} = cc{0}; - let Inst{12} = cc{1}; + let Inst{12-11} = cc; let Inst{13} = 0; let Inst{17-14} = cond; - let Inst{18} = cc{2}; + let Inst{18} = intcc; } class F4_2<bits<6> op3, dag outs, dag ins, string asmstr, list<dag> pattern> : F4<op3, outs, ins, asmstr, pattern> { - bits<3> cc; + bit intcc; + bits<2> cc; bits<4> cond; bits<11> simm11; let Inst{10-0} = simm11; - let Inst{11} = cc{0}; - let Inst{12} = cc{1}; + let Inst{12-11} = cc; let Inst{13} = 1; let Inst{17-14} = cond; - let Inst{18} = cc{2}; + let Inst{18} = intcc; } class F4_3<bits<6> op3, bits<6> opf_low, dag outs, dag ins, string asmstr, list<dag> pattern> : F4<op3, outs, ins, asmstr, pattern> { bits<4> cond; - bits<3> opf_cc; + bit intcc; + bits<2> opf_cc; bits<5> rs2; let Inst{18} = 0; let Inst{17-14} = cond; - let Inst{13-11} = opf_cc; + let Inst{13} = intcc; + let Inst{12-11} = opf_cc; let Inst{10-5} = opf_low; let Inst{4-0} = rs2; } + +class F4_4r<bits<6> op3, bits<5> opf_low, bits<3> rcond, dag outs, dag ins, + string asmstr, list<dag> pattern> + : F4<op3, outs, ins, asmstr, pattern> { + bits <5> rs1; + bits <5> rs2; + let Inst{18-14} = rs1; + let Inst{13} = 0; // IsImm + let Inst{12-10} = rcond; + let Inst{9-5} = opf_low; + let Inst{4-0} = rs2; +} + + +class F4_4i<bits<6> op3, bits<3> rcond, dag outs, dag ins, + string asmstr, list<dag> pattern> + : F4<op3, outs, ins, asmstr, pattern> { + bits<5> rs1; + bits<10> simm10; + let Inst{18-14} = rs1; + let Inst{13} = 1; // IsImm + let Inst{12-10} = rcond; + let Inst{9-0} = simm10; +} + + +class TRAPSP<bits<6> op3Val, bit isimm, dag outs, dag ins, string asmstr, + list<dag> pattern>: F3<outs, ins, asmstr, pattern> { + + bits<4> cond; + bits<2> cc; + + let op = 0b10; + let rd{4} = 0; + let rd{3-0} = cond; + let op3 = op3Val; + let Inst{13} = isimm; + let Inst{12-11} = cc; + +} + +class TRAPSPrr<bits<6> op3Val, dag outs, dag ins, string asmstr, + list<dag> pattern>: TRAPSP<op3Val, 0, outs, ins, asmstr, pattern> { + bits<5> rs2; + + let Inst{10-5} = 0; + let Inst{4-0} = rs2; +} +class TRAPSPri<bits<6> op3Val, dag outs, dag ins, string asmstr, + list<dag> pattern>: TRAPSP<op3Val, 1, outs, ins, asmstr, pattern> { + bits<8> imm; + + let Inst{10-8} = 0; + let Inst{7-0} = imm; +} diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp index 6ecf81de8369..8b2e6bc5f32f 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp @@ -24,11 +24,10 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" -#define GET_INSTRINFO_CTOR_DTOR -#include "SparcGenInstrInfo.inc" - using namespace llvm; +#define GET_INSTRINFO_CTOR_DTOR +#include "SparcGenInstrInfo.inc" // Pin the vtable to this file. void SparcInstrInfo::anchor() {} @@ -89,6 +88,8 @@ static bool IsIntegerCC(unsigned CC) static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC) { switch(CC) { + case SPCC::ICC_A: return SPCC::ICC_N; + case SPCC::ICC_N: return SPCC::ICC_A; case SPCC::ICC_NE: return SPCC::ICC_E; case SPCC::ICC_E: return SPCC::ICC_NE; case SPCC::ICC_G: return SPCC::ICC_LE; @@ -104,6 +105,8 @@ static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC) case SPCC::ICC_VC: return SPCC::ICC_VS; case SPCC::ICC_VS: return SPCC::ICC_VC; + case SPCC::FCC_A: return SPCC::FCC_N; + case SPCC::FCC_N: return SPCC::FCC_A; case SPCC::FCC_U: return SPCC::FCC_O; case SPCC::FCC_O: return SPCC::FCC_U; case SPCC::FCC_G: return SPCC::FCC_ULE; @@ -154,14 +157,14 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, continue; } - while (llvm::next(I) != MBB.end()) - llvm::next(I)->eraseFromParent(); + while (std::next(I) != MBB.end()) + std::next(I)->eraseFromParent(); Cond.clear(); - FBB = 0; + FBB = nullptr; if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { - TBB = 0; + TBB = nullptr; I->eraseFromParent(); I = MBB.end(); UnCondBrIter = MBB.end(); @@ -281,7 +284,7 @@ void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB, bool KillSrc) const { unsigned numSubRegs = 0; unsigned movOpc = 0; - const unsigned *subRegIdx = 0; + const unsigned *subRegIdx = nullptr; const unsigned DFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd }; const unsigned QFP_DFP_SubRegsIdx[] = { SP::sub_even64, SP::sub_odd64 }; @@ -325,11 +328,11 @@ void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB, } else llvm_unreachable("Impossible reg-to-reg copy"); - if (numSubRegs == 0 || subRegIdx == 0 || movOpc == 0) + if (numSubRegs == 0 || subRegIdx == nullptr || movOpc == 0) return; const TargetRegisterInfo *TRI = &getRegisterInfo(); - MachineInstr *MovMI = 0; + MachineInstr *MovMI = nullptr; for (unsigned i = 0; i != numSubRegs; ++i) { unsigned Dst = TRI->getSubReg(DestReg, subRegIdx[i]); diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.h b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.h index a86cbcb1c4ba..3a1472ee9b15 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.h +++ b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.h @@ -45,52 +45,52 @@ public: /// such, whenever a client has an instance of instruction info, it should /// always be able to get register info as well (through this method). /// - virtual const SparcRegisterInfo &getRegisterInfo() const { return RI; } + const SparcRegisterInfo &getRegisterInfo() const { return RI; } /// isLoadFromStackSlot - If the specified machine instruction is a direct /// load from a stack slot, return the virtual or physical register number of /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, - int &FrameIndex) const; + unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const override; /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(const MachineInstr *MI, - int &FrameIndex) const; - - virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, - MachineBasicBlock *&FBB, - SmallVectorImpl<MachineOperand> &Cond, - bool AllowModify = false) const ; - - virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const; - - virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - const SmallVectorImpl<MachineOperand> &Cond, - DebugLoc DL) const; - - virtual void copyPhysReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, DebugLoc DL, - unsigned DestReg, unsigned SrcReg, - bool KillSrc) const; - - virtual void storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, - unsigned SrcReg, bool isKill, int FrameIndex, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const; - - virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, - unsigned DestReg, int FrameIndex, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const; + unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const override; + + bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, + MachineBasicBlock *&FBB, + SmallVectorImpl<MachineOperand> &Cond, + bool AllowModify = false) const override ; + + unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + + unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + MachineBasicBlock *FBB, + const SmallVectorImpl<MachineOperand> &Cond, + DebugLoc DL) const override; + + void copyPhysReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, DebugLoc DL, + unsigned DestReg, unsigned SrcReg, + bool KillSrc) const override; + + void storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned SrcReg, bool isKill, int FrameIndex, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const override; + + void loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const override; unsigned getGlobalBaseReg(MachineFunction *MF) const; }; diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.td b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.td index ae10ca0bd413..960261ce9835 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -29,7 +29,8 @@ def Is64Bit : Predicate<"Subtarget.is64Bit()">; // HasV9 - This predicate is true when the target processor supports V9 // instructions. Note that the machine may be running in 32-bit mode. -def HasV9 : Predicate<"Subtarget.isV9()">; +def HasV9 : Predicate<"Subtarget.isV9()">, + AssemblerPredicate<"FeatureV9">; // HasNoV9 - This predicate is true when the target doesn't have V9 // instructions. Use of this is just a hack for the isel not having proper @@ -37,7 +38,12 @@ def HasV9 : Predicate<"Subtarget.isV9()">; def HasNoV9 : Predicate<"!Subtarget.isV9()">; // HasVIS - This is true when the target processor has VIS extensions. -def HasVIS : Predicate<"Subtarget.isVIS()">; +def HasVIS : Predicate<"Subtarget.isVIS()">, + AssemblerPredicate<"FeatureVIS">; +def HasVIS2 : Predicate<"Subtarget.isVIS2()">, + AssemblerPredicate<"FeatureVIS2">; +def HasVIS3 : Predicate<"Subtarget.isVIS3()">, + AssemblerPredicate<"FeatureVIS3">; // HasHardQuad - This is true when the target processor supports quad floating // point instructions. @@ -104,8 +110,21 @@ def brtarget : Operand<OtherVT> { let EncoderMethod = "getBranchTargetOpValue"; } +def bprtarget : Operand<OtherVT> { + let EncoderMethod = "getBranchPredTargetOpValue"; +} + +def bprtarget16 : Operand<OtherVT> { + let EncoderMethod = "getBranchOnRegTargetOpValue"; +} + def calltarget : Operand<i32> { let EncoderMethod = "getCallTargetOpValue"; + let DecoderMethod = "DecodeCall"; +} + +def simm13Op : Operand<i32> { + let DecoderMethod = "DecodeSIMM13"; } // Operand for printing out a condition code. @@ -246,7 +265,7 @@ multiclass F3_12np<string OpcStr, bits<6> Op3Val> { (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), !strconcat(OpcStr, " $rs1, $rs2, $rd"), []>; def ri : F3_2<2, Op3Val, - (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), + (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), !strconcat(OpcStr, " $rs1, $simm13, $rd"), []>; } @@ -316,8 +335,8 @@ let isBarrier = 1, isTerminator = 1, rd = 0b1000, rs1 = 0, simm13 = 5 in def TA5 : F3_2<0b10, 0b111010, (outs), (ins), "ta 5", [(trap)]>; let rd = 0 in - def UNIMP : F2_1<0b000, (outs), (ins i32imm:$val), - "unimp $val", []>; + def UNIMP : F2_1<0b000, (outs), (ins i32imm:$imm22), + "unimp $imm22", []>; // SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after // instruction selection into a branch sequence. This has to handle all @@ -344,7 +363,7 @@ let Uses = [ICC], usesCustomInserter = 1 in { [(set f128:$dst, (SPselecticc f128:$T, f128:$F, imm:$Cond))]>; } -let usesCustomInserter = 1, Uses = [FCC] in { +let usesCustomInserter = 1, Uses = [FCC0] in { def SELECT_CC_Int_FCC : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), @@ -366,7 +385,8 @@ let usesCustomInserter = 1, Uses = [FCC] in { } // JMPL Instruction. -let isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in { +let isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, + DecoderMethod = "DecodeJMPL" in { def JMPLrr: F3_1<2, 0b111000, (outs IntRegs:$dst), (ins MEMrr:$addr), "jmpl $addr, $dst", []>; def JMPLri: F3_2<2, 0b111000, (outs IntRegs:$dst), (ins MEMri:$addr), @@ -386,29 +406,47 @@ let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, "jmp %i7+$val", []>; } +let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, + isBarrier = 1, rd = 0, DecoderMethod = "DecodeReturn" in { + def RETTrr : F3_1<2, 0b111001, (outs), (ins MEMrr:$addr), + "rett $addr", []>; + def RETTri : F3_2<2, 0b111001, (outs), (ins MEMri:$addr), + "rett $addr", []>; +} + // Section B.1 - Load Integer Instructions, p. 90 -defm LDSB : Load<"ldsb", 0b001001, sextloadi8, IntRegs, i32>; -defm LDSH : Load<"ldsh", 0b001010, sextloadi16, IntRegs, i32>; -defm LDUB : Load<"ldub", 0b000001, zextloadi8, IntRegs, i32>; -defm LDUH : Load<"lduh", 0b000010, zextloadi16, IntRegs, i32>; -defm LD : Load<"ld", 0b000000, load, IntRegs, i32>; +let DecoderMethod = "DecodeLoadInt" in { + defm LDSB : Load<"ldsb", 0b001001, sextloadi8, IntRegs, i32>; + defm LDSH : Load<"ldsh", 0b001010, sextloadi16, IntRegs, i32>; + defm LDUB : Load<"ldub", 0b000001, zextloadi8, IntRegs, i32>; + defm LDUH : Load<"lduh", 0b000010, zextloadi16, IntRegs, i32>; + defm LD : Load<"ld", 0b000000, load, IntRegs, i32>; +} // Section B.2 - Load Floating-point Instructions, p. 92 -defm LDF : Load<"ld", 0b100000, load, FPRegs, f32>; -defm LDDF : Load<"ldd", 0b100011, load, DFPRegs, f64>; -defm LDQF : Load<"ldq", 0b100010, load, QFPRegs, f128>, - Requires<[HasV9, HasHardQuad]>; +let DecoderMethod = "DecodeLoadFP" in + defm LDF : Load<"ld", 0b100000, load, FPRegs, f32>; +let DecoderMethod = "DecodeLoadDFP" in + defm LDDF : Load<"ldd", 0b100011, load, DFPRegs, f64>; +let DecoderMethod = "DecodeLoadQFP" in + defm LDQF : Load<"ldq", 0b100010, load, QFPRegs, f128>, + Requires<[HasV9, HasHardQuad]>; // Section B.4 - Store Integer Instructions, p. 95 -defm STB : Store<"stb", 0b000101, truncstorei8, IntRegs, i32>; -defm STH : Store<"sth", 0b000110, truncstorei16, IntRegs, i32>; -defm ST : Store<"st", 0b000100, store, IntRegs, i32>; +let DecoderMethod = "DecodeStoreInt" in { + defm STB : Store<"stb", 0b000101, truncstorei8, IntRegs, i32>; + defm STH : Store<"sth", 0b000110, truncstorei16, IntRegs, i32>; + defm ST : Store<"st", 0b000100, store, IntRegs, i32>; +} // Section B.5 - Store Floating-point Instructions, p. 97 -defm STF : Store<"st", 0b100100, store, FPRegs, f32>; -defm STDF : Store<"std", 0b100111, store, DFPRegs, f64>; -defm STQF : Store<"stq", 0b100110, store, QFPRegs, f128>, - Requires<[HasV9, HasHardQuad]>; +let DecoderMethod = "DecodeStoreFP" in + defm STF : Store<"st", 0b100100, store, FPRegs, f32>; +let DecoderMethod = "DecodeStoreDFP" in + defm STDF : Store<"std", 0b100111, store, DFPRegs, f64>; +let DecoderMethod = "DecodeStoreQFP" in + defm STQF : Store<"stq", 0b100110, store, QFPRegs, f128>, + Requires<[HasV9, HasHardQuad]>; // Section B.9 - SETHI Instruction, p. 104 def SETHIi: F2_1<0b100, @@ -422,42 +460,51 @@ let rd = 0, imm22 = 0 in def NOP : F2_1<0b100, (outs), (ins), "nop", []>; // Section B.11 - Logical Instructions, p. 106 -defm AND : F3_12<"and", 0b000001, and, IntRegs, i32, i32imm>; +defm AND : F3_12<"and", 0b000001, and, IntRegs, i32, simm13Op>; def ANDNrr : F3_1<2, 0b000101, (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), "andn $rs1, $rs2, $rd", [(set i32:$rd, (and i32:$rs1, (not i32:$rs2)))]>; def ANDNri : F3_2<2, 0b000101, - (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), + (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), "andn $rs1, $simm13, $rd", []>; -defm OR : F3_12<"or", 0b000010, or, IntRegs, i32, i32imm>; +defm OR : F3_12<"or", 0b000010, or, IntRegs, i32, simm13Op>; def ORNrr : F3_1<2, 0b000110, (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), "orn $rs1, $rs2, $rd", [(set i32:$rd, (or i32:$rs1, (not i32:$rs2)))]>; def ORNri : F3_2<2, 0b000110, - (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), + (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), "orn $rs1, $simm13, $rd", []>; -defm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, i32imm>; +defm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, simm13Op>; def XNORrr : F3_1<2, 0b000111, (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), "xnor $rs1, $rs2, $rd", [(set i32:$rd, (not (xor i32:$rs1, i32:$rs2)))]>; def XNORri : F3_2<2, 0b000111, - (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), + (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), "xnor $rs1, $simm13, $rd", []>; +let Defs = [ICC] in { + defm ANDCC : F3_12np<"andcc", 0b010001>; + defm ANDNCC : F3_12np<"andncc", 0b010101>; + defm ORCC : F3_12np<"orcc", 0b010010>; + defm ORNCC : F3_12np<"orncc", 0b010110>; + defm XORCC : F3_12np<"xorcc", 0b010011>; + defm XNORCC : F3_12np<"xnorcc", 0b010111>; +} + // Section B.12 - Shift Instructions, p. 107 -defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, i32imm>; -defm SRL : F3_12<"srl", 0b100110, srl, IntRegs, i32, i32imm>; -defm SRA : F3_12<"sra", 0b100111, sra, IntRegs, i32, i32imm>; +defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, simm13Op>; +defm SRL : F3_12<"srl", 0b100110, srl, IntRegs, i32, simm13Op>; +defm SRA : F3_12<"sra", 0b100111, sra, IntRegs, i32, simm13Op>; // Section B.13 - Add Instructions, p. 108 -defm ADD : F3_12<"add", 0b000000, add, IntRegs, i32, i32imm>; +defm ADD : F3_12<"add", 0b000000, add, IntRegs, i32, simm13Op>; // "LEA" forms of add (patterns to make tblgen happy) let Predicates = [Is32Bit], isCodeGenOnly = 1 in @@ -467,18 +514,24 @@ let Predicates = [Is32Bit], isCodeGenOnly = 1 in [(set iPTR:$dst, ADDRri:$addr)]>; let Defs = [ICC] in - defm ADDCC : F3_12<"addcc", 0b010000, addc, IntRegs, i32, i32imm>; + defm ADDCC : F3_12<"addcc", 0b010000, addc, IntRegs, i32, simm13Op>; + +let Uses = [ICC] in + defm ADDC : F3_12np<"addx", 0b001000>; let Uses = [ICC], Defs = [ICC] in - defm ADDE : F3_12<"addxcc", 0b011000, adde, IntRegs, i32, i32imm>; + defm ADDE : F3_12<"addxcc", 0b011000, adde, IntRegs, i32, simm13Op>; // Section B.15 - Subtract Instructions, p. 110 -defm SUB : F3_12 <"sub" , 0b000100, sub, IntRegs, i32, i32imm>; +defm SUB : F3_12 <"sub" , 0b000100, sub, IntRegs, i32, simm13Op>; let Uses = [ICC], Defs = [ICC] in - defm SUBE : F3_12 <"subxcc" , 0b011100, sube, IntRegs, i32, i32imm>; + defm SUBE : F3_12 <"subxcc" , 0b011100, sube, IntRegs, i32, simm13Op>; let Defs = [ICC] in - defm SUBCC : F3_12 <"subcc", 0b010100, subc, IntRegs, i32, i32imm>; + defm SUBCC : F3_12 <"subcc", 0b010100, subc, IntRegs, i32, simm13Op>; + +let Uses = [ICC] in + defm SUBC : F3_12np <"subx", 0b001100>; let Defs = [ICC], rd = 0 in { def CMPrr : F3_1<2, 0b010100, @@ -486,7 +539,7 @@ let Defs = [ICC], rd = 0 in { "cmp $rs1, $rs2", [(SPcmpicc i32:$rs1, i32:$rs2)]>; def CMPri : F3_2<2, 0b010100, - (outs), (ins IntRegs:$rs1, i32imm:$simm13), + (outs), (ins IntRegs:$rs1, simm13Op:$simm13), "cmp $rs1, $simm13", [(SPcmpicc i32:$rs1, (i32 simm13:$simm13))]>; } @@ -494,7 +547,12 @@ let Defs = [ICC], rd = 0 in { // Section B.18 - Multiply Instructions, p. 113 let Defs = [Y] in { defm UMUL : F3_12np<"umul", 0b001010>; - defm SMUL : F3_12 <"smul", 0b001011, mul, IntRegs, i32, i32imm>; + defm SMUL : F3_12 <"smul", 0b001011, mul, IntRegs, i32, simm13Op>; +} + +let Defs = [Y, ICC] in { + defm UMULCC : F3_12np<"umulcc", 0b011010>; + defm SMULCC : F3_12np<"smulcc", 0b011011>; } // Section B.19 - Divide Instructions, p. 115 @@ -503,6 +561,11 @@ let Defs = [Y] in { defm SDIV : F3_12np<"sdiv", 0b001111>; } +let Defs = [Y, ICC] in { + defm UDIVCC : F3_12np<"udivcc", 0b011110>; + defm SDIVCC : F3_12np<"sdivcc", 0b011111>; +} + // Section B.20 - SAVE and RESTORE, p. 117 defm SAVE : F3_12np<"save" , 0b111100>; defm RESTORE : F3_12np<"restore", 0b111101>; @@ -511,7 +574,7 @@ defm RESTORE : F3_12np<"restore", 0b111101>; // unconditional branch class. class BranchAlways<dag ins, string asmstr, list<dag> pattern> - : F2_2<0b010, (outs), ins, asmstr, pattern> { + : F2_2<0b010, 0, (outs), ins, asmstr, pattern> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; @@ -521,14 +584,36 @@ class BranchAlways<dag ins, string asmstr, list<dag> pattern> let cond = 8 in def BA : BranchAlways<(ins brtarget:$imm22), "ba $imm22", [(br bb:$imm22)]>; + +let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in { + // conditional branch class: class BranchSP<dag ins, string asmstr, list<dag> pattern> - : F2_2<0b010, (outs), ins, asmstr, pattern> { - let isBranch = 1; - let isTerminator = 1; - let hasDelaySlot = 1; + : F2_2<0b010, 0, (outs), ins, asmstr, pattern>; + +// conditional branch with annul class: +class BranchSPA<dag ins, string asmstr, list<dag> pattern> + : F2_2<0b010, 1, (outs), ins, asmstr, pattern>; + +// Conditional branch class on %icc|%xcc with predication: +multiclass IPredBranch<string regstr, list<dag> CCPattern> { + def CC : F2_3<0b001, 0, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond), + !strconcat("b$cond ", !strconcat(regstr, ", $imm19")), + CCPattern>; + def CCA : F2_3<0b001, 1, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond), + !strconcat("b$cond,a ", !strconcat(regstr, ", $imm19")), + []>; + def CCNT : F2_3<0b001, 0, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond), + !strconcat("b$cond,pn ", !strconcat(regstr, ", $imm19")), + []>; + def CCANT : F2_3<0b001, 1, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond), + !strconcat("b$cond,a,pn ", !strconcat(regstr, ", $imm19")), + []>; } +} // let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 + + // Indirect branch instructions. let isTerminator = 1, isBarrier = 1, hasDelaySlot = 1, isBranch =1, isIndirectBranch = 1, rd = 0, isCodeGenOnly = 1 in { @@ -542,33 +627,64 @@ let isTerminator = 1, isBarrier = 1, hasDelaySlot = 1, isBranch =1, [(brind ADDRri:$ptr)]>; } -let Uses = [ICC] in +let Uses = [ICC] in { def BCOND : BranchSP<(ins brtarget:$imm22, CCOp:$cond), "b$cond $imm22", [(SPbricc bb:$imm22, imm:$cond)]>; + def BCONDA : BranchSPA<(ins brtarget:$imm22, CCOp:$cond), + "b$cond,a $imm22", []>; + + let Predicates = [HasV9], cc = 0b00 in + defm BPI : IPredBranch<"%icc", []>; +} // Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121 +let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in { + // floating-point conditional branch class: class FPBranchSP<dag ins, string asmstr, list<dag> pattern> - : F2_2<0b110, (outs), ins, asmstr, pattern> { - let isBranch = 1; - let isTerminator = 1; - let hasDelaySlot = 1; + : F2_2<0b110, 0, (outs), ins, asmstr, pattern>; + +// floating-point conditional branch with annul class: +class FPBranchSPA<dag ins, string asmstr, list<dag> pattern> + : F2_2<0b110, 1, (outs), ins, asmstr, pattern>; + +// Conditional branch class on %fcc0-%fcc3 with predication: +multiclass FPredBranch { + def CC : F2_3<0b101, 0, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond, + FCCRegs:$cc), + "fb$cond $cc, $imm19", []>; + def CCA : F2_3<0b101, 1, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond, + FCCRegs:$cc), + "fb$cond,a $cc, $imm19", []>; + def CCNT : F2_3<0b101, 0, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond, + FCCRegs:$cc), + "fb$cond,pn $cc, $imm19", []>; + def CCANT : F2_3<0b101, 1, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond, + FCCRegs:$cc), + "fb$cond,a,pn $cc, $imm19", []>; } +} // let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 -let Uses = [FCC] in +let Uses = [FCC0] in { def FBCOND : FPBranchSP<(ins brtarget:$imm22, CCOp:$cond), "fb$cond $imm22", [(SPbrfcc bb:$imm22, imm:$cond)]>; + def FBCONDA : FPBranchSPA<(ins brtarget:$imm22, CCOp:$cond), + "fb$cond,a $imm22", []>; +} + +let Predicates = [HasV9] in + defm BPF : FPredBranch; // Section B.24 - Call and Link Instruction, p. 125 // This is the only Format 1 instruction let Uses = [O6], hasDelaySlot = 1, isCall = 1 in { - def CALL : InstSP<(outs), (ins calltarget:$dst, variable_ops), - "call $dst", []> { + def CALL : InstSP<(outs), (ins calltarget:$disp, variable_ops), + "call $disp", []> { bits<30> disp; let op = 1; let Inst{29-0} = disp; @@ -596,11 +712,11 @@ let Uses = [Y], rs1 = 0, rs2 = 0 in // Section B.29 - Write State Register Instructions let Defs = [Y], rd = 0 in { def WRYrr : F3_1<2, 0b110000, - (outs), (ins IntRegs:$b, IntRegs:$c), - "wr $b, $c, %y", []>; + (outs), (ins IntRegs:$rs1, IntRegs:$rs2), + "wr $rs1, $rs2, %y", []>; def WRYri : F3_2<2, 0b110000, - (outs), (ins IntRegs:$b, i32imm:$c), - "wr $b, $c, %y", []>; + (outs), (ins IntRegs:$rs1, simm13Op:$simm13), + "wr $rs1, $simm13, %y", []>; } // Convert Integer to Floating-point Instructions, p. 141 def FITOS : F3_3u<2, 0b110100, 0b011000100, @@ -771,7 +887,7 @@ def FDIVQ : F3_3<2, 0b110100, 0b001001111, // This behavior is modeled with a forced noop after the instruction in // DelaySlotFiller. -let Defs = [FCC] in { +let Defs = [FCC0], rd = 0, isCodeGenOnly = 1 in { def FCMPS : F3_3c<2, 0b110101, 0b001010001, (outs), (ins FPRegs:$rs1, FPRegs:$rs2), "fcmps $rs1, $rs2", @@ -823,7 +939,7 @@ let Uses = [O6], isCall = 1, hasDelaySlot = 1 in // V9 Conditional Moves. let Predicates = [HasV9], Constraints = "$f = $rd" in { // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. - let Uses = [ICC], cc = 0b100 in { + let Uses = [ICC], intcc = 1, cc = 0b00 in { def MOVICCrr : F4_1<0b101100, (outs IntRegs:$rd), (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond), @@ -838,7 +954,7 @@ let Predicates = [HasV9], Constraints = "$f = $rd" in { (SPselecticc simm11:$simm11, i32:$f, imm:$cond))]>; } - let Uses = [FCC], cc = 0b000 in { + let Uses = [FCC0], intcc = 0, cc = 0b00 in { def MOVFCCrr : F4_1<0b101100, (outs IntRegs:$rd), (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond), @@ -852,7 +968,7 @@ let Predicates = [HasV9], Constraints = "$f = $rd" in { (SPselectfcc simm11:$simm11, i32:$f, imm:$cond))]>; } - let Uses = [ICC], opf_cc = 0b100 in { + let Uses = [ICC], intcc = 1, opf_cc = 0b00 in { def FMOVS_ICC : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond), @@ -871,7 +987,7 @@ let Predicates = [HasV9], Constraints = "$f = $rd" in { Requires<[HasHardQuad]>; } - let Uses = [FCC], opf_cc = 0b000 in { + let Uses = [FCC0], intcc = 0, opf_cc = 0b00 in { def FMOVS_FCC : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond), @@ -921,6 +1037,59 @@ let Predicates = [HasV9] in { Requires<[HasHardQuad]>; } +// Floating-point compare instruction with %fcc0-%fcc3. +def V9FCMPS : F3_3c<2, 0b110101, 0b001010001, + (outs FCCRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), + "fcmps $rd, $rs1, $rs2", []>; +def V9FCMPD : F3_3c<2, 0b110101, 0b001010010, + (outs FCCRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fcmpd $rd, $rs1, $rs2", []>; +def V9FCMPQ : F3_3c<2, 0b110101, 0b001010011, + (outs FCCRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), + "fcmpq $rd, $rs1, $rs2", []>, + Requires<[HasHardQuad]>; + +let hasSideEffects = 1 in { + def V9FCMPES : F3_3c<2, 0b110101, 0b001010101, + (outs FCCRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), + "fcmpes $rd, $rs1, $rs2", []>; + def V9FCMPED : F3_3c<2, 0b110101, 0b001010110, + (outs FCCRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fcmped $rd, $rs1, $rs2", []>; + def V9FCMPEQ : F3_3c<2, 0b110101, 0b001010111, + (outs FCCRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), + "fcmpeq $rd, $rs1, $rs2", []>, + Requires<[HasHardQuad]>; +} + +// Floating point conditional move instrucitons with %fcc0-%fcc3. +let Predicates = [HasV9] in { + let Constraints = "$f = $rd", intcc = 0 in { + def V9MOVFCCrr + : F4_1<0b101100, (outs IntRegs:$rd), + (ins FCCRegs:$cc, IntRegs:$rs2, IntRegs:$f, CCOp:$cond), + "mov$cond $cc, $rs2, $rd", []>; + def V9MOVFCCri + : F4_2<0b101100, (outs IntRegs:$rd), + (ins FCCRegs:$cc, i32imm:$simm11, IntRegs:$f, CCOp:$cond), + "mov$cond $cc, $simm11, $rd", []>; + def V9FMOVS_FCC + : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), + (ins FCCRegs:$opf_cc, FPRegs:$rs2, FPRegs:$f, CCOp:$cond), + "fmovs$cond $opf_cc, $rs2, $rd", []>; + def V9FMOVD_FCC + : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), + (ins FCCRegs:$opf_cc, DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), + "fmovd$cond $opf_cc, $rs2, $rd", []>; + def V9FMOVQ_FCC + : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), + (ins FCCRegs:$opf_cc, QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), + "fmovq$cond $opf_cc, $rs2, $rd", []>, + Requires<[HasHardQuad]>; + } // Constraints = "$f = $rd", ... +} // let Predicates = [hasV9] + + // POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear // the top 32-bits before using it. To do this clearing, we use a SRLri X,0. let rs1 = 0 in @@ -935,10 +1104,10 @@ let hasSideEffects =1, rd = 0, rs1 = 0b01111, rs2 = 0 in def STBAR : F3_1<2, 0b101000, (outs), (ins), "stbar", []>; let Predicates = [HasV9], hasSideEffects = 1, rd = 0, rs1 = 0b01111 in - def MEMBARi : F3_2<2, 0b101000, (outs), (ins i32imm:$simm13), + def MEMBARi : F3_2<2, 0b101000, (outs), (ins simm13Op:$simm13), "membar $simm13", []>; -let Constraints = "$val = $dst" in { +let Constraints = "$val = $dst", DecoderMethod = "DecodeSWAP" in { def SWAPrr : F3_1<3, 0b001111, (outs IntRegs:$dst), (ins MEMrr:$addr, IntRegs:$val), "swap [$addr], $dst", @@ -957,6 +1126,28 @@ let Predicates = [HasV9], Constraints = "$swap = $rd" in [(set i32:$rd, (atomic_cmp_swap iPTR:$rs1, i32:$rs2, i32:$swap))]>; +let Defs = [ICC] in { +defm TADDCC : F3_12np<"taddcc", 0b100000>; +defm TSUBCC : F3_12np<"tsubcc", 0b100001>; + +let hasSideEffects = 1 in { + defm TADDCCTV : F3_12np<"taddcctv", 0b100010>; + defm TSUBCCTV : F3_12np<"tsubcctv", 0b100011>; +} +} + +multiclass TRAP<string regStr> { + def rr : TRAPSPrr<0b111010, (outs), (ins IntRegs:$rs1, IntRegs:$rs2, + CCOp:$cond), + !strconcat(!strconcat("t$cond ", regStr), ", $rs1 + $rs2"), []>; + def ri : TRAPSPri<0b111010, (outs), (ins IntRegs:$rs1, i32imm:$imm, + CCOp:$cond), + !strconcat(!strconcat("t$cond ", regStr), ", $rs1 + $imm"), []>; +} + +let hasSideEffects = 1, Uses = [ICC], cc = 0b00 in + defm TICC : TRAP<"%icc">; + //===----------------------------------------------------------------------===// // Non-Instruction Patterns //===----------------------------------------------------------------------===// @@ -1032,4 +1223,5 @@ def : Pat<(atomic_store ADDRri:$dst, i32:$val), (STri ADDRri:$dst, $val)>; include "SparcInstr64Bit.td" +include "SparcInstrVIS.td" include "SparcInstrAliases.td" diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstrVIS.td b/contrib/llvm/lib/Target/Sparc/SparcInstrVIS.td new file mode 100644 index 000000000000..3e2b49d05c28 --- /dev/null +++ b/contrib/llvm/lib/Target/Sparc/SparcInstrVIS.td @@ -0,0 +1,263 @@ +//===---- SparcInstrVIS.td - Visual Instruction Set extensions (VIS) -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains instruction formats, definitions and patterns needed for +// VIS, VIS II, VIS II instructions on SPARC. +//===----------------------------------------------------------------------===// + +// VIS Instruction Format. +class VISInstFormat<bits<9> opfval, dag outs, dag ins, string asmstr, + list<dag> pattern> + : F3_3<0b10, 0b110110, opfval, outs, ins, asmstr, pattern>; + +class VISInst<bits<9> opfval, string OpcStr, RegisterClass RC = DFPRegs> + : VISInstFormat<opfval, + (outs RC:$rd), (ins RC:$rs1, RC:$rs2), + !strconcat(OpcStr, " $rs1, $rs2, $rd"), []>; + +// VIS Instruction with integer destination register. +class VISInstID<bits<9> opfval, string OpcStr> + : VISInstFormat<opfval, + (outs I64Regs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + !strconcat(OpcStr, " $rs1, $rs2, $rd"), []>; + +// For VIS Instructions with no operand. +let rd = 0, rs1 = 0, rs2 = 0 in +class VISInst0<bits<9> opfval, string asmstr> + : VISInstFormat<opfval, (outs), (ins), asmstr, []>; + +// For VIS Instructions with only rs1, rd operands. +let rs2 = 0 in +class VISInst1<bits<9> opfval, string OpcStr, RegisterClass RC = DFPRegs> + : VISInstFormat<opfval, + (outs RC:$rd), (ins RC:$rs1), + !strconcat(OpcStr, " $rs1, $rd"), []>; + +// For VIS Instructions with only rs2, rd operands. +let rs1 = 0 in +class VISInst2<bits<9> opfval, string OpcStr, RegisterClass RC = DFPRegs> + : VISInstFormat<opfval, + (outs RC:$rd), (ins RC:$rs2), + !strconcat(OpcStr, " $rs2, $rd"), []>; + +// For VIS Instructions with only rd operand. +let Constraints = "$rd = $f", rs1 = 0, rs2 = 0 in +class VISInstD<bits<9> opfval, string OpcStr, RegisterClass RC = DFPRegs> + : VISInstFormat<opfval, + (outs RC:$rd), (ins RC:$f), + !strconcat(OpcStr, " $rd"), []>; + +// VIS 1 Instructions +let Predicates = [HasVIS] in { + +def FPADD16 : VISInst<0b001010000, "fpadd16">; +def FPADD16S : VISInst<0b001010001, "fpadd16s">; +def FPADD32 : VISInst<0b001010010, "fpadd32">; +def FPADD32S : VISInst<0b001010011, "fpadd32s">; +def FPSUB16 : VISInst<0b001010100, "fpsub16">; +def FPSUB16S : VISInst<0b001010101, "fpsub16S">; +def FPSUB32 : VISInst<0b001010110, "fpsub32">; +def FPSUB32S : VISInst<0b001010111, "fpsub32S">; + +def FPACK16 : VISInst2<0b000111011, "fpack16">; +def FPACK32 : VISInst <0b000111010, "fpack32">; +def FPACKFIX : VISInst2<0b000111101, "fpackfix">; +def FEXPAND : VISInst2<0b001001101, "fexpand">; +def FPMERGE : VISInst <0b001001011, "fpmerge">; + +def FMUL8X16 : VISInst<0b00110001, "fmul8x16">; +def FMUL8X16AU : VISInst<0b00110011, "fmul8x16au">; +def FMUL8X16AL : VISInst<0b00110101, "fmul8x16al">; +def FMUL8SUX16 : VISInst<0b00110110, "fmul8sux16">; +def FMUL8ULX16 : VISInst<0b00110111, "fmul8ulx16">; +def FMULD8SUX16 : VISInst<0b00111000, "fmuld8sux16">; +def FMULD8ULX16 : VISInst<0b00111001, "fmuld8ulx16">; + +def ALIGNADDR : VISInst<0b000011000, "alignaddr", I64Regs>; +def ALIGNADDRL : VISInst<0b000011010, "alignaddrl", I64Regs>; +def FALIGNADATA : VISInst<0b001001000, "faligndata">; + +def FZERO : VISInstD<0b001100000, "fzero">; +def FZEROS : VISInstD<0b001100001, "fzeros", FPRegs>; +def FONE : VISInstD<0b001111110, "fone">; +def FONES : VISInstD<0b001111111, "fones", FPRegs>; +def FSRC1 : VISInst1<0b001110100, "fsrc1">; +def FSRC1S : VISInst1<0b001110101, "fsrc1s", FPRegs>; +def FSRC2 : VISInst2<0b001111000, "fsrc2">; +def FSRC2S : VISInst2<0b001111001, "fsrc2s", FPRegs>; +def FNOT1 : VISInst1<0b001101010, "fnot1">; +def FNOT1S : VISInst1<0b001101011, "fnot1s", FPRegs>; +def FNOT2 : VISInst2<0b001100110, "fnot2">; +def FNOT2S : VISInst2<0b001100111, "fnot2s", FPRegs>; +def FOR : VISInst<0b001111100, "for">; +def FORS : VISInst<0b001111101, "fors", FPRegs>; +def FNOR : VISInst<0b001100010, "fnor">; +def FNORS : VISInst<0b001100011, "fnors", FPRegs>; +def FAND : VISInst<0b001110000, "fand">; +def FANDS : VISInst<0b001110001, "fands", FPRegs>; +def FNAND : VISInst<0b001101110, "fnand">; +def FNANDS : VISInst<0b001101111, "fnands", FPRegs>; +def FXOR : VISInst<0b001101100, "fxor">; +def FXORS : VISInst<0b001101101, "fxors", FPRegs>; +def FXNOR : VISInst<0b001110010, "fxnor">; +def FXNORS : VISInst<0b001110011, "fxnors", FPRegs>; + +def FORNOT1 : VISInst<0b001111010, "fornot1">; +def FORNOT1S : VISInst<0b001111011, "fornot1s", FPRegs>; +def FORNOT2 : VISInst<0b001110110, "fornot2">; +def FORNOT2S : VISInst<0b001110111, "fornot2s", FPRegs>; +def FANDNOT1 : VISInst<0b001101000, "fandnot1">; +def FANDNOT1S : VISInst<0b001101001, "fandnot1s", FPRegs>; +def FANDNOT2 : VISInst<0b001100100, "fandnot2">; +def FANDNOT2S : VISInst<0b001100101, "fandnot2s", FPRegs>; + +def FCMPGT16 : VISInstID<0b000101000, "fcmpgt16">; +def FCMPGT32 : VISInstID<0b000101100, "fcmpgt32">; +def FCMPLE16 : VISInstID<0b000100000, "fcmple16">; +def FCMPLE32 : VISInstID<0b000100100, "fcmple32">; +def FCMPNE16 : VISInstID<0b000100010, "fcmpne16">; +def FCMPNE32 : VISInstID<0b000100110, "fcmpne32">; +def FCMPEQ16 : VISInstID<0b000101010, "fcmpeq16">; +def FCMPEQ32 : VISInstID<0b000101110, "fcmpeq32">; + + +def EDGE8 : VISInst<0b000000000, "edge8", I64Regs>; +def EDGE8L : VISInst<0b000000010, "edge8l", I64Regs>; +def EDGE16 : VISInst<0b000000100, "edge16", I64Regs>; +def EDGE16L : VISInst<0b000000110, "edge16l", I64Regs>; +def EDGE32 : VISInst<0b000001000, "edge32", I64Regs>; +def EDGE32L : VISInst<0b000001010, "edge32l", I64Regs>; + +def PDIST : VISInst<0b00111110, "pdist">; + +def ARRAY8 : VISInst<0b000010000, "array8", I64Regs>; +def ARRAY16 : VISInst<0b000010010, "array16", I64Regs>; +def ARRAY32 : VISInst<0b000010100, "array32", I64Regs>; + +def SHUTDOWN : VISInst0<0b010000000, "shutdown">; + +} // Predicates = [HasVIS] + + +// VIS 2 Instructions. +let Predicates = [HasVIS2] in { + +def BMASK : VISInst<0b000011001, "bmask", I64Regs>; +def BSHUFFLE : VISInst<0b000011100, "bshuffle">; + +def SIAM : VISInst0<0b010000001, "siam">; + +def EDGE8N : VISInst<0b000000001, "edge8n", I64Regs>; +def EDGE8LN : VISInst<0b000000011, "edge8ln", I64Regs>; +def EDGE16N : VISInst<0b000000101, "edge16n", I64Regs>; +def EDGE16LN : VISInst<0b000000111, "edge16ln", I64Regs>; +def EDGE32N : VISInst<0b000001001, "edge32n", I64Regs>; +def EDGE32LN : VISInst<0b000001011, "edge32ln", I64Regs>; +} // Predicates = [HasVIS2] + + +// VIS 3 Instructions. +let Predicates = [HasVIS3] in { + +let Uses = [ICC] in +def ADDXC : VISInst<0b000010001, "addxc", I64Regs>; + +let Defs = [ICC], Uses = [ICC] in +def ADDXCCC : VISInst<0b000010011, "addxccc", I64Regs>; + +let rd = 0, rs1 = 0 in { +def CMASK8 : VISInstFormat<0b000011011, (outs), (ins I64Regs:$rs2), + "cmask8 $rs2", []>; +def CMASK16 : VISInstFormat<0b000011101, (outs), (ins I64Regs:$rs2), + "cmask16 $rs2", []>; +def CMASK32 : VISInstFormat<0b000011111, (outs), (ins I64Regs:$rs2), + "cmask32 $rs2", []>; + +} + +def FCHKSM16 : VISInst<0b01000100, "fchksm16">; + +def FHADDS : F3_3<0b10, 0b110100, 0b001100001, + (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fhadds $rs1, $rs2, $rd", []>; +def FHADDD : F3_3<0b10, 0b110100, 0b001100010, + (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fhaddd $rs1, $rs2, $rd", []>; +def FHSUBS : F3_3<0b10, 0b110100, 0b001100101, + (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fhsubs $rs1, $rs2, $rd", []>; +def FHSUBD : F3_3<0b10, 0b110100, 0b001100110, + (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fhsubd $rs1, $rs2, $rd", []>; +def FLCMPS : VISInstFormat<0b101010001, (outs FCCRegs:$rd), + (ins DFPRegs:$rs1, DFPRegs:$rs2), + "flcmps $rd, $rs1, $rs2", []>; +def FLCMPD : VISInstFormat<0b101010010, (outs FCCRegs:$rd), + (ins DFPRegs:$rs1, DFPRegs:$rs2), + "flcmpd $rd, $rs1, $rs2", []>; + +def FMEAN16 : VISInst<0b001000000, "fmean16">; + +def FNADDS : F3_3<0b10, 0b110100, 0b001010001, + (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fnadds $rs1, $rs2, $rd", []>; +def FNADDD : F3_3<0b10, 0b110100, 0b001010010, + (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fnaddd $rs1, $rs2, $rd", []>; +def FNHADDS : F3_3<0b10, 0b110100, 0b001110001, + (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fnhadds $rs1, $rs2, $rd", []>; +def FNHADDD : F3_3<0b10, 0b110100, 0b001110010, + (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fnhaddd $rs1, $rs2, $rd", []>; + +def FNMULS : F3_3<0b10, 0b110100, 0b001011001, + (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fnhadds $rs1, $rs2, $rd", []>; +def FNMULD : F3_3<0b10, 0b110100, 0b001011010, + (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fnhaddd $rs1, $rs2, $rd", []>; +def FNSMULD : F3_3<0b10, 0b110100, 0b001111001, + (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), + "fnhadds $rs1, $rs2, $rd", []>; + +def FPADD64 : VISInst<0b001000010, "fpadd64">; + +def FSLL16 : VISInst<0b00100001, "fsll16">; +def FSRL16 : VISInst<0b00100011, "fsrl16">; +def FSLL32 : VISInst<0b00100101, "fsll32">; +def FSRL32 : VISInst<0b00100111, "fsrl32">; +def FSLAS16 : VISInst<0b00101001, "fslas16">; +def FSRA16 : VISInst<0b00101011, "fsra16">; +def FSLAS32 : VISInst<0b00101101, "fslas32">; +def FSRA32 : VISInst<0b00101111, "fsra32">; + +let rs1 = 0 in +def LZCNT : VISInstFormat<0b000010111, (outs I64Regs:$rd), + (ins I64Regs:$rs2), "lzcnt $rs2, $rd", []>; + +let rs1 = 0 in { +def MOVSTOSW : VISInstFormat<0b100010011, (outs I64Regs:$rd), + (ins DFPRegs:$rs2), "movstosw $rs2, $rd", []>; +def MOVSTOUW : VISInstFormat<0b100010001, (outs I64Regs:$rd), + (ins DFPRegs:$rs2), "movstouw $rs2, $rd", []>; +def MOVDTOX : VISInstFormat<0b100010000, (outs I64Regs:$rd), + (ins DFPRegs:$rs2), "movdtox $rs2, $rd", []>; +def MOVWTOS : VISInstFormat<0b100011001, (outs DFPRegs:$rd), + (ins I64Regs:$rs2), "movdtox $rs2, $rd", []>; +def MOVXTOD : VISInstFormat<0b100011000, (outs DFPRegs:$rd), + (ins I64Regs:$rs2), "movdtox $rs2, $rd", []>; +} + +def PDISTN : VISInst<0b000111111, "pdistn">; + +def UMULXHI : VISInst<0b000010110, "umulxhi", I64Regs>; +def XMULX : VISInst<0b100010101, "xmulx", I64Regs>; +def XMULXHI : VISInst<0b100010111, "xmulxhi", I64Regs>; +} // Predicates = [IsVIS3] diff --git a/contrib/llvm/lib/Target/Sparc/SparcJITInfo.cpp b/contrib/llvm/lib/Target/Sparc/SparcJITInfo.cpp index 959d12f712b1..d0eec98b5e91 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcJITInfo.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcJITInfo.cpp @@ -10,7 +10,6 @@ // This file implements the JIT interfaces for the Sparc target. // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "jit" #include "SparcJITInfo.h" #include "Sparc.h" #include "SparcRelocations.h" @@ -20,6 +19,8 @@ using namespace llvm; +#define DEBUG_TYPE "jit" + /// JITCompilerFunction - This contains the address of the JIT function used to /// compile a function lazily. static TargetJITInfo::JITCompilerFn JITCompilerFunction; @@ -212,7 +213,8 @@ extern "C" void *SparcCompilationCallbackC(intptr_t StubAddr) { void SparcJITInfo::replaceMachineCodeForFunction(void *Old, void *New) { - assert(0 && "FIXME: Implement SparcJITInfo::replaceMachineCodeForFunction"); + llvm_unreachable("FIXME: Implement SparcJITInfo::" + "replaceMachineCodeForFunction"); } diff --git a/contrib/llvm/lib/Target/Sparc/SparcJITInfo.h b/contrib/llvm/lib/Target/Sparc/SparcJITInfo.h index 9c6e488e4886..ff1b43a7f6aa 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcJITInfo.h +++ b/contrib/llvm/lib/Target/Sparc/SparcJITInfo.h @@ -34,27 +34,27 @@ class SparcJITInfo : public TargetJITInfo { /// overwriting OLD with a branch to NEW. This is used for self-modifying /// code. /// - virtual void replaceMachineCodeForFunction(void *Old, void *New); + void replaceMachineCodeForFunction(void *Old, void *New) override; // getStubLayout - Returns the size and alignment of the largest call stub // on Sparc. - virtual StubLayout getStubLayout(); + StubLayout getStubLayout() override; /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a /// small native function that simply calls the function at the specified /// address. - virtual void *emitFunctionStub(const Function *F, void *Fn, - JITCodeEmitter &JCE); + void *emitFunctionStub(const Function *F, void *Fn, + JITCodeEmitter &JCE) override; /// getLazyResolverFunction - Expose the lazy resolver to the JIT. - virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn); + LazyResolverFn getLazyResolverFunction(JITCompilerFn) override; /// relocate - Before the JIT can run a block of code that has been emitted, /// it must rewrite the code to contain the actual addresses of any /// referenced global symbols. - virtual void relocate(void *Function, MachineRelocation *MR, - unsigned NumRelocs, unsigned char *GOTBase); + void relocate(void *Function, MachineRelocation *MR, + unsigned NumRelocs, unsigned char *GOTBase) override; /// Initialize - Initialize internal stage for the function being JITted. void Initialize(const MachineFunction &MF, bool isPIC) { diff --git a/contrib/llvm/lib/Target/Sparc/SparcMCInstLower.cpp b/contrib/llvm/lib/Target/Sparc/SparcMCInstLower.cpp index fc3ba9057103..9e94d2c3140c 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcMCInstLower.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcMCInstLower.cpp @@ -14,16 +14,16 @@ #include "Sparc.h" #include "MCTargetDesc/SparcMCExpr.h" +#include "llvm/ADT/SmallString.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineOperand.h" -#include "llvm/MC/MCContext.h" +#include "llvm/IR/Mangler.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" -#include "llvm/Target/Mangler.h" -#include "llvm/ADT/SmallString.h" using namespace llvm; @@ -34,7 +34,7 @@ static MCOperand LowerSymbolOperand(const MachineInstr *MI, SparcMCExpr::VariantKind Kind = (SparcMCExpr::VariantKind)MO.getTargetFlags(); - const MCSymbol *Symbol = 0; + const MCSymbol *Symbol = nullptr; switch(MO.getType()) { default: llvm_unreachable("Unknown type in LowerSymbolOperand"); diff --git a/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp b/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp index f222382a6bc4..dc1ec7c9d6b4 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp @@ -25,11 +25,11 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetInstrInfo.h" +using namespace llvm; + #define GET_REGINFO_TARGET_DESC #include "SparcGenRegisterInfo.inc" -using namespace llvm; - static cl::opt<bool> ReserveAppRegisters("sparc-reserve-app-registers", cl::Hidden, cl::init(false), cl::desc("Reserve application registers (%g2-%g4)")); @@ -38,8 +38,8 @@ SparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st) : SparcGenRegisterInfo(SP::O7), Subtarget(st) { } -const uint16_t* SparcRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) - const { +const MCPhysReg* +SparcRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { return CSR_SaveList; } diff --git a/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.h b/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.h index 00b5a98dd79f..77f879a8beca 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.h +++ b/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.h @@ -31,25 +31,26 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo { SparcRegisterInfo(SparcSubtarget &st); /// Code Generation virtual methods... - const uint16_t *getCalleeSavedRegs(const MachineFunction *MF = 0) const; - const uint32_t* getCallPreservedMask(CallingConv::ID CC) const; + const MCPhysReg * + getCalleeSavedRegs(const MachineFunction *MF =nullptr) const override; + const uint32_t* getCallPreservedMask(CallingConv::ID CC) const override; const uint32_t* getRTCallPreservedMask(CallingConv::ID CC) const; - BitVector getReservedRegs(const MachineFunction &MF) const; + BitVector getReservedRegs(const MachineFunction &MF) const override; const TargetRegisterClass *getPointerRegClass(const MachineFunction &MF, - unsigned Kind) const; + unsigned Kind) const override; void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, - RegScavenger *RS = NULL) const; + RegScavenger *RS = nullptr) const override; void processFunctionBeforeFrameFinalized(MachineFunction &MF, - RegScavenger *RS = NULL) const; + RegScavenger *RS = nullptr) const; // Debug information queries. - unsigned getFrameRegister(const MachineFunction &MF) const; + unsigned getFrameRegister(const MachineFunction &MF) const override; }; } // end namespace llvm diff --git a/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.td b/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.td index 2a575c05a952..2cadff1ef7bb 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.td +++ b/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.td @@ -16,7 +16,8 @@ class SparcReg<bits<16> Enc, string n> : Register<n> { let Namespace = "SP"; } -class SparcCtrlReg<string n>: Register<n> { +class SparcCtrlReg<bits<16> Enc, string n>: Register<n> { + let HWEncoding = Enc; let Namespace = "SP"; } @@ -49,11 +50,12 @@ class Rq<bits<16> Enc, string n, list<Register> subregs> : SparcReg<Enc, n> { } // Control Registers -def ICC : SparcCtrlReg<"ICC">; // This represents icc and xcc in 64-bit code. -def FCC : SparcCtrlReg<"FCC">; +def ICC : SparcCtrlReg<0, "ICC">; // This represents icc and xcc in 64-bit code. +foreach I = 0-3 in + def FCC#I : SparcCtrlReg<I, "FCC"#I>; // Y register -def Y : SparcCtrlReg<"Y">; +def Y : SparcCtrlReg<0, "Y">, DwarfRegNum<[64]>; // Integer registers def G0 : Ri< 0, "G0">, DwarfRegNum<[0]>; @@ -204,3 +206,6 @@ def FPRegs : RegisterClass<"SP", [f32], 32, (sequence "F%u", 0, 31)>; def DFPRegs : RegisterClass<"SP", [f64], 64, (sequence "D%u", 0, 31)>; def QFPRegs : RegisterClass<"SP", [f128], 128, (sequence "Q%u", 0, 15)>; + +// Floating point control register classes. +def FCCRegs : RegisterClass<"SP", [i1], 1, (sequence "FCC%u", 0, 3)>; diff --git a/contrib/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.cpp b/contrib/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.cpp index 190c575a52de..a308fc5e739e 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.cpp @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sparc-selectiondag-info" -#include "SparcTargetMachine.h" +#include "SparcSelectionDAGInfo.h" using namespace llvm; -SparcSelectionDAGInfo::SparcSelectionDAGInfo(const SparcTargetMachine &TM) - : TargetSelectionDAGInfo(TM) { +#define DEBUG_TYPE "sparc-selectiondag-info" + +SparcSelectionDAGInfo::SparcSelectionDAGInfo(const DataLayout &DL) + : TargetSelectionDAGInfo(&DL) { } SparcSelectionDAGInfo::~SparcSelectionDAGInfo() { diff --git a/contrib/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.h b/contrib/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.h index dcd42037253d..2346f4109dcb 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.h +++ b/contrib/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.h @@ -22,7 +22,7 @@ class SparcTargetMachine; class SparcSelectionDAGInfo : public TargetSelectionDAGInfo { public: - explicit SparcSelectionDAGInfo(const SparcTargetMachine &TM); + explicit SparcSelectionDAGInfo(const DataLayout &DL); ~SparcSelectionDAGInfo(); }; diff --git a/contrib/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/contrib/llvm/lib/Target/Sparc/SparcSubtarget.cpp index 6fc9d5638488..eea0c8c33c6a 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcSubtarget.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcSubtarget.cpp @@ -16,28 +16,54 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/TargetRegistry.h" +using namespace llvm; + +#define DEBUG_TYPE "sparc-subtarget" + #define GET_SUBTARGETINFO_TARGET_DESC #define GET_SUBTARGETINFO_CTOR #include "SparcGenSubtargetInfo.inc" -using namespace llvm; - void SparcSubtarget::anchor() { } -SparcSubtarget::SparcSubtarget(const std::string &TT, const std::string &CPU, - const std::string &FS, bool is64Bit) : - SparcGenSubtargetInfo(TT, CPU, FS), - IsV9(false), - V8DeprecatedInsts(false), - IsVIS(false), - Is64Bit(is64Bit), - HasHardQuad(false), - UsePopc(false) { +static std::string computeDataLayout(const SparcSubtarget &ST) { + // Sparc is big endian. + std::string Ret = "E-m:e"; + + // Some ABIs have 32bit pointers. + if (!ST.is64Bit()) + Ret += "-p:32:32"; + + // Alignments for 64 bit integers. + Ret += "-i64:64"; + + // On SparcV9 128 floats are aligned to 128 bits, on others only to 64. + // On SparcV9 registers can hold 64 or 32 bits, on others only 32. + if (ST.is64Bit()) + Ret += "-n32:64"; + else + Ret += "-f128:64-n32"; + + if (ST.is64Bit()) + Ret += "-S128"; + else + Ret += "-S64"; + + return Ret; +} + +SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU, + StringRef FS) { + IsV9 = false; + V8DeprecatedInsts = false; + IsVIS = false; + HasHardQuad = false; + UsePopc = false; // Determine default and user specified characteristics std::string CPUName = CPU; if (CPUName.empty()) - CPUName = (is64Bit) ? "v9" : "v8"; + CPUName = (Is64Bit) ? "v9" : "v8"; // Parse features string. ParseSubtargetFeatures(CPUName, FS); @@ -45,8 +71,16 @@ SparcSubtarget::SparcSubtarget(const std::string &TT, const std::string &CPU, // Popc is a v9-only instruction. if (!IsV9) UsePopc = false; + + return *this; } +SparcSubtarget::SparcSubtarget(const std::string &TT, const std::string &CPU, + const std::string &FS, TargetMachine &TM, + bool is64Bit) + : SparcGenSubtargetInfo(TT, CPU, FS), Is64Bit(is64Bit), + DL(computeDataLayout(initializeSubtargetDependencies(CPU, FS))), + InstrInfo(*this), TLInfo(TM), TSInfo(DL), FrameLowering(*this) {} int SparcSubtarget::getAdjustedFrameSize(int frameSize) const { diff --git a/contrib/llvm/lib/Target/Sparc/SparcSubtarget.h b/contrib/llvm/lib/Target/Sparc/SparcSubtarget.h index e4239e2a745d..a3357786cded 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcSubtarget.h +++ b/contrib/llvm/lib/Target/Sparc/SparcSubtarget.h @@ -14,6 +14,13 @@ #ifndef SPARC_SUBTARGET_H #define SPARC_SUBTARGET_H +#include "SparcFrameLowering.h" +#include "SparcInstrInfo.h" +#include "SparcISelLowering.h" +#include "SparcJITInfo.h" +#include "SparcSelectionDAGInfo.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetSubtargetInfo.h" #include <string> @@ -27,17 +34,35 @@ class SparcSubtarget : public SparcGenSubtargetInfo { virtual void anchor(); bool IsV9; bool V8DeprecatedInsts; - bool IsVIS; + bool IsVIS, IsVIS2, IsVIS3; bool Is64Bit; bool HasHardQuad; bool UsePopc; + const DataLayout DL; // Calculates type size & alignment + SparcInstrInfo InstrInfo; + SparcTargetLowering TLInfo; + SparcSelectionDAGInfo TSInfo; + SparcFrameLowering FrameLowering; + SparcJITInfo JITInfo; public: SparcSubtarget(const std::string &TT, const std::string &CPU, - const std::string &FS, bool is64bit); + const std::string &FS, TargetMachine &TM, bool is64bit); + + const SparcInstrInfo *getInstrInfo() const { return &InstrInfo; } + const TargetFrameLowering *getFrameLowering() const { return &FrameLowering; } + const SparcRegisterInfo *getRegisterInfo() const { + return &InstrInfo.getRegisterInfo(); + } + const SparcTargetLowering *getTargetLowering() const { return &TLInfo; } + const SparcSelectionDAGInfo *getSelectionDAGInfo() const { return &TSInfo; } + SparcJITInfo *getJITInfo() { return &JITInfo; } + const DataLayout *getDataLayout() const { return &DL; } bool isV9() const { return IsV9; } bool isVIS() const { return IsVIS; } + bool isVIS2() const { return IsVIS2; } + bool isVIS3() const { return IsVIS3; } bool useDeprecatedV8Instructions() const { return V8DeprecatedInsts; } bool hasHardQuad() const { return HasHardQuad; } bool usePopc() const { return UsePopc; } @@ -45,17 +70,9 @@ public: /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. void ParseSubtargetFeatures(StringRef CPU, StringRef FS); + SparcSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); bool is64Bit() const { return Is64Bit; } - std::string getDataLayout() const { - const char *p; - if (is64Bit()) { - p = "E-p:64:64:64-i64:64:64-f64:64:64-f128:128:128-n32:64"; - } else { - p = "E-p:32:32:32-i64:64:64-f64:64:64-f128:64:64-n32"; - } - return std::string(p); - } /// The 64-bit ABI uses biased stack and frame pointers, so the stack frame /// of the current function is the area from [%sp+BIAS] to [%fp+BIAS]. diff --git a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp index 0f936747cfed..0130face3ff6 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp @@ -32,11 +32,7 @@ SparcTargetMachine::SparcTargetMachine(const Target &T, StringRef TT, CodeGenOpt::Level OL, bool is64bit) : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), - Subtarget(TT, CPU, FS, is64bit), - DL(Subtarget.getDataLayout()), - InstrInfo(Subtarget), - TLInfo(*this), TSInfo(*this), - FrameLowering(Subtarget) { + Subtarget(TT, CPU, FS, *this, is64bit) { initAsmInfo(); } @@ -51,8 +47,8 @@ public: return getTM<SparcTargetMachine>(); } - virtual bool addInstSelector(); - virtual bool addPreEmitPass(); + bool addInstSelector() override; + bool addPreEmitPass() override; }; } // namespace diff --git a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.h b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.h index 8c9bcd36bf33..03b513746dfe 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.h +++ b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.h @@ -14,54 +14,44 @@ #ifndef SPARCTARGETMACHINE_H #define SPARCTARGETMACHINE_H -#include "SparcFrameLowering.h" -#include "SparcISelLowering.h" #include "SparcInstrInfo.h" -#include "SparcJITInfo.h" -#include "SparcSelectionDAGInfo.h" #include "SparcSubtarget.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetMachine.h" namespace llvm { class SparcTargetMachine : public LLVMTargetMachine { SparcSubtarget Subtarget; - const DataLayout DL; // Calculates type size & alignment - SparcInstrInfo InstrInfo; - SparcTargetLowering TLInfo; - SparcSelectionDAGInfo TSInfo; - SparcFrameLowering FrameLowering; - SparcJITInfo JITInfo; public: SparcTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL, bool is64bit); - virtual const SparcInstrInfo *getInstrInfo() const { return &InstrInfo; } - virtual const TargetFrameLowering *getFrameLowering() const { - return &FrameLowering; + const SparcInstrInfo *getInstrInfo() const override { + return getSubtargetImpl()->getInstrInfo(); } - virtual const SparcSubtarget *getSubtargetImpl() const{ return &Subtarget; } - virtual const SparcRegisterInfo *getRegisterInfo() const { - return &InstrInfo.getRegisterInfo(); + const TargetFrameLowering *getFrameLowering() const override { + return getSubtargetImpl()->getFrameLowering(); } - virtual const SparcTargetLowering* getTargetLowering() const { - return &TLInfo; + const SparcSubtarget *getSubtargetImpl() const override { return &Subtarget; } + const SparcRegisterInfo *getRegisterInfo() const override { + return getSubtargetImpl()->getRegisterInfo(); } - virtual const SparcSelectionDAGInfo* getSelectionDAGInfo() const { - return &TSInfo; + const SparcTargetLowering *getTargetLowering() const override { + return getSubtargetImpl()->getTargetLowering(); } - virtual SparcJITInfo *getJITInfo() { - return &JITInfo; + const SparcSelectionDAGInfo *getSelectionDAGInfo() const override { + return getSubtargetImpl()->getSelectionDAGInfo(); + } + SparcJITInfo *getJITInfo() override { return Subtarget.getJITInfo(); } + const DataLayout *getDataLayout() const override { + return getSubtargetImpl()->getDataLayout(); } - virtual const DataLayout *getDataLayout() const { return &DL; } // Pass Pipeline Configuration - virtual TargetPassConfig *createPassConfig(PassManagerBase &PM); - virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &JCE); + TargetPassConfig *createPassConfig(PassManagerBase &PM) override; + bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &JCE) override; }; /// SparcV8TargetMachine - Sparc 32-bit target machine diff --git a/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.cpp b/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.cpp index 18612bd0c26f..32b2240f87ea 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.cpp @@ -11,30 +11,25 @@ #include "MCTargetDesc/SparcMCExpr.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/Support/Dwarf.h" -#include "llvm/Target/Mangler.h" +#include "llvm/Target/TargetLowering.h" using namespace llvm; - -const MCExpr *SparcELFTargetObjectFile:: -getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI, unsigned Encoding, - MCStreamer &Streamer) const { +const MCExpr *SparcELFTargetObjectFile::getTTypeGlobalReference( + const GlobalValue *GV, unsigned Encoding, Mangler &Mang, + const TargetMachine &TM, MachineModuleInfo *MMI, + MCStreamer &Streamer) const { if (Encoding & dwarf::DW_EH_PE_pcrel) { MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); - //MCSymbol *SSym = getSymbolWithGlobalValueBase(*Mang, GV, ".DW.stub"); - SmallString<60> NameStr; - Mang->getNameWithPrefix(NameStr, GV, true); - NameStr.append(".DW.stub"); - MCSymbol *SSym = getContext().GetOrCreateSymbol(NameStr.str()); + MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", Mang, TM); // Add information about the stub reference to ELFMMI so that the stub // gets emitted by the asmprinter. MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); - if (StubSym.getPointer() == 0) { - MCSymbol *Sym = getSymbol(*Mang, GV); + if (!StubSym.getPointer()) { + MCSymbol *Sym = TM.getSymbol(GV, Mang); StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); } @@ -43,6 +38,6 @@ getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, MCSymbolRefExpr::Create(SSym, Ctx), Ctx); } - return TargetLoweringObjectFileELF:: - getTTypeGlobalReference(GV, Mang, MMI, Encoding, Streamer); + return TargetLoweringObjectFileELF::getTTypeGlobalReference( + GV, Encoding, Mang, TM, MMI, Streamer); } diff --git a/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.h b/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.h index 7cf850de1608..c60675b49459 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.h +++ b/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.h @@ -24,9 +24,10 @@ public: {} const MCExpr * - getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI, unsigned Encoding, - MCStreamer &Streamer) const; + getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding, + Mangler &Mang, const TargetMachine &TM, + MachineModuleInfo *MMI, + MCStreamer &Streamer) const override; }; } // end namespace llvm diff --git a/contrib/llvm/lib/Target/Sparc/SparcTargetStreamer.h b/contrib/llvm/lib/Target/Sparc/SparcTargetStreamer.h index 73339acf8dfa..3767d8e27b57 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcTargetStreamer.h +++ b/contrib/llvm/lib/Target/Sparc/SparcTargetStreamer.h @@ -18,6 +18,7 @@ class SparcTargetStreamer : public MCTargetStreamer { virtual void anchor(); public: + SparcTargetStreamer(MCStreamer &S); /// Emit ".register <reg>, #ignore". virtual void emitSparcRegisterIgnore(unsigned reg) = 0; /// Emit ".register <reg>, #scratch". @@ -29,18 +30,19 @@ class SparcTargetAsmStreamer : public SparcTargetStreamer { formatted_raw_ostream &OS; public: - SparcTargetAsmStreamer(formatted_raw_ostream &OS); - virtual void emitSparcRegisterIgnore(unsigned reg); - virtual void emitSparcRegisterScratch(unsigned reg); + SparcTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS); + void emitSparcRegisterIgnore(unsigned reg) override; + void emitSparcRegisterScratch(unsigned reg) override; }; // This part is for ELF object output class SparcTargetELFStreamer : public SparcTargetStreamer { public: + SparcTargetELFStreamer(MCStreamer &S); MCELFStreamer &getStreamer(); - virtual void emitSparcRegisterIgnore(unsigned reg) {} - virtual void emitSparcRegisterScratch(unsigned reg) {} + void emitSparcRegisterIgnore(unsigned reg) override {} + void emitSparcRegisterScratch(unsigned reg) override {} }; } // end namespace llvm |