diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Sparc')
25 files changed, 474 insertions, 1098 deletions
diff --git a/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp index b2003b8..e775aa6 100644 --- a/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ b/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -84,7 +84,7 @@ class SparcAsmParser : public MCTargetAsmParser { return getSTI().getTargetTriple().getArch() == Triple::sparcv9; } - void expandSET(MCInst &Inst, SMLoc IDLoc, + bool expandSET(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions); public: @@ -121,7 +121,7 @@ public: static const MCPhysReg DoubleRegs[32] = { Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3, Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7, - Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9, + Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11, Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15, Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19, Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23, @@ -466,7 +466,7 @@ public: } // end namespace -void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc, +bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) { MCOperand MCRegOp = Inst.getOperand(0); MCOperand MCValOp = Inst.getOperand(1); @@ -479,8 +479,8 @@ void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc, // Allow either a signed or unsigned 32-bit immediate. if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) { - Error(IDLoc, "set: argument must be between -2147483648 and 4294967295"); - return; + return Error(IDLoc, + "set: argument must be between -2147483648 and 4294967295"); } // If the value was expressed as a large unsigned number, that's ok. @@ -537,6 +537,7 @@ void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc, TmpInst.addOperand(MCOperand::createExpr(Expr)); Instructions.push_back(TmpInst); } + return false; } bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, @@ -556,7 +557,8 @@ bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, Instructions.push_back(Inst); break; case SP::SET: - expandSET(Inst, IDLoc, Instructions); + if (expandSET(Inst, IDLoc, Instructions)) + return true; break; } @@ -626,13 +628,11 @@ bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info, 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(); return Error(Loc, "unexpected token"); } @@ -645,14 +645,12 @@ bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info, // Parse and remember the operand. if (parseOperand(Operands, Name) != MatchOperand_Success) { SMLoc Loc = getLexer().getLoc(); - Parser.eatToEndOfStatement(); return Error(Loc, "unexpected token"); } } } if (getLexer().isNot(AsmToken::EndOfStatement)) { SMLoc Loc = getLexer().getLoc(); - Parser.eatToEndOfStatement(); return Error(Loc, "unexpected token"); } Parser.Lex(); // Consume the EndOfStatement. @@ -717,7 +715,7 @@ bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) { return false; } -SparcAsmParser::OperandMatchResultTy +OperandMatchResultTy SparcAsmParser::parseMEMOperand(OperandVector &Operands) { SMLoc S, E; @@ -755,7 +753,7 @@ SparcAsmParser::parseMEMOperand(OperandVector &Operands) { return MatchOperand_Success; } -SparcAsmParser::OperandMatchResultTy +OperandMatchResultTy SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); @@ -823,7 +821,7 @@ SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { return MatchOperand_Success; } -SparcAsmParser::OperandMatchResultTy +OperandMatchResultTy SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op, bool isCall) { @@ -910,7 +908,7 @@ SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op, return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; } -SparcAsmParser::OperandMatchResultTy +OperandMatchResultTy SparcAsmParser::parseBranchModifiers(OperandVector &Operands) { // parse (,a|,pn|,pt)+ @@ -1265,9 +1263,9 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal, } extern "C" void LLVMInitializeSparcAsmParser() { - RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget); - RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target); - RegisterMCAsmParser<SparcAsmParser> C(TheSparcelTarget); + RegisterMCAsmParser<SparcAsmParser> A(getTheSparcTarget()); + RegisterMCAsmParser<SparcAsmParser> B(getTheSparcV9Target()); + RegisterMCAsmParser<SparcAsmParser> C(getTheSparcelTarget()); } #define GET_REGISTER_MATCHER diff --git a/contrib/llvm/lib/Target/Sparc/DelaySlotFiller.cpp b/contrib/llvm/lib/Target/Sparc/DelaySlotFiller.cpp index 944f355..6f9cc31 100644 --- a/contrib/llvm/lib/Target/Sparc/DelaySlotFiller.cpp +++ b/contrib/llvm/lib/Target/Sparc/DelaySlotFiller.cpp @@ -43,9 +43,7 @@ namespace { static char ID; Filler() : MachineFunctionPass(ID) {} - const char *getPassName() const override { - return "SPARC Delay Slot Filler"; - } + StringRef getPassName() const override { return "SPARC Delay Slot Filler"; } bool runOnMachineBasicBlock(MachineBasicBlock &MBB); bool runOnMachineFunction(MachineFunction &F) override { @@ -64,7 +62,7 @@ namespace { MachineFunctionProperties getRequiredProperties() const override { return MachineFunctionProperties().set( - MachineFunctionProperties::Property::AllVRegsAllocated); + MachineFunctionProperties::Property::NoVRegs); } void insertCallDefsUses(MachineBasicBlock::iterator MI, diff --git a/contrib/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/contrib/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index 1dea379..da7e0b7 100644 --- a/contrib/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/contrib/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -44,7 +44,9 @@ public: } namespace llvm { -extern Target TheSparcTarget, TheSparcV9Target, TheSparcelTarget; +Target &getTheSparcTarget(); +Target &getTheSparcV9Target(); +Target &getTheSparcelTarget(); } static MCDisassembler *createSparcDisassembler(const Target &T, @@ -56,11 +58,11 @@ static MCDisassembler *createSparcDisassembler(const Target &T, extern "C" void LLVMInitializeSparcDisassembler() { // Register the disassembler. - TargetRegistry::RegisterMCDisassembler(TheSparcTarget, + TargetRegistry::RegisterMCDisassembler(getTheSparcTarget(), createSparcDisassembler); - TargetRegistry::RegisterMCDisassembler(TheSparcV9Target, + TargetRegistry::RegisterMCDisassembler(getTheSparcV9Target(), createSparcDisassembler); - TargetRegistry::RegisterMCDisassembler(TheSparcelTarget, + TargetRegistry::RegisterMCDisassembler(getTheSparcelTarget(), createSparcDisassembler); } diff --git a/contrib/llvm/lib/Target/Sparc/LeonFeatures.td b/contrib/llvm/lib/Target/Sparc/LeonFeatures.td index 63f8b33..d06e734 100755 --- a/contrib/llvm/lib/Target/Sparc/LeonFeatures.td +++ b/contrib/llvm/lib/Target/Sparc/LeonFeatures.td @@ -10,82 +10,73 @@ // //===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// CASA Support differs between LEON3-FT GR712RC and LEON3-FT UT699 -// We need to have the option to switch this on and off. -//===----------------------------------------------------------------------===// - -// support to casa instruction; for leon3 subtarget only -def LeonCASA : SubtargetFeature< - "hasleoncasa", "HasLeonCasa", "true", - "Enable CASA instruction for LEON3 and LEON4 processors">; //===----------------------------------------------------------------------===// // UMAC and SMAC support for LEON3 and LEON4 processors. //===----------------------------------------------------------------------===// -// support to casa instruction; for leon3 subtarget only -def UMACSMACSupport - : SubtargetFeature<"hasumacsmac", "HasUmacSmac", "true", - "Enable UMAC and SMAC for LEON3 and LEON4 processors">; +//support to casa instruction; for leon3 subtarget only +def UMACSMACSupport : SubtargetFeature< + "hasumacsmac", + "HasUmacSmac", + "true", + "Enable UMAC and SMAC for LEON3 and LEON4 processors" +>; + //===----------------------------------------------------------------------===// -// LEON Erratum fixes +// CASA Support differs between LEON3-FT GR712RC and LEON3-FT UT699 +// We need to have the option to switch this on and off. //===----------------------------------------------------------------------===// -def ReplaceSDIV - : SubtargetFeature< - "replacesdiv", "PerformSDIVReplace", "true", - "AT697E erratum fix: Do not emit SDIV, emit SDIVCC instead">; - -def FixCALL - : SubtargetFeature<"fixcall", "FixCallImmediates", "true", - "AT697E erratum fix: Restrict the size of the immediate " - "operand of the CALL instruction to 20 bits">; - -def IgnoreZeroFlag - : SubtargetFeature<"ignrzeroflag", "IgnoreZeroFlag", "true", - "AT697E erratum fix: Do not rely on the zero bit flag " - "on a divide overflow for SDIVCC and UDIVCC">; - -def InsertNOPDoublePrecision - : SubtargetFeature<"insrtnopdblprcsn", "InsertNOPDoublePrecision", "true", - "LEON2 erratum fix: Insert a NOP before the double " - "precision floating point instruction">; - -def FixFSMULD : SubtargetFeature<"fixfsmuld", "FixFSMULD", "true", - "LEON3 erratum fix: Do not select FSMULD">; - -def ReplaceFMULS - : SubtargetFeature<"replacefmuls", "ReplaceFMULS", "true", - "LEON3 erratum fix: Replace FMULS instruction with a " - "routine using conversions/double precision operations " - "to replace FMULS">; - -def PreventRoundChange - : SubtargetFeature<"prvntroundchange", "PreventRoundChange", "true", - "LEON3 erratum fix: Prevent any rounding mode change " - "request: use only the round-to-nearest rounding mode">; - -def FixAllFDIVSQRT - : SubtargetFeature<"fixallfdivsqrt", "FixAllFDIVSQRT", "true", - "LEON3 erratum fix: Fix FDIVS/FDIVD/FSQRTS/FSQRTD " - "instructions with NOPs and floating-point store">; - -def InsertNOPLoad - : SubtargetFeature<"insertnopload", "InsertNOPLoad", "true", - "LEON3 erratum fix: Insert a NOP instruction after " - "every single-cycle load instruction when the next " - "instruction is another load/store instruction">; - -def FlushCacheLineSWAP - : SubtargetFeature<"flshcachelineswap", "FlushCacheLineSWAP", "true", - "LEON3 erratum fix: Flush cache line containing the " - "lock before performing any of the atomic instructions " - "SWAP and LDSTUB">; - -def InsertNOPsLoadStore - : SubtargetFeature<"insertnopsloadstore", "InsertNOPsLoadStore", "true", - "LEON3 erratum fix: Insert NOPs between " - "single-precision loads and the store, so the number of " - "instructions between is 4">; +//support to casa instruction; for leon3 subtarget only +def LeonCASA : SubtargetFeature< + "hasleoncasa", + "HasLeonCasa", + "true", + "Enable CASA instruction for LEON3 and LEON4 processors" +>; + + +def ReplaceSDIV : SubtargetFeature< + "replacesdiv", + "PerformSDIVReplace", + "true", + "AT697E erratum fix: Do not emit SDIV, emit SDIVCC instead" +>; + +def InsertNOPLoad: SubtargetFeature< + "insertnopload", + "InsertNOPLoad", + "true", + "LEON3 erratum fix: Insert a NOP instruction after every single-cycle load instruction when the next instruction is another load/store instruction" +>; + +def FixFSMULD : SubtargetFeature< + "fixfsmuld", + "FixFSMULD", + "true", + "LEON erratum fix: Do not use FSMULD" +>; + +def ReplaceFMULS : SubtargetFeature< + "replacefmuls", + "ReplaceFMULS", + "true", + "LEON erratum fix: Replace FMULS instruction with FMULD and relevant conversion instructions" +>; + +def DetectRoundChange : SubtargetFeature< + "detectroundchange", + "DetectRoundChange", + "true", + "LEON3 erratum detection: Detects any rounding mode change " + "request: use only the round-to-nearest rounding mode" +>; + +def FixAllFDIVSQRT : SubtargetFeature< + "fixallfdivsqrt", + "FixAllFDIVSQRT", + "true", + "LEON erratum fix: Fix FDIVS/FDIVD/FSQRTS/FSQRTD instructions with NOPs and floating-point store" +>; diff --git a/contrib/llvm/lib/Target/Sparc/LeonPasses.cpp b/contrib/llvm/lib/Target/Sparc/LeonPasses.cpp index 5d09208..0acc287 100755 --- a/contrib/llvm/lib/Target/Sparc/LeonPasses.cpp +++ b/contrib/llvm/lib/Target/Sparc/LeonPasses.cpp @@ -16,6 +16,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/LLVMContext.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -51,8 +52,7 @@ int LEONMachineFunctionPass::GetRegIndexForOperand(MachineInstr &MI, int LEONMachineFunctionPass::getUnusedFPRegister(MachineRegisterInfo &MRI) { for (int RegisterIndex = SP::F0; RegisterIndex <= SP::F31; ++RegisterIndex) { if (!MRI.isPhysRegUsed(RegisterIndex) && - !(std::find(UsedRegisters.begin(), UsedRegisters.end(), - RegisterIndex) != UsedRegisters.end())) { + !is_contained(UsedRegisters, RegisterIndex)) { return RegisterIndex; } } @@ -90,15 +90,6 @@ bool InsertNOPLoad::runOnMachineFunction(MachineFunction &MF) { MachineBasicBlock::iterator NMBBI = std::next(MBBI); BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); Modified = true; - } else if (MI.isInlineAsm()) { - // Look for an inline ld or ldf instruction. - StringRef AsmString = - MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); - if (AsmString.startswith_lower("ld")) { - MachineBasicBlock::iterator NMBBI = std::next(MBBI); - BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); - Modified = true; - } } } } @@ -148,29 +139,6 @@ bool FixFSMULD::runOnMachineFunction(MachineFunction &MF) { Reg1Index = MI.getOperand(0).getReg(); Reg2Index = MI.getOperand(1).getReg(); Reg3Index = MI.getOperand(2).getReg(); - } else if (MI.isInlineAsm()) { - StringRef AsmString = - MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); - if (AsmString.startswith_lower("fsmuld")) { - // this is an inline FSMULD instruction - - unsigned StartOp = InlineAsm::MIOp_FirstOperand; - - // extracts the registers from the inline assembly instruction - for (unsigned i = StartOp, e = MI.getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI.getOperand(i); - if (MO.isReg()) { - if (Reg1Index == UNASSIGNED_INDEX) - Reg1Index = MO.getReg(); - else if (Reg2Index == UNASSIGNED_INDEX) - Reg2Index = MO.getReg(); - else if (Reg3Index == UNASSIGNED_INDEX) - Reg3Index = MO.getReg(); - } - if (Reg3Index != UNASSIGNED_INDEX) - break; - } - } } if (Reg1Index != UNASSIGNED_INDEX && Reg2Index != UNASSIGNED_INDEX && @@ -260,28 +228,6 @@ bool ReplaceFMULS::runOnMachineFunction(MachineFunction &MF) { Reg1Index = MI.getOperand(0).getReg(); Reg2Index = MI.getOperand(1).getReg(); Reg3Index = MI.getOperand(2).getReg(); - } else if (MI.isInlineAsm()) { - StringRef AsmString = - MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); - if (AsmString.startswith_lower("fmuls")) { - // this is an inline FMULS instruction - unsigned StartOp = InlineAsm::MIOp_FirstOperand; - - // extracts the registers from the inline assembly instruction - for (unsigned i = StartOp, e = MI.getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI.getOperand(i); - if (MO.isReg()) { - if (Reg1Index == UNASSIGNED_INDEX) - Reg1Index = MO.getReg(); - else if (Reg2Index == UNASSIGNED_INDEX) - Reg2Index = MO.getReg(); - else if (Reg3Index == UNASSIGNED_INDEX) - Reg3Index = MO.getReg(); - } - if (Reg3Index != UNASSIGNED_INDEX) - break; - } - } } if (Reg1Index != UNASSIGNED_INDEX && Reg2Index != UNASSIGNED_INDEX && @@ -329,391 +275,22 @@ bool ReplaceFMULS::runOnMachineFunction(MachineFunction &MF) { return Modified; } -//***************************************************************************** -//**** FixAllFDIVSQRT pass -//***************************************************************************** -// This pass fixes the incorrectly working FDIVx and FSQRTx instructions that -// exist for some earlier versions of the LEON processor line. Five NOP -// instructions need to be inserted after these instructions to ensure the -// correct result is placed in the destination registers before they are used. -// -// This pass implements two fixes: -// 1) fixing the FSQRTS and FSQRTD instructions. -// 2) fixing the FDIVS and FDIVD instructions. -// -// FSQRTS and FDIVS are converted to FDIVD and FSQRTD respectively earlier in -// the pipeline when this option is enabled, so this pass needs only to deal -// with the changes that still need implementing for the "double" versions -// of these instructions. -// -char FixAllFDIVSQRT::ID = 0; - -FixAllFDIVSQRT::FixAllFDIVSQRT(TargetMachine &tm) - : LEONMachineFunctionPass(tm, ID) {} - -bool FixAllFDIVSQRT::runOnMachineFunction(MachineFunction &MF) { - Subtarget = &MF.getSubtarget<SparcSubtarget>(); - const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); - DebugLoc DL = DebugLoc(); - - bool Modified = false; - for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { - MachineBasicBlock &MBB = *MFI; - for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { - MachineInstr &MI = *MBBI; - unsigned Opcode = MI.getOpcode(); - - if (MI.isInlineAsm()) { - StringRef AsmString = - MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); - if (AsmString.startswith_lower("fsqrtd")) { - // this is an inline fsqrts instruction - Opcode = SP::FSQRTD; - } else if (AsmString.startswith_lower("fdivd")) { - // this is an inline fsqrts instruction - Opcode = SP::FDIVD; - } - } - - // Note: FDIVS and FSQRTS cannot be generated when this erratum fix is - // switched on so we don't need to check for them here. They will - // already have been converted to FSQRTD or FDIVD earlier in the - // pipeline. - if (Opcode == SP::FSQRTD || Opcode == SP::FDIVD) { - // Insert 5 NOPs before FSQRTD,FDIVD. - for (int InsertedCount = 0; InsertedCount < 5; InsertedCount++) - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - - MachineBasicBlock::iterator NMBBI = std::next(MBBI); - // ... and inserting 28 NOPs after FSQRTD,FDIVD. - for (int InsertedCount = 0; InsertedCount < 28; InsertedCount++) - BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); - - Modified = true; - } - } - } - - return Modified; -} - -//***************************************************************************** -//**** ReplaceSDIV pass -//***************************************************************************** -// This pass fixes the incorrectly working SDIV instruction that -// exist for some earlier versions of the LEON processor line. The instruction -// is replaced with an SDIVcc instruction instead, which is working. -// -char ReplaceSDIV::ID = 0; - -ReplaceSDIV::ReplaceSDIV() : LEONMachineFunctionPass(ID) {} - -ReplaceSDIV::ReplaceSDIV(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {} - -bool ReplaceSDIV::runOnMachineFunction(MachineFunction &MF) { - Subtarget = &MF.getSubtarget<SparcSubtarget>(); - const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); - - bool Modified = false; - for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { - MachineBasicBlock &MBB = *MFI; - for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { - MachineInstr &MI = *MBBI; - unsigned Opcode = MI.getOpcode(); - if (Opcode == SP::SDIVrr) { - MI.setDesc(TII.get(SP::SDIVCCrr)); - Modified = true; - } else if (Opcode == SP::SDIVri) { - MI.setDesc(TII.get(SP::SDIVCCri)); - Modified = true; - } - } - } - - return Modified; -} - -static RegisterPass<ReplaceSDIV> X("replace-sdiv", "Replase SDIV Pass", false, - false); - -//***************************************************************************** -//**** FixCALL pass -//***************************************************************************** -// This pass restricts the size of the immediate operand of the CALL -// instruction, which can cause problems on some earlier versions of the LEON -// processor, which can interpret some of the call address bits incorrectly. -// -char FixCALL::ID = 0; - -FixCALL::FixCALL(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {} - -bool FixCALL::runOnMachineFunction(MachineFunction &MF) { - bool Modified = false; - - for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { - MachineBasicBlock &MBB = *MFI; - for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { - MachineInstr &MI = *MBBI; - MI.print(errs()); - errs() << "\n"; - - unsigned Opcode = MI.getOpcode(); - if (Opcode == SP::CALL || Opcode == SP::CALLrr) { - unsigned NumOperands = MI.getNumOperands(); - for (unsigned OperandIndex = 0; OperandIndex < NumOperands; - OperandIndex++) { - MachineOperand &MO = MI.getOperand(OperandIndex); - if (MO.isImm()) { - int64_t Value = MO.getImm(); - MO.setImm(Value & 0x000fffffL); - Modified = true; - break; - } - } - } else if (MI.isInlineAsm()) // inline assembly immediate call - { - StringRef AsmString = - MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); - if (AsmString.startswith_lower("call")) { - // this is an inline call instruction - unsigned StartOp = InlineAsm::MIOp_FirstOperand; - - // extracts the registers from the inline assembly instruction - for (unsigned i = StartOp, e = MI.getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI.getOperand(i); - if (MO.isImm()) { - int64_t Value = MO.getImm(); - MO.setImm(Value & 0x000fffffL); - Modified = true; - } - } - } - } - } - } - - return Modified; -} - -//***************************************************************************** -//**** IgnoreZeroFlag pass -//***************************************************************************** -// This erratum fix fixes the overflow behavior of SDIVCC and UDIVCC -// instructions that exists on some earlier LEON processors. Where these -// instructions are detected, they are replaced by a sequence that will -// explicitly write the overflow bit flag if this is required. -// -char IgnoreZeroFlag::ID = 0; - -IgnoreZeroFlag::IgnoreZeroFlag(TargetMachine &tm) - : LEONMachineFunctionPass(tm, ID) {} - -bool IgnoreZeroFlag::runOnMachineFunction(MachineFunction &MF) { - Subtarget = &MF.getSubtarget<SparcSubtarget>(); - const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); - DebugLoc DL = DebugLoc(); - - bool Modified = false; - for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { - MachineBasicBlock &MBB = *MFI; - for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { - MachineInstr &MI = *MBBI; - unsigned Opcode = MI.getOpcode(); - if (Opcode == SP::SDIVCCrr || Opcode == SP::SDIVCCri || - Opcode == SP::UDIVCCrr || Opcode == SP::UDIVCCri) { - - // split the current machine basic block - just after the sdivcc/udivcc - // instruction - // create a label that help us skip the zero flag update (of PSR - - // Processor Status Register) - // if conditions are not met - const BasicBlock *LLVM_BB = MBB.getBasicBlock(); - MachineFunction::iterator It = - std::next(MachineFunction::iterator(MBB)); - - MachineBasicBlock *dneBB = MF.CreateMachineBasicBlock(LLVM_BB); - MF.insert(It, dneBB); - - // Transfer the remainder of MBB and its successor edges to dneBB. - dneBB->splice(dneBB->begin(), &MBB, - std::next(MachineBasicBlock::iterator(MI)), MBB.end()); - dneBB->transferSuccessorsAndUpdatePHIs(&MBB); - - MBB.addSuccessor(dneBB); - - MachineBasicBlock::iterator NextMBBI = std::next(MBBI); - - // bvc - branch if overflow flag not set - BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND)) - .addMBB(dneBB) - .addImm(SPCC::ICC_VS); - - // bnz - branch if not zero - BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND)) - .addMBB(dneBB) - .addImm(SPCC::ICC_NE); - - // use the WRPSR (Write Processor State Register) instruction to set the - // zeo flag to 1 - // create wr %g0, 1, %psr - BuildMI(MBB, NextMBBI, DL, TII.get(SP::WRPSRri)) - .addReg(SP::G0) - .addImm(1); - - BuildMI(MBB, NextMBBI, DL, TII.get(SP::NOP)); - - Modified = true; - } else if (MI.isInlineAsm()) { - StringRef AsmString = - MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); - if (AsmString.startswith_lower("sdivcc") || - AsmString.startswith_lower("udivcc")) { - // this is an inline SDIVCC or UDIVCC instruction - - // split the current machine basic block - just after the - // sdivcc/udivcc instruction - // create a label that help us skip the zero flag update (of PSR - - // Processor Status Register) - // if conditions are not met - const BasicBlock *LLVM_BB = MBB.getBasicBlock(); - MachineFunction::iterator It = - std::next(MachineFunction::iterator(MBB)); - - MachineBasicBlock *dneBB = MF.CreateMachineBasicBlock(LLVM_BB); - MF.insert(It, dneBB); - - // Transfer the remainder of MBB and its successor edges to dneBB. - dneBB->splice(dneBB->begin(), &MBB, - std::next(MachineBasicBlock::iterator(MI)), MBB.end()); - dneBB->transferSuccessorsAndUpdatePHIs(&MBB); - - MBB.addSuccessor(dneBB); - - MachineBasicBlock::iterator NextMBBI = std::next(MBBI); - - // bvc - branch if overflow flag not set - BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND)) - .addMBB(dneBB) - .addImm(SPCC::ICC_VS); - - // bnz - branch if not zero - BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND)) - .addMBB(dneBB) - .addImm(SPCC::ICC_NE); - - // use the WRPSR (Write Processor State Register) instruction to set - // the zeo flag to 1 - // create wr %g0, 1, %psr - BuildMI(MBB, NextMBBI, DL, TII.get(SP::WRPSRri)) - .addReg(SP::G0) - .addImm(1); - - BuildMI(MBB, NextMBBI, DL, TII.get(SP::NOP)); - - Modified = true; - } - } - } - } - - return Modified; -} - -//***************************************************************************** -//**** InsertNOPDoublePrecision pass -//***************************************************************************** -// This erratum fix for some earlier LEON processors fixes a problem where a -// double precision load will not yield the correct result if used in FMUL, -// FDIV, FADD, FSUB or FSQRT instructions later. If this sequence is detected, -// inserting a NOP between the two instructions will fix the erratum. -// 1.scans the code after register allocation; -// 2.checks for the problem conditions as described in the AT697E erratum -// “Odd-Numbered FPU Register Dependency not Properly Checked in some -// Double-Precision FPU Operations”; -// 3.inserts NOPs if the problem exists. -// -char InsertNOPDoublePrecision::ID = 0; - -InsertNOPDoublePrecision::InsertNOPDoublePrecision(TargetMachine &tm) - : LEONMachineFunctionPass(tm, ID) {} - -bool InsertNOPDoublePrecision::runOnMachineFunction(MachineFunction &MF) { - Subtarget = &MF.getSubtarget<SparcSubtarget>(); - const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); - DebugLoc DL = DebugLoc(); - - bool Modified = false; - for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { - MachineBasicBlock &MBB = *MFI; - for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { - MachineInstr &MI = *MBBI; - unsigned Opcode = MI.getOpcode(); - if (Opcode == SP::LDDFri || Opcode == SP::LDDFrr) { - MachineBasicBlock::iterator NMBBI = std::next(MBBI); - MachineInstr &NMI = *NMBBI; - - unsigned NextOpcode = NMI.getOpcode(); - // NMI.print(errs()); - if (NextOpcode == SP::FADDD || NextOpcode == SP::FSUBD || - NextOpcode == SP::FMULD || NextOpcode == SP::FDIVD) { - int RegAIndex = GetRegIndexForOperand(MI, 0); - int RegBIndex = GetRegIndexForOperand(NMI, 0); - int RegCIndex = - GetRegIndexForOperand(NMI, 2); // Second source operand is index 2 - int RegDIndex = - GetRegIndexForOperand(NMI, 1); // Destination operand is index 1 - - if ((RegAIndex == RegBIndex + 1 && RegBIndex == RegDIndex) || - (RegAIndex == RegCIndex + 1 && RegCIndex == RegDIndex) || - (RegAIndex == RegBIndex + 1 && RegCIndex == RegDIndex) || - (RegAIndex == RegCIndex + 1 && RegBIndex == RegDIndex)) { - // Insert NOP between the two instructions. - BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); - Modified = true; - } - - // Check the errata patterns that only happen for FADDD and FMULD - if (Modified == false && - (NextOpcode == SP::FADDD || NextOpcode == SP::FMULD)) { - RegAIndex = GetRegIndexForOperand(MI, 1); - if (RegAIndex == RegBIndex + 1 && RegBIndex == RegCIndex && - RegBIndex == RegDIndex) { - // Insert NOP between the two instructions. - BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); - Modified = true; - } - } - } else if (NextOpcode == SP::FSQRTD) { - int RegAIndex = GetRegIndexForOperand(MI, 1); - int RegBIndex = GetRegIndexForOperand(NMI, 0); - int RegCIndex = GetRegIndexForOperand(NMI, 1); - - if (RegAIndex == RegBIndex + 1 && RegBIndex == RegCIndex) { - // Insert NOP between the two instructions. - BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); - Modified = true; - } - } - } - } - } - - return Modified; -} //***************************************************************************** -//**** PreventRoundChange pass +//**** DetectRoundChange pass //***************************************************************************** // To prevent any explicit change of the default rounding mode, this pass -// detects any call of the fesetround function and removes this call from the -// list of generated operations. +// detects any call of the fesetround function. +// A warning is generated to ensure the user knows this has happened. // -char PreventRoundChange::ID = 0; +// Detects an erratum in UT699 LEON 3 processor -PreventRoundChange::PreventRoundChange(TargetMachine &tm) +char DetectRoundChange::ID = 0; + +DetectRoundChange::DetectRoundChange(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {} -bool PreventRoundChange::runOnMachineFunction(MachineFunction &MF) { +bool DetectRoundChange::runOnMachineFunction(MachineFunction &MF) { Subtarget = &MF.getSubtarget<SparcSubtarget>(); bool Modified = false; @@ -728,10 +305,11 @@ bool PreventRoundChange::runOnMachineFunction(MachineFunction &MF) { if (MO.isGlobal()) { StringRef FuncName = MO.getGlobal()->getName(); if (FuncName.compare_lower("fesetround") == 0) { - MachineBasicBlock::iterator NMBBI = std::next(MBBI); - MI.eraseFromParent(); - MBBI = NMBBI; - Modified = true; + errs() << "Error: You are using the detectroundchange " + "option to detect rounding changes that will " + "cause LEON errata. The only way to fix this " + "is to remove the call to fesetround from " + "the source code.\n"; } } } @@ -740,17 +318,30 @@ bool PreventRoundChange::runOnMachineFunction(MachineFunction &MF) { return Modified; } + //***************************************************************************** -//**** FlushCacheLineSWAP pass +//**** FixAllFDIVSQRT pass //***************************************************************************** -// This pass inserts FLUSHW just before any SWAP atomic instruction. +// This pass fixes the incorrectly working FDIVx and FSQRTx instructions that +// exist for some earlier versions of the LEON processor line. Five NOP +// instructions need to be inserted after these instructions to ensure the +// correct result is placed in the destination registers before they are used. // -char FlushCacheLineSWAP::ID = 0; +// This pass implements two fixes: +// 1) fixing the FSQRTS and FSQRTD instructions. +// 2) fixing the FDIVS and FDIVD instructions. +// +// FSQRTS and FDIVS are converted to FDIVD and FSQRTD respectively earlier in +// the pipeline when this option is enabled, so this pass needs only to deal +// with the changes that still need implementing for the "double" versions +// of these instructions. +// +char FixAllFDIVSQRT::ID = 0; -FlushCacheLineSWAP::FlushCacheLineSWAP(TargetMachine &tm) +FixAllFDIVSQRT::FixAllFDIVSQRT(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {} -bool FlushCacheLineSWAP::runOnMachineFunction(MachineFunction &MF) { +bool FixAllFDIVSQRT::runOnMachineFunction(MachineFunction &MF) { Subtarget = &MF.getSubtarget<SparcSubtarget>(); const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); DebugLoc DL = DebugLoc(); @@ -761,170 +352,20 @@ bool FlushCacheLineSWAP::runOnMachineFunction(MachineFunction &MF) { for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { MachineInstr &MI = *MBBI; unsigned Opcode = MI.getOpcode(); - if (Opcode == SP::SWAPrr || Opcode == SP::SWAPri || - Opcode == SP::LDSTUBrr || Opcode == SP::LDSTUBri) { - // insert flush and 5 NOPs before the swap/ldstub instruction - BuildMI(MBB, MBBI, DL, TII.get(SP::FLUSH)); - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - Modified = true; - } else if (MI.isInlineAsm()) { - StringRef AsmString = - MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); - if (AsmString.startswith_lower("swap") || - AsmString.startswith_lower("ldstub")) { - // this is an inline swap or ldstub instruction - - // insert flush and 5 NOPs before the swap/ldstub instruction - BuildMI(MBB, MBBI, DL, TII.get(SP::FLUSH)); - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); + // Note: FDIVS and FSQRTS cannot be generated when this erratum fix is + // switched on so we don't need to check for them here. They will + // already have been converted to FSQRTD or FDIVD earlier in the + // pipeline. + if (Opcode == SP::FSQRTD || Opcode == SP::FDIVD) { + for (int InsertedCount = 0; InsertedCount < 5; InsertedCount++) BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - Modified = true; - } - } - } - } - - return Modified; -} - -//***************************************************************************** -//**** InsertNOPsLoadStore pass -//***************************************************************************** -// This pass shall insert NOPs between floating point loads and stores when the -// following circumstances are present [5]: -// Pattern 1: -// 1. single-precision load or single-precision FPOP to register %fX, where X is -// the same register as the store being checked; -// 2. single-precision load or single-precision FPOP to register %fY , where Y -// is the opposite register in the same double-precision pair; -// 3. 0-3 instructions of any kind, except stores from %fX or %fY or operations -// with %fX as destination; -// 4. the store (from register %fX) being considered. -// Pattern 2: -// 1. double-precision FPOP; -// 2. any number of operations on any kind, except no double-precision FPOP and -// at most one (less than two) single-precision or single-to-double FPOPs; -// 3. the store (from register %fX) being considered. -// -char InsertNOPsLoadStore::ID = 0; - -InsertNOPsLoadStore::InsertNOPsLoadStore(TargetMachine &tm) - : LEONMachineFunctionPass(tm, ID) {} - -bool InsertNOPsLoadStore::runOnMachineFunction(MachineFunction &MF) { - Subtarget = &MF.getSubtarget<SparcSubtarget>(); - const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); - DebugLoc DL = DebugLoc(); - - MachineInstr *Pattern1FirstInstruction = NULL; - MachineInstr *Pattern2FirstInstruction = NULL; - unsigned int StoreInstructionsToCheck = 0; - int FxRegIndex, FyRegIndex; - - bool Modified = false; - for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { - MachineBasicBlock &MBB = *MFI; - for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { - MachineInstr &MI = *MBBI; - - if (StoreInstructionsToCheck > 0) { - if (((MI.getOpcode() == SP::STFrr || MI.getOpcode() == SP::STFri) && - (GetRegIndexForOperand(MI, LAST_OPERAND) == FxRegIndex || - GetRegIndexForOperand(MI, LAST_OPERAND) == FyRegIndex)) || - GetRegIndexForOperand(MI, 0) == FxRegIndex) { - // Insert four NOPs - for (unsigned InsertedCount = 0; InsertedCount < 4; InsertedCount++) { - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - } - Modified = true; - } - StoreInstructionsToCheck--; - } - - switch (MI.getOpcode()) { - // Watch for Pattern 1 FPop instructions - case SP::LDrr: - case SP::LDri: - case SP::LDFrr: - case SP::LDFri: - case SP::FADDS: - case SP::FSUBS: - case SP::FMULS: - case SP::FDIVS: - case SP::FSQRTS: - case SP::FCMPS: - case SP::FMOVS: - case SP::FNEGS: - case SP::FABSS: - case SP::FITOS: - case SP::FSTOI: - case SP::FITOD: - case SP::FDTOI: - case SP::FDTOS: - if (Pattern1FirstInstruction != NULL) { - FxRegIndex = GetRegIndexForOperand(*Pattern1FirstInstruction, 0); - FyRegIndex = GetRegIndexForOperand(MI, 0); - - // Check to see if these registers are part of the same double - // precision - // register pair. - int DoublePrecRegIndexForX = (FxRegIndex - SP::F0) / 2; - int DoublePrecRegIndexForY = (FyRegIndex - SP::F0) / 2; - - if (DoublePrecRegIndexForX == DoublePrecRegIndexForY) - StoreInstructionsToCheck = 4; - } + MachineBasicBlock::iterator NMBBI = std::next(MBBI); + for (int InsertedCount = 0; InsertedCount < 28; InsertedCount++) + BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); - Pattern1FirstInstruction = &MI; - break; - // End of Pattern 1 - - // Search for Pattern 2 - case SP::FADDD: - case SP::FSUBD: - case SP::FMULD: - case SP::FDIVD: - case SP::FSQRTD: - case SP::FCMPD: - Pattern2FirstInstruction = &MI; - Pattern1FirstInstruction = NULL; - break; - - case SP::STFrr: - case SP::STFri: - case SP::STDFrr: - case SP::STDFri: - if (Pattern2FirstInstruction != NULL) { - if (GetRegIndexForOperand(MI, LAST_OPERAND) == - GetRegIndexForOperand(*Pattern2FirstInstruction, 0)) { - // Insert four NOPs - for (unsigned InsertedCount = 0; InsertedCount < 4; - InsertedCount++) { - BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); - } - - Pattern2FirstInstruction = NULL; - } - } - Pattern1FirstInstruction = NULL; - break; - // End of Pattern 2 - - default: - // Ensure we don't count debug-only values while we're testing for the - // patterns. - if (!MI.isDebugValue()) - Pattern1FirstInstruction = NULL; - break; + Modified = true; } } } diff --git a/contrib/llvm/lib/Target/Sparc/LeonPasses.h b/contrib/llvm/lib/Target/Sparc/LeonPasses.h index 5e21813..2158cb6 100755 --- a/contrib/llvm/lib/Target/Sparc/LeonPasses.h +++ b/contrib/llvm/lib/Target/Sparc/LeonPasses.h @@ -44,57 +44,17 @@ protected: int getUnusedFPRegister(MachineRegisterInfo &MRI); }; -class LLVM_LIBRARY_VISIBILITY ReplaceSDIV : public LEONMachineFunctionPass { -public: - static char ID; - - ReplaceSDIV(); - ReplaceSDIV(TargetMachine &tm); - bool runOnMachineFunction(MachineFunction &MF) override; - - const char *getPassName() const override { - return "ReplaceSDIV: Erratum Fix LBR25: do not emit SDIV, but emit SDIVCC " - "instead"; - } -}; - -class LLVM_LIBRARY_VISIBILITY FixCALL : public LEONMachineFunctionPass { -public: - static char ID; - - FixCALL(TargetMachine &tm); - bool runOnMachineFunction(MachineFunction &MF) override; - - const char *getPassName() const override { - return "FixCALL: Erratum Fix LBR26: restrict the size of the immediate " - "operand of the CALL instruction to 20 bits"; - } -}; - -class LLVM_LIBRARY_VISIBILITY IgnoreZeroFlag : public LEONMachineFunctionPass { -public: - static char ID; - - IgnoreZeroFlag(TargetMachine &tm); - bool runOnMachineFunction(MachineFunction &MF) override; - - const char *getPassName() const override { - return "IgnoreZeroFlag: Erratum Fix LBR28: do not rely on the zero bit " - "flag on a divide overflow for SDIVCC and UDIVCC"; - } -}; - -class LLVM_LIBRARY_VISIBILITY InsertNOPDoublePrecision - : public LEONMachineFunctionPass { +class LLVM_LIBRARY_VISIBILITY InsertNOPLoad : public LEONMachineFunctionPass { public: static char ID; - InsertNOPDoublePrecision(TargetMachine &tm); + InsertNOPLoad(TargetMachine &tm); bool runOnMachineFunction(MachineFunction &MF) override; - const char *getPassName() const override { - return "InsertNOPDoublePrecision: Erratum Fix LBR30: insert a NOP before " - "the double precision floating point instruction"; + StringRef getPassName() const override { + return "InsertNOPLoad: Erratum Fix LBR35: insert a NOP instruction after " + "every single-cycle load instruction when the next instruction is " + "another load/store instruction"; } }; @@ -105,7 +65,7 @@ public: FixFSMULD(TargetMachine &tm); bool runOnMachineFunction(MachineFunction &MF) override; - const char *getPassName() const override { + StringRef getPassName() const override { return "FixFSMULD: Erratum Fix LBR31: do not select FSMULD"; } }; @@ -117,24 +77,24 @@ public: ReplaceFMULS(TargetMachine &tm); bool runOnMachineFunction(MachineFunction &MF) override; - const char *getPassName() const override { + StringRef getPassName() const override { return "ReplaceFMULS: Erratum Fix LBR32: replace FMULS instruction with a " "routine using conversions/double precision operations to replace " "FMULS"; } }; -class LLVM_LIBRARY_VISIBILITY PreventRoundChange +class LLVM_LIBRARY_VISIBILITY DetectRoundChange : public LEONMachineFunctionPass { public: static char ID; - PreventRoundChange(TargetMachine &tm); + DetectRoundChange(TargetMachine &tm); bool runOnMachineFunction(MachineFunction &MF) override; - const char *getPassName() const override { - return "PreventRoundChange: Erratum Fix LBR33: prevent any rounding mode " - "change request: use only the round-to-nearest rounding mode"; + StringRef getPassName() const override { + return "DetectRoundChange: Leon erratum detection: detect any rounding " + "mode change request: use only the round-to-nearest rounding mode"; } }; @@ -145,55 +105,11 @@ public: FixAllFDIVSQRT(TargetMachine &tm); bool runOnMachineFunction(MachineFunction &MF) override; - const char *getPassName() const override { + StringRef getPassName() const override { return "FixAllFDIVSQRT: Erratum Fix LBR34: fix FDIVS/FDIVD/FSQRTS/FSQRTD " "instructions with NOPs and floating-point store"; } }; - -class LLVM_LIBRARY_VISIBILITY InsertNOPLoad : public LEONMachineFunctionPass { -public: - static char ID; - - InsertNOPLoad(TargetMachine &tm); - bool runOnMachineFunction(MachineFunction &MF) override; - - const char *getPassName() const override { - return "InsertNOPLoad: insert a NOP instruction after " - "every single-cycle load instruction when the next instruction is " - "another load/store instruction"; - } -}; - -class LLVM_LIBRARY_VISIBILITY FlushCacheLineSWAP - : public LEONMachineFunctionPass { -public: - static char ID; - - FlushCacheLineSWAP(TargetMachine &tm); - bool runOnMachineFunction(MachineFunction &MF) override; - - const char *getPassName() const override { - return "FlushCacheLineSWAP: Erratum Fix LBR36: flush cache line containing " - "the lock before performing any of the atomic instructions SWAP and " - "LDSTUB"; - } -}; - -class LLVM_LIBRARY_VISIBILITY InsertNOPsLoadStore - : public LEONMachineFunctionPass { -public: - static char ID; - - InsertNOPsLoadStore(TargetMachine &tm); - bool runOnMachineFunction(MachineFunction &MF) override; - - const char *getPassName() const override { - return "InsertNOPsLoadStore: Erratum Fix LBR37: insert NOPs between " - "single-precision loads and the store, so the number of " - "instructions between is 4"; - } -}; -} // namespace lllvm +} // namespace llvm #endif // LLVM_LIB_TARGET_SPARC_LEON_PASSES_H diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp index 14a70d8..6106a6c 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -300,6 +300,7 @@ namespace { MCAsmBackend *llvm::createSparcAsmBackend(const Target &T, const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU) { + const Triple &TT, StringRef CPU, + const MCTargetOptions &Options) { return new ELFSparcAsmBackend(T, TT.getOS()); } diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp index 45bc4a1..86341c6 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCAsmInfo.h" @@ -35,10 +36,12 @@ namespace { class SparcMCCodeEmitter : public MCCodeEmitter { SparcMCCodeEmitter(const SparcMCCodeEmitter &) = delete; void operator=(const SparcMCCodeEmitter &) = delete; + const MCInstrInfo &MCII; MCContext &Ctx; public: - SparcMCCodeEmitter(MCContext &ctx): Ctx(ctx) {} + SparcMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) + : MCII(mcii), Ctx(ctx) {} ~SparcMCCodeEmitter() override {} @@ -71,18 +74,25 @@ public: SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; +private: + uint64_t computeAvailableFeatures(const FeatureBitset &FB) const; + void verifyInstructionPredicates(const MCInst &MI, + uint64_t AvailableFeatures) const; }; } // end anonymous namespace MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx) { - return new SparcMCCodeEmitter(Ctx); + return new SparcMCCodeEmitter(MCII, Ctx); } void SparcMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { + verifyInstructionPredicates(MI, + computeAvailableFeatures(STI.getFeatureBits())); + unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI); if (Ctx.getAsmInfo()->isLittleEndian()) { @@ -215,6 +225,5 @@ getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo, return 0; } - - +#define ENABLE_INSTR_PREDICATE_VERIFIER #include "SparcGenMCCodeEmitter.inc" diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp index dceaca7..889e2fd 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp @@ -128,11 +128,12 @@ static MCInstPrinter *createSparcMCInstPrinter(const Triple &T, extern "C" void LLVMInitializeSparcTargetMC() { // Register the MC asm info. - RegisterMCAsmInfoFn X(TheSparcTarget, createSparcMCAsmInfo); - RegisterMCAsmInfoFn Y(TheSparcV9Target, createSparcV9MCAsmInfo); - RegisterMCAsmInfoFn Z(TheSparcelTarget, createSparcMCAsmInfo); + RegisterMCAsmInfoFn X(getTheSparcTarget(), createSparcMCAsmInfo); + RegisterMCAsmInfoFn Y(getTheSparcV9Target(), createSparcV9MCAsmInfo); + RegisterMCAsmInfoFn Z(getTheSparcelTarget(), createSparcMCAsmInfo); - for (Target *T : {&TheSparcTarget, &TheSparcV9Target, &TheSparcelTarget}) { + for (Target *T : + {&getTheSparcTarget(), &getTheSparcV9Target(), &getTheSparcelTarget()}) { // Register the MC instruction info. TargetRegistry::RegisterMCInstrInfo(*T, createSparcMCInstrInfo); @@ -160,10 +161,10 @@ extern "C" void LLVMInitializeSparcTargetMC() { } // Register the MC codegen info. - TargetRegistry::registerMCAdjustCodeGenOpts(TheSparcTarget, + TargetRegistry::registerMCAdjustCodeGenOpts(getTheSparcTarget(), adjustCodeGenOpts); - TargetRegistry::registerMCAdjustCodeGenOpts(TheSparcV9Target, + TargetRegistry::registerMCAdjustCodeGenOpts(getTheSparcV9Target(), adjustCodeGenOptsV9); - TargetRegistry::registerMCAdjustCodeGenOpts(TheSparcelTarget, + TargetRegistry::registerMCAdjustCodeGenOpts(getTheSparcelTarget(), adjustCodeGenOpts); } diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h index a9c9f15..4e754c1 100644 --- a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h @@ -24,21 +24,23 @@ class MCInstrInfo; class MCObjectWriter; class MCRegisterInfo; class MCSubtargetInfo; +class MCTargetOptions; class Target; class Triple; class StringRef; class raw_pwrite_stream; class raw_ostream; -extern Target TheSparcTarget; -extern Target TheSparcV9Target; -extern Target TheSparcelTarget; +Target &getTheSparcTarget(); +Target &getTheSparcV9Target(); +Target &getTheSparcelTarget(); MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx); MCAsmBackend *createSparcAsmBackend(const Target &T, const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU); + const Triple &TT, StringRef CPU, + const MCTargetOptions &Options); MCObjectWriter *createSparcELFObjectWriter(raw_pwrite_stream &OS, bool Is64Bit, bool IsLIttleEndian, uint8_t OSABI); } // End llvm namespace diff --git a/contrib/llvm/lib/Target/Sparc/Sparc.td b/contrib/llvm/lib/Target/Sparc/Sparc.td index 7a3d124..11004c5 100644 --- a/contrib/llvm/lib/Target/Sparc/Sparc.td +++ b/contrib/llvm/lib/Target/Sparc/Sparc.td @@ -21,34 +21,35 @@ include "llvm/Target/Target.td" // def FeatureV9 - : SubtargetFeature<"v9", "IsV9", "true", "Enable SPARC-V9 instructions">; + : SubtargetFeature<"v9", "IsV9", "true", + "Enable SPARC-V9 instructions">; def FeatureV8Deprecated - : SubtargetFeature<"deprecated-v8", "V8DeprecatedInsts", "true", - "Enable deprecated V8 instructions in V9 mode">; + : SubtargetFeature<"deprecated-v8", "V8DeprecatedInsts", "true", + "Enable deprecated V8 instructions in V9 mode">; def FeatureVIS - : SubtargetFeature<"vis", "IsVIS", "true", - "Enable UltraSPARC Visual Instruction Set extensions">; + : SubtargetFeature<"vis", "IsVIS", "true", + "Enable UltraSPARC Visual Instruction Set extensions">; def FeatureVIS2 - : SubtargetFeature<"vis2", "IsVIS2", "true", - "Enable Visual Instruction Set extensions II">; + : SubtargetFeature<"vis2", "IsVIS2", "true", + "Enable Visual Instruction Set extensions II">; def FeatureVIS3 - : SubtargetFeature<"vis3", "IsVIS3", "true", - "Enable Visual Instruction Set extensions III">; + : SubtargetFeature<"vis3", "IsVIS3", "true", + "Enable Visual Instruction Set extensions III">; def FeatureLeon - : SubtargetFeature<"leon", "IsLeon", "true", "Enable LEON extensions">; + : SubtargetFeature<"leon", "IsLeon", "true", + "Enable LEON extensions">; def FeatureHardQuad - : SubtargetFeature<"hard-quad-float", "HasHardQuad", "true", - "Enable quad-word floating point instructions">; + : SubtargetFeature<"hard-quad-float", "HasHardQuad", "true", + "Enable quad-word floating point instructions">; def UsePopc : SubtargetFeature<"popc", "UsePopc", "true", "Use the popc (population count) instruction">; -def FeatureSoftFloat - : SubtargetFeature<"soft-float", "UseSoftFloat", "true", - "Use software emulation for floating point">; +def FeatureSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true", + "Use software emulation for floating point">; -//==== Features added predmoninantly for LEON subtarget support +//==== Features added predmoninantly for LEON subtarget support include "LeonFeatures.td" //===----------------------------------------------------------------------===// @@ -62,92 +63,90 @@ include "SparcInstrInfo.td" def SparcInstrInfo : InstrInfo; -def SparcAsmParser : AsmParser { bit ShouldEmitMatchRegisterName = 0; } +def SparcAsmParser : AsmParser { + bit ShouldEmitMatchRegisterName = 0; +} //===----------------------------------------------------------------------===// // SPARC processors supported. //===----------------------------------------------------------------------===// class Proc<string Name, list<SubtargetFeature> Features> - : Processor<Name, NoItineraries, Features>; - -def : Proc<"generic", []>; -def : Proc<"v7", []>; -def : Proc<"v8", []>; -def : Proc<"supersparc", []>; -def : Proc<"sparclite", []>; -def : Proc<"f934", []>; -def : Proc<"hypersparc", []>; -def : Proc<"sparclite86x", []>; -def : Proc<"sparclet", []>; -def : Proc<"tsc701", []>; -def : Proc<"myriad2", []>; -def : Proc<"myriad2.1", []>; -def : Proc<"myriad2.2", []>; -def : Proc<"v9", [ FeatureV9 ]>; -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 -]>; + : Processor<Name, NoItineraries, Features>; + +def : Proc<"generic", []>; +def : Proc<"v7", []>; +def : Proc<"v8", []>; +def : Proc<"supersparc", []>; +def : Proc<"sparclite", []>; +def : Proc<"f934", []>; +def : Proc<"hypersparc", []>; +def : Proc<"sparclite86x", []>; +def : Proc<"sparclet", []>; +def : Proc<"tsc701", []>; +def : Proc<"myriad2", [FeatureLeon, LeonCASA]>; +def : Proc<"myriad2.1", [FeatureLeon, LeonCASA]>; +def : Proc<"myriad2.2", [FeatureLeon, LeonCASA]>; +def : Proc<"ma2100", [FeatureLeon, LeonCASA]>; +def : Proc<"ma2150", [FeatureLeon, LeonCASA]>; +def : Proc<"ma2450", [FeatureLeon, LeonCASA]>; +def : Proc<"v9", [FeatureV9]>; +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]>; // LEON 2 FT generic -def : Processor<"leon2", LEON2Itineraries, [ FeatureLeon ]>; +def : Processor<"leon2", LEON2Itineraries, + [FeatureLeon]>; // LEON 2 FT (AT697E) -// AT697E: Provides full coverage of AT697E - covers all the erratum fixes for -// LEON2 AT697E -def : Processor<"at697e", LEON2Itineraries, [ - FeatureLeon, ReplaceSDIV, FixCALL, IgnoreZeroFlag, InsertNOPDoublePrecision -]>; +// TO DO: Place-holder: Processor specific features will be added *very* soon here. +def : Processor<"at697e", LEON2Itineraries, + [FeatureLeon, ReplaceSDIV, InsertNOPLoad]>; // LEON 2 FT (AT697F) -// AT697F: Provides full coverage of AT697F - covers all the erratum fixes for -// LEON2 AT697F +// TO DO: Place-holder: Processor specific features will be added *very* soon here. def : Processor<"at697f", LEON2Itineraries, - [ FeatureLeon, InsertNOPDoublePrecision ]>; + [FeatureLeon, InsertNOPLoad]>; + // LEON 3 FT generic -def : Processor<"leon3", LEON3Itineraries, [ FeatureLeon, UMACSMACSupport ]>; +def : Processor<"leon3", LEON3Itineraries, + [FeatureLeon, UMACSMACSupport]>; // LEON 3 FT (UT699). Provides features for the UT699 processor -// - covers all the erratum fixes for LEON3, but does not support the CASA -// instruction. -def : Processor<"ut699", LEON3Itineraries, [ - FeatureLeon, FixFSMULD, ReplaceFMULS, PreventRoundChange, - FixAllFDIVSQRT, InsertNOPLoad, FlushCacheLineSWAP, InsertNOPsLoadStore -]>; +// - covers all the erratum fixes for LEON3, but does not support the CASA instruction. +def : Processor<"ut699", LEON3Itineraries, + [FeatureLeon, InsertNOPLoad, FixFSMULD, ReplaceFMULS, FixAllFDIVSQRT]>; // LEON3 FT (GR712RC). Provides features for the GR712RC processor. -// - covers all the erratum fixed for LEON3 and support for the CASA -// instruction. +// - covers all the erratum fixed for LEON3 and support for the CASA instruction. def : Processor<"gr712rc", LEON3Itineraries, - [ FeatureLeon, LeonCASA ]>; + [FeatureLeon, LeonCASA]>; // LEON 4 FT generic def : Processor<"leon4", LEON4Itineraries, - [ FeatureLeon, LeonCASA ]>; + [FeatureLeon, UMACSMACSupport, LeonCASA]>; -// GR740: Provides full coverage of GR740 - covers all the erratum fixes for -// LEON3 + support to CASA + LEON 4 instruction timings -def : Processor<"gr740", LEON4Itineraries, - [ FeatureLeon, LeonCASA ]> {} +// LEON 4 FT (GR740) +// TO DO: Place-holder: Processor specific features will be added *very* soon here. +def : Processor<"gr740", LEON4Itineraries, + [FeatureLeon, UMACSMACSupport, LeonCASA]>; //===----------------------------------------------------------------------===// // Declare the target which we are implementing //===----------------------------------------------------------------------===// def SparcAsmWriter : AsmWriter { - string AsmWriterClassName = "InstPrinter"; + string AsmWriterClassName = "InstPrinter"; int PassSubtarget = 1; int Variant = 0; } @@ -155,6 +154,6 @@ def SparcAsmWriter : AsmWriter { def Sparc : Target { // Pull in Instruction Info: let InstructionSet = SparcInstrInfo; - let AssemblyParsers = [ SparcAsmParser ]; - let AssemblyWriters = [ SparcAsmWriter ]; + 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 c068440..31a128a 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp @@ -46,9 +46,7 @@ namespace { std::unique_ptr<MCStreamer> Streamer) : AsmPrinter(TM, std::move(Streamer)) {} - const char *getPassName() const override { - return "Sparc Assembly Printer"; - } + StringRef 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, @@ -445,7 +443,7 @@ bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, // Force static initialization. extern "C" void LLVMInitializeSparcAsmPrinter() { - RegisterAsmPrinter<SparcAsmPrinter> X(TheSparcTarget); - RegisterAsmPrinter<SparcAsmPrinter> Y(TheSparcV9Target); - RegisterAsmPrinter<SparcAsmPrinter> Z(TheSparcelTarget); + RegisterAsmPrinter<SparcAsmPrinter> X(getTheSparcTarget()); + RegisterAsmPrinter<SparcAsmPrinter> Y(getTheSparcV9Target()); + RegisterAsmPrinter<SparcAsmPrinter> Z(getTheSparcelTarget()); } diff --git a/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.cpp b/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.cpp index 87b0155..122f830 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcFrameLowering.cpp @@ -87,7 +87,7 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF, SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); - MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineFrameInfo &MFI = MF.getFrameInfo(); const SparcInstrInfo &TII = *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo()); const SparcRegisterInfo &RegInfo = @@ -103,13 +103,13 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF, // rather than reporting an error, as would be sensible. This is // poor, but fixing that bogosity is going to be a large project. // For now, just see if it's lied, and report an error here. - if (!NeedsStackRealignment && MFI->getMaxAlignment() > getStackAlignment()) + if (!NeedsStackRealignment && MFI.getMaxAlignment() > getStackAlignment()) report_fatal_error("Function \"" + Twine(MF.getName()) + "\" required " "stack re-alignment, but LLVM couldn't handle it " "(probably because it has a dynamic alloca)."); // Get the number of bytes to allocate from the FrameInfo - int NumBytes = (int) MFI->getStackSize(); + int NumBytes = (int) MFI.getStackSize(); unsigned SAVEri = SP::SAVEri; unsigned SAVErr = SP::SAVErr; @@ -136,8 +136,8 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF, // Add the extra call frame stack size, if needed. (This is the same // code as in PrologEpilogInserter, but also gets disabled by // targetHandlesStackFrameRounding) - if (MFI->adjustsStack() && hasReservedCallFrame(MF)) - NumBytes += MFI->getMaxCallFrameSize(); + if (MFI.adjustsStack() && hasReservedCallFrame(MF)) + NumBytes += MFI.getMaxCallFrameSize(); // Adds the SPARC subtarget-specific spill area to the stack // size. Also ensures target-required alignment. @@ -145,40 +145,39 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF, // Finally, ensure that the size is sufficiently aligned for the // data on the stack. - if (MFI->getMaxAlignment() > 0) { - NumBytes = alignTo(NumBytes, MFI->getMaxAlignment()); + if (MFI.getMaxAlignment() > 0) { + NumBytes = alignTo(NumBytes, MFI.getMaxAlignment()); } // Update stack size with corrected value. - MFI->setStackSize(NumBytes); + MFI.setStackSize(NumBytes); emitSPAdjustment(MF, MBB, MBBI, -NumBytes, SAVErr, SAVEri); - MachineModuleInfo &MMI = MF.getMMI(); unsigned regFP = RegInfo.getDwarfRegNum(SP::I6, true); // Emit ".cfi_def_cfa_register 30". unsigned CFIIndex = - MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, regFP)); + MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, regFP)); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); // Emit ".cfi_window_save". - CFIIndex = MMI.addFrameInst(MCCFIInstruction::createWindowSave(nullptr)); + CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr)); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); unsigned regInRA = RegInfo.getDwarfRegNum(SP::I7, true); unsigned regOutRA = RegInfo.getDwarfRegNum(SP::O7, true); // Emit ".cfi_register 15, 31". - CFIIndex = MMI.addFrameInst( + CFIIndex = MF.addFrameInst( MCCFIInstruction::createRegister(nullptr, regOutRA, regInRA)); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); if (NeedsStackRealignment) { // andn %o6, MaxAlign-1, %o6 - int MaxAlign = MFI->getMaxAlignment(); + int MaxAlign = MFI.getMaxAlignment(); BuildMI(MBB, MBBI, dl, TII.get(SP::ANDNri), SP::O6).addReg(SP::O6).addImm(MaxAlign - 1); } } @@ -213,9 +212,9 @@ void SparcFrameLowering::emitEpilogue(MachineFunction &MF, .addReg(SP::G0); return; } - MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineFrameInfo &MFI = MF.getFrameInfo(); - int NumBytes = (int) MFI->getStackSize(); + int NumBytes = (int) MFI.getStackSize(); if (NumBytes == 0) return; @@ -224,7 +223,7 @@ void SparcFrameLowering::emitEpilogue(MachineFunction &MF, bool SparcFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { // Reserve call frame if there are no variable sized objects on the stack. - return !MF.getFrameInfo()->hasVarSizedObjects(); + return !MF.getFrameInfo().hasVarSizedObjects(); } // hasFP - Return true if the specified function should have a dedicated frame @@ -233,21 +232,21 @@ bool SparcFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { bool SparcFrameLowering::hasFP(const MachineFunction &MF) const { const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); - const MachineFrameInfo *MFI = MF.getFrameInfo(); + const MachineFrameInfo &MFI = MF.getFrameInfo(); return MF.getTarget().Options.DisableFramePointerElim(MF) || RegInfo->needsStackRealignment(MF) || - MFI->hasVarSizedObjects() || - MFI->isFrameAddressTaken(); + MFI.hasVarSizedObjects() || + MFI.isFrameAddressTaken(); } int SparcFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const { const SparcSubtarget &Subtarget = MF.getSubtarget<SparcSubtarget>(); - const MachineFrameInfo *MFI = MF.getFrameInfo(); + const MachineFrameInfo &MFI = MF.getFrameInfo(); const SparcRegisterInfo *RegInfo = Subtarget.getRegisterInfo(); const SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); - bool isFixed = MFI->isFixedObjectIndex(FI); + bool isFixed = MFI.isFixedObjectIndex(FI); // Addressable stack objects are accessed using neg. offsets from // %fp, or positive offsets from %sp. @@ -273,7 +272,7 @@ int SparcFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI UseFP = true; } - int64_t FrameOffset = MF.getFrameInfo()->getObjectOffset(FI) + + int64_t FrameOffset = MF.getFrameInfo().getObjectOffset(FI) + Subtarget.getStackPointerBias(); if (UseFP) { @@ -281,7 +280,7 @@ int SparcFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI return FrameOffset; } else { FrameReg = SP::O6; // %sp - return FrameOffset + MF.getFrameInfo()->getStackSize(); + return FrameOffset + MF.getFrameInfo().getStackSize(); } } @@ -303,9 +302,9 @@ bool SparcFrameLowering::isLeafProc(MachineFunction &MF) const { MachineRegisterInfo &MRI = MF.getRegInfo(); - MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineFrameInfo &MFI = MF.getFrameInfo(); - return !(MFI->hasCalls() // has calls + return !(MFI.hasCalls() // has calls || !MRI.reg_nodbg_empty(SP::L0) // Too many registers needed || !MRI.reg_nodbg_empty(SP::O6) // %SP is used || hasFP(MF)); // need %FP diff --git a/contrib/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/contrib/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp index 07948a3..c36e75d 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -53,7 +53,7 @@ public: unsigned ConstraintID, std::vector<SDValue> &OutOps) override; - const char *getPassName() const override { + StringRef getPassName() const override { return "SPARC DAG->DAG Pattern Instruction Selection"; } @@ -360,22 +360,15 @@ void SparcDAGToDAGISel::Select(SDNode *N) { // FIXME: Handle div by immediate. unsigned Opcode = N->getOpcode() == ISD::SDIV ? SP::SDIVrr : SP::UDIVrr; + // SDIV is a hardware erratum on some LEON2 processors. Replace it with SDIVcc here. + if (((SparcTargetMachine&)TM).getSubtargetImpl()->performSDIVReplace() + && + Opcode == SP::SDIVrr) { + Opcode = SP::SDIVCCrr; + } CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart); return; } - case ISD::MULHU: - case ISD::MULHS: { - // FIXME: Handle mul by immediate. - SDValue MulLHS = N->getOperand(0); - SDValue MulRHS = N->getOperand(1); - unsigned Opcode = N->getOpcode() == ISD::MULHU ? SP::UMULrr : SP::SMULrr; - SDNode *Mul = - CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32, MulLHS, MulRHS); - SDValue ResultHigh = SDValue(Mul, 1); - ReplaceUses(SDValue(N, 0), ResultHigh); - CurDAG->RemoveDeadNode(N); - return; - } } SelectCode(N); diff --git a/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 8738bc8..2ac9aae 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -32,6 +32,7 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// @@ -403,7 +404,7 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( 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); + int FrameIdx = MF.getFrameInfo().CreateFixedObject(4, 64, true); SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); SDValue Arg = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo()); @@ -424,7 +425,7 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( SDValue LoVal; if (NextVA.isMemLoc()) { - int FrameIdx = MF.getFrameInfo()-> + int FrameIdx = MF.getFrameInfo(). CreateFixedObject(4, StackOffset+NextVA.getLocMemOffset(),true); SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo()); @@ -466,9 +467,9 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( assert(VA.getValVT() == MVT::f64 || VA.getValVT() == MVT::v2i32); // If it is double-word aligned, just load. if (Offset % 8 == 0) { - int FI = MF.getFrameInfo()->CreateFixedObject(8, - Offset, - true); + int FI = MF.getFrameInfo().CreateFixedObject(8, + Offset, + true); SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT); SDValue Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, MachinePointerInfo()); @@ -476,15 +477,15 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( continue; } - int FI = MF.getFrameInfo()->CreateFixedObject(4, - Offset, - true); + int FI = MF.getFrameInfo().CreateFixedObject(4, + Offset, + true); SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT); SDValue HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo()); - int FI2 = MF.getFrameInfo()->CreateFixedObject(4, - Offset+4, - true); + int FI2 = MF.getFrameInfo().CreateFixedObject(4, + Offset+4, + true); SDValue FIPtr2 = DAG.getFrameIndex(FI2, PtrVT); SDValue LoVal = @@ -500,9 +501,9 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( continue; } - int FI = MF.getFrameInfo()->CreateFixedObject(4, - Offset, - true); + int FI = MF.getFrameInfo().CreateFixedObject(4, + Offset, + true); SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT); SDValue Load ; if (VA.getValVT() == MVT::i32 || VA.getValVT() == MVT::f32) { @@ -554,8 +555,8 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( MF.getRegInfo().addLiveIn(*CurArgReg, VReg); SDValue Arg = DAG.getCopyFromReg(DAG.getRoot(), dl, VReg, MVT::i32); - int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset, - true); + int FrameIdx = MF.getFrameInfo().CreateFixedObject(4, ArgOffset, + true); SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); OutChains.push_back( @@ -638,7 +639,7 @@ SDValue SparcTargetLowering::LowerFormalArguments_64( // prefer our own extending loads. if (VA.isExtInLoc()) Offset += 8 - ValSize; - int FI = MF.getFrameInfo()->CreateFixedObject(ValSize, Offset, true); + int FI = MF.getFrameInfo().CreateFixedObject(ValSize, Offset, true); InVals.push_back( DAG.getLoad(VA.getValVT(), DL, Chain, DAG.getFrameIndex(FI, getPointerTy(MF.getDataLayout())), @@ -668,7 +669,7 @@ SDValue SparcTargetLowering::LowerFormalArguments_64( for (; ArgOffset < 6*8; ArgOffset += 8) { unsigned VReg = MF.addLiveIn(SP::I0 + ArgOffset/8, &SP::I64RegsRegClass); SDValue VArg = DAG.getCopyFromReg(Chain, DL, VReg, MVT::i64); - int FI = MF.getFrameInfo()->CreateFixedObject(8, ArgOffset + ArgArea, true); + int FI = MF.getFrameInfo().CreateFixedObject(8, ArgOffset + ArgArea, true); auto PtrVT = getPointerTy(MF.getDataLayout()); OutChains.push_back( DAG.getStore(Chain, DL, VArg, DAG.getFrameIndex(FI, PtrVT), @@ -740,7 +741,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI, // Keep stack frames 8-byte aligned. ArgsSize = (ArgsSize+7) & ~7; - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); // Create local copies for byval args. SmallVector<SDValue, 8> ByValArgs; @@ -754,7 +755,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI, unsigned Align = Flags.getByValAlign(); if (Size > 0U) { - int FI = MFI->CreateStackObject(Size, Align, false); + int FI = MFI.CreateStackObject(Size, Align, false); SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); SDValue SizeNode = DAG.getConstant(Size, dl, MVT::i32); @@ -1207,7 +1208,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI, if (VA.isRegLoc()) { if (VA.needsCustom() && VA.getValVT() == MVT::f128 && VA.getLocVT() == MVT::i128) { - // Store and reload into the interger register reg and reg+1. + // Store and reload into the integer register reg and reg+1. unsigned Offset = 8 * (VA.getLocReg() - SP::I0); unsigned StackOffset = Offset + Subtarget->getStackPointerBias() + 128; SDValue StackPtr = DAG.getRegister(SP::O6, PtrVT); @@ -1507,7 +1508,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, // AddPromotedToType(ISD::STORE, MVT::i64, MVT::v2i32); } - // Turn FP extload into load/fextend + // Turn FP extload into load/fpextend for (MVT VT : MVT::fp_valuetypes()) { setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand); setLoadExtAction(ISD::EXTLOAD, VT, MVT::f64, Expand); @@ -1616,8 +1617,10 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, // Atomics are supported on SparcV9. 32-bit atomics are also // supported by some Leon SparcV8 variants. Otherwise, atomics // are unsupported. - if (Subtarget->isV9() || Subtarget->hasLeonCasa()) + if (Subtarget->isV9()) setMaxAtomicSizeInBitsSupported(64); + else if (Subtarget->hasLeonCasa()) + setMaxAtomicSizeInBitsSupported(32); else setMaxAtomicSizeInBitsSupported(0); @@ -1638,6 +1641,13 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Custom); } + if (!Subtarget->is64Bit()) { + // These libcalls are not available in 32-bit. + setLibcallName(RTLIB::SHL_I128, nullptr); + setLibcallName(RTLIB::SRL_I128, nullptr); + setLibcallName(RTLIB::SRA_I128, nullptr); + } + if (!Subtarget->isV9()) { // SparcV8 does not have FNEGD and FABSD. setOperationAction(ISD::FNEG, MVT::f64, Custom); @@ -1675,9 +1685,10 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); - // FIXME: Sparc provides these multiplies, but we don't have them yet. - setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); - setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); + // Expands to [SU]MUL_LOHI. + setOperationAction(ISD::MULHU, MVT::i32, Expand); + setOperationAction(ISD::MULHS, MVT::i32, Expand); + setOperationAction(ISD::MUL, MVT::i32, Expand); if (Subtarget->is64Bit()) { setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); @@ -1961,8 +1972,8 @@ SDValue SparcTargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const { SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo); // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this // function has calls. - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); - MFI->setHasCalls(true); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); + MFI.setHasCalls(true); return DAG.getLoad(VT, DL, DAG.getEntryNode(), AbsAddr, MachinePointerInfo::getGOT(DAG.getMachineFunction())); } @@ -2089,8 +2100,8 @@ SDValue SparcTargetLowering::LowerGlobalTLSAddress(SDValue Op, // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this // function has calls. - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); - MFI->setHasCalls(true); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); + MFI.setHasCalls(true); SDValue TGA = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_TLS_IE_HI22, @@ -2120,7 +2131,7 @@ SDValue SparcTargetLowering::LowerF128_LibCallArg(SDValue Chain, ArgListTy &Args, SDValue Arg, const SDLoc &DL, SelectionDAG &DAG) const { - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); EVT ArgVT = Arg.getValueType(); Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); @@ -2130,7 +2141,7 @@ SDValue SparcTargetLowering::LowerF128_LibCallArg(SDValue Chain, if (ArgTy->isFP128Ty()) { // Create a stack object and pass the pointer to the library function. - int FI = MFI->CreateStackObject(16, 8, false); + int FI = MFI.CreateStackObject(16, 8, false); SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); Chain = DAG.getStore(Chain, DL, Entry.Node, FIPtr, MachinePointerInfo(), /* Alignment = */ 8); @@ -2149,7 +2160,7 @@ SparcTargetLowering::LowerF128Op(SDValue Op, SelectionDAG &DAG, ArgListTy Args; - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); auto PtrVT = getPointerTy(DAG.getDataLayout()); SDValue Callee = DAG.getExternalSymbol(LibFuncName, PtrVT); @@ -2161,7 +2172,7 @@ SparcTargetLowering::LowerF128Op(SDValue Op, SelectionDAG &DAG, if (RetTy->isFP128Ty()) { // Create a Stack Object to receive the return value of type f128. ArgListEntry Entry; - int RetFI = MFI->CreateStackObject(16, 8, false); + int RetFI = MFI.CreateStackObject(16, 8, false); RetPtr = DAG.getFrameIndex(RetFI, PtrVT); Entry.Node = RetPtr; Entry.Ty = PointerType::getUnqual(RetTy); @@ -2517,7 +2528,7 @@ static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG, auto PtrVT = TLI.getPointerTy(DAG.getDataLayout()); // Need frame address to find the address of VarArgsFrameIndex. - MF.getFrameInfo()->setFrameAddressIsTaken(true); + MF.getFrameInfo().setFrameAddressIsTaken(true); // vastart just stores the address of the VarArgsFrameIndex slot into the // memory location argument. @@ -2557,17 +2568,57 @@ static SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget) { SDValue Chain = Op.getOperand(0); // Legalize the chain. SDValue Size = Op.getOperand(1); // Legalize the size. + unsigned Align = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue(); + unsigned StackAlign = Subtarget->getFrameLowering()->getStackAlignment(); EVT VT = Size->getValueType(0); SDLoc dl(Op); + // TODO: implement over-aligned alloca. (Note: also implies + // supporting support for overaligned function frames + dynamic + // allocations, at all, which currently isn't supported) + if (Align > StackAlign) { + const MachineFunction &MF = DAG.getMachineFunction(); + report_fatal_error("Function \"" + Twine(MF.getName()) + "\": " + "over-aligned dynamic alloca not supported."); + } + + // The resultant pointer needs to be above the register spill area + // at the bottom of the stack. + unsigned regSpillArea; + if (Subtarget->is64Bit()) { + regSpillArea = 128; + } else { + // On Sparc32, the size of the spill area is 92. Unfortunately, + // that's only 4-byte aligned, not 8-byte aligned (the stack + // pointer is 8-byte aligned). So, if the user asked for an 8-byte + // aligned dynamic allocation, we actually need to add 96 to the + // bottom of the stack, instead of 92, to ensure 8-byte alignment. + + // That also means adding 4 to the size of the allocation -- + // before applying the 8-byte rounding. Unfortunately, we the + // value we get here has already had rounding applied. So, we need + // to add 8, instead, wasting a bit more memory. + + // Further, this only actually needs to be done if the required + // alignment is > 4, but, we've lost that info by this point, too, + // so we always apply it. + + // (An alternative approach would be to always reserve 96 bytes + // instead of the required 92, but then we'd waste 4 extra bytes + // in every frame, not just those with dynamic stack allocations) + + // TODO: modify code in SelectionDAGBuilder to make this less sad. + + Size = DAG.getNode(ISD::ADD, dl, VT, Size, + DAG.getConstant(8, dl, VT)); + regSpillArea = 96; + } + unsigned SPReg = SP::O6; SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT); SDValue NewSP = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP); // Output chain - // The resultant pointer is actually 16 words from the bottom of the stack, - // to provide a register spill area. - unsigned regSpillArea = Subtarget->is64Bit() ? 128 : 96; regSpillArea += Subtarget->getStackPointerBias(); SDValue NewVal = DAG.getNode(ISD::ADD, dl, VT, NewSP, @@ -2586,8 +2637,8 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG &DAG) { static SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget) { - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); - MFI->setFrameAddressIsTaken(true); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); + MFI.setFrameAddressIsTaken(true); EVT VT = Op.getValueType(); SDLoc dl(Op); @@ -2628,14 +2679,15 @@ static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, uint64_t depth = Op.getConstantOperandVal(0); return getFRAMEADDR(depth, Op, DAG, Subtarget); + } static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG, const SparcTargetLowering &TLI, const SparcSubtarget *Subtarget) { MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - MFI->setReturnAddressIsTaken(true); + MachineFrameInfo &MFI = MF.getFrameInfo(); + MFI.setReturnAddressIsTaken(true); if (TLI.verifyReturnAddressArgumentIsConstant(Op, DAG)) return SDValue(); @@ -2805,7 +2857,7 @@ static SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) SDValue Val = DAG.getNode(ISD::BITCAST, dl, MVT::v2i32, St->getValue()); SDValue Chain = DAG.getStore( St->getChain(), dl, Val, St->getBasePtr(), St->getPointerInfo(), - St->isVolatile(), St->getMemOperand()->getFlags(), St->getAAInfo()); + St->getAlignment(), St->getMemOperand()->getFlags(), St->getAAInfo()); return Chain; } @@ -3042,7 +3094,7 @@ MachineBasicBlock * SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const { switch (MI.getOpcode()) { - default: llvm_unreachable("Unknown Custom Instruction!"); + default: llvm_unreachable("Unknown SELECT_CC!"); case SP::SELECT_CC_Int_ICC: case SP::SELECT_CC_FP_ICC: case SP::SELECT_CC_DFP_ICC: @@ -3059,6 +3111,7 @@ SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, case SP::EH_SJLJ_LONGJMP32rr: case SP::EH_SJLJ_LONGJMP32ri: return emitEHSjLjLongJmp(MI, BB); + } } @@ -3329,11 +3382,8 @@ SparcTargetLowering::ConstraintType SparcTargetLowering::getConstraintType(StringRef Constraint) const { if (Constraint.size() == 1) { switch (Constraint[0]) { - default: - break; - case 'f': - case 'r': - return C_RegisterClass; + default: break; + case 'r': return C_RegisterClass; case 'I': // SIMM13 return C_Other; } @@ -3407,9 +3457,6 @@ SparcTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, MVT VT) const { if (Constraint.size() == 1) { switch (Constraint[0]) { - case 'f': - return std::make_pair(0U, &SP::FPRegsRegClass); - case 'r': if (VT == MVT::v2i32) return std::make_pair(0U, &SP::IntPairRegClass); diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp index cfd3424..ea8ed83 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp @@ -118,19 +118,19 @@ static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC) case SPCC::CPCC_A: return SPCC::CPCC_N; case SPCC::CPCC_N: return SPCC::CPCC_A; - case SPCC::CPCC_3: // Fall through - case SPCC::CPCC_2: // Fall through - case SPCC::CPCC_23: // Fall through - case SPCC::CPCC_1: // Fall through - case SPCC::CPCC_13: // Fall through - case SPCC::CPCC_12: // Fall through - case SPCC::CPCC_123: // Fall through - case SPCC::CPCC_0: // Fall through - case SPCC::CPCC_03: // Fall through - case SPCC::CPCC_02: // Fall through - case SPCC::CPCC_023: // Fall through - case SPCC::CPCC_01: // Fall through - case SPCC::CPCC_013: // Fall through + case SPCC::CPCC_3: LLVM_FALLTHROUGH; + case SPCC::CPCC_2: LLVM_FALLTHROUGH; + case SPCC::CPCC_23: LLVM_FALLTHROUGH; + case SPCC::CPCC_1: LLVM_FALLTHROUGH; + case SPCC::CPCC_13: LLVM_FALLTHROUGH; + case SPCC::CPCC_12: LLVM_FALLTHROUGH; + case SPCC::CPCC_123: LLVM_FALLTHROUGH; + case SPCC::CPCC_0: LLVM_FALLTHROUGH; + case SPCC::CPCC_03: LLVM_FALLTHROUGH; + case SPCC::CPCC_02: LLVM_FALLTHROUGH; + case SPCC::CPCC_023: LLVM_FALLTHROUGH; + case SPCC::CPCC_01: LLVM_FALLTHROUGH; + case SPCC::CPCC_013: LLVM_FALLTHROUGH; case SPCC::CPCC_012: // "Opposite" code is not meaningful, as we don't know // what the CoProc condition means here. The cond-code will @@ -240,14 +240,16 @@ bool SparcInstrInfo::analyzeBranch(MachineBasicBlock &MBB, return true; } -unsigned SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB, +unsigned SparcInstrInfo::insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, - const DebugLoc &DL) const { - assert(TBB && "InsertBranch must not be told to insert a fallthrough"); + const DebugLoc &DL, + int *BytesAdded) const { + assert(TBB && "insertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 1 || Cond.size() == 0) && "Sparc branch conditions should have one component!"); + assert(!BytesAdded && "code size not handled"); if (Cond.empty()) { assert(!FBB && "Unconditional branch with multiple successors!"); @@ -269,8 +271,10 @@ unsigned SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB, return 2; } -unsigned SparcInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const -{ +unsigned SparcInstrInfo::removeBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; while (I != MBB.begin()) { @@ -291,7 +295,7 @@ unsigned SparcInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const return Count; } -bool SparcInstrInfo::ReverseBranchCondition( +bool SparcInstrInfo::reverseBranchCondition( SmallVectorImpl<MachineOperand> &Cond) const { assert(Cond.size() == 1); SPCC::CondCodes CC = static_cast<SPCC::CondCodes>(Cond[0].getImm()); @@ -397,7 +401,7 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, if (I != MBB.end()) DL = I->getDebugLoc(); MachineFunction *MF = MBB.getParent(); - const MachineFrameInfo &MFI = *MF->getFrameInfo(); + const MachineFrameInfo &MFI = MF->getFrameInfo(); MachineMemOperand *MMO = MF->getMachineMemOperand( MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore, MFI.getObjectSize(FI), MFI.getObjectAlignment(FI)); @@ -436,7 +440,7 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, if (I != MBB.end()) DL = I->getDebugLoc(); MachineFunction *MF = MBB.getParent(); - const MachineFrameInfo &MFI = *MF->getFrameInfo(); + const MachineFrameInfo &MFI = MF->getFrameInfo(); MachineMemOperand *MMO = MF->getMachineMemOperand( MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, MFI.getObjectSize(FI), MFI.getObjectAlignment(FI)); diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.h b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.h index 8ed97c1..c053cc4 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.h +++ b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.h @@ -70,14 +70,16 @@ public: SmallVectorImpl<MachineOperand> &Cond, bool AllowModify = false) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned removeBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; - unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; bool - ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; + reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.td b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.td index cc55c9c..5a19c62 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -734,8 +734,8 @@ let Defs = [ICC], rd = 0 in { // Section B.18 - Multiply Instructions, p. 113 let Defs = [Y] in { - defm UMUL : F3_12np<"umul", 0b001010, IIC_iu_umul>; - defm SMUL : F3_12 <"smul", 0b001011, mul, IntRegs, i32, simm13Op, IIC_iu_smul>; + defm UMUL : F3_12<"umul", 0b001010, umullohi, IntRegs, i32, simm13Op, IIC_iu_umul>; + defm SMUL : F3_12<"smul", 0b001011, smullohi, IntRegs, i32, simm13Op, IIC_iu_smul>; } let Defs = [Y, ICC] in { @@ -1131,32 +1131,32 @@ def FQTOI : F3_3u<2, 0b110100, 0b011010011, def FSTOD : F3_3u<2, 0b110100, 0b011001001, (outs DFPRegs:$rd), (ins FPRegs:$rs2), "fstod $rs2, $rd", - [(set f64:$rd, (fextend f32:$rs2))], + [(set f64:$rd, (fpextend f32:$rs2))], IIC_fpu_stod>; def FSTOQ : F3_3u<2, 0b110100, 0b011001101, (outs QFPRegs:$rd), (ins FPRegs:$rs2), "fstoq $rs2, $rd", - [(set f128:$rd, (fextend f32:$rs2))]>, + [(set f128:$rd, (fpextend f32:$rs2))]>, Requires<[HasHardQuad]>; def FDTOS : F3_3u<2, 0b110100, 0b011000110, (outs FPRegs:$rd), (ins DFPRegs:$rs2), "fdtos $rs2, $rd", - [(set f32:$rd, (fround f64:$rs2))], + [(set f32:$rd, (fpround f64:$rs2))], IIC_fpu_fast_instr>; def FDTOQ : F3_3u<2, 0b110100, 0b011001110, (outs QFPRegs:$rd), (ins DFPRegs:$rs2), "fdtoq $rs2, $rd", - [(set f128:$rd, (fextend f64:$rs2))]>, + [(set f128:$rd, (fpextend f64:$rs2))]>, Requires<[HasHardQuad]>; def FQTOS : F3_3u<2, 0b110100, 0b011000111, (outs FPRegs:$rd), (ins QFPRegs:$rs2), "fqtos $rs2, $rd", - [(set f32:$rd, (fround f128:$rs2))]>, + [(set f32:$rd, (fpround f128:$rs2))]>, Requires<[HasHardQuad]>; def FQTOD : F3_3u<2, 0b110100, 0b011001011, (outs DFPRegs:$rd), (ins QFPRegs:$rs2), "fqtod $rs2, $rd", - [(set f64:$rd, (fround f128:$rs2))]>, + [(set f64:$rd, (fpround f128:$rs2))]>, Requires<[HasHardQuad]>; // Floating-point Move Instructions, p. 144 @@ -1255,14 +1255,14 @@ let Predicates = [HasNoFsmuldFix] in def FSMULD : F3_3<2, 0b110100, 0b001101001, (outs DFPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), "fsmuld $rs1, $rs2, $rd", - [(set f64:$rd, (fmul (fextend f32:$rs1), - (fextend f32:$rs2)))], + [(set f64:$rd, (fmul (fpextend f32:$rs1), + (fpextend f32:$rs2)))], IIC_fpu_muld>; def FDMULQ : F3_3<2, 0b110100, 0b001101110, (outs QFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), "fdmulq $rs1, $rs2, $rd", - [(set f128:$rd, (fmul (fextend f64:$rs1), - (fextend f64:$rs2)))]>, + [(set f128:$rd, (fmul (fpextend f64:$rs1), + (fpextend f64:$rs2)))]>, Requires<[HasHardQuad]>; // FDIVS generates an erratum on LEON processors, so by disabling this instruction diff --git a/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.td b/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.td index d1ef3b1..6ecfddf 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.td +++ b/contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.td @@ -331,7 +331,6 @@ def IntRegs : RegisterClass<"SP", [i32, i64], 32, (sequence "L%u", 0, 7), (sequence "O%u", 0, 7))>; - // Should be in the same order as IntRegs. def IntPair : RegisterClass<"SP", [v2i32], 64, (add I0_I1, I2_I3, I4_I5, I6_I7, diff --git a/contrib/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/contrib/llvm/lib/Target/Sparc/SparcSubtarget.cpp index a6a4dc5..43ddef3 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcSubtarget.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcSubtarget.cpp @@ -40,16 +40,11 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU, HasLeonCasa = false; HasUmacSmac = false; PerformSDIVReplace = false; - FixCallImmediates = false; - IgnoreZeroFlag = false; - InsertNOPDoublePrecision = false; + InsertNOPLoad = false; FixFSMULD = false; ReplaceFMULS = false; - PreventRoundChange = false; FixAllFDIVSQRT = false; - InsertNOPLoad = false; - FlushCacheLineSWAP = false; - InsertNOPsLoadStore = false; + DetectRoundChange = false; // Determine default and user specified characteristics std::string CPUName = CPU; diff --git a/contrib/llvm/lib/Target/Sparc/SparcSubtarget.h b/contrib/llvm/lib/Target/Sparc/SparcSubtarget.h index 42d6936..fa42da4 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcSubtarget.h +++ b/contrib/llvm/lib/Target/Sparc/SparcSubtarget.h @@ -48,14 +48,8 @@ class SparcSubtarget : public SparcGenSubtargetInfo { bool FixFSMULD; bool ReplaceFMULS; bool FixAllFDIVSQRT; - bool UseSoftFpu; + bool DetectRoundChange; bool PerformSDIVReplace; - bool FixCallImmediates; - bool IgnoreZeroFlag; - bool InsertNOPDoublePrecision; - bool PreventRoundChange; - bool FlushCacheLineSWAP; - bool InsertNOPsLoadStore; SparcInstrInfo InstrInfo; SparcTargetLowering TLInfo; @@ -93,20 +87,14 @@ public: bool useSoftFloat() const { return UseSoftFloat; } // Leon options - bool useSoftFpu() const { return UseSoftFpu; } - bool hasLeonCasa() const { return HasLeonCasa; } bool hasUmacSmac() const { return HasUmacSmac; } bool performSDIVReplace() const { return PerformSDIVReplace; } - bool fixCallImmediates() const { return FixCallImmediates; } - bool ignoreZeroFlag() const { return IgnoreZeroFlag; } - bool insertNOPDoublePrecision() const { return InsertNOPDoublePrecision; } + bool hasLeonCasa() const { return HasLeonCasa; } + bool insertNOPLoad() const { return InsertNOPLoad; } bool fixFSMULD() const { return FixFSMULD; } bool replaceFMULS() const { return ReplaceFMULS; } - bool preventRoundChange() const { return PreventRoundChange; } bool fixAllFDIVSQRT() const { return FixAllFDIVSQRT; } - bool flushCacheLineSWAP() const { return FlushCacheLineSWAP; } - bool insertNOPsLoadStore() const { return InsertNOPsLoadStore; } - bool insertNOPLoad() const { return InsertNOPLoad; } + bool detectRoundChange() const { return DetectRoundChange; } /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. diff --git a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp index 17fe86a..4ae6406 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp @@ -22,9 +22,9 @@ using namespace llvm; extern "C" void LLVMInitializeSparcTarget() { // Register the target. - RegisterTargetMachine<SparcV8TargetMachine> X(TheSparcTarget); - RegisterTargetMachine<SparcV9TargetMachine> Y(TheSparcV9Target); - RegisterTargetMachine<SparcelTargetMachine> Z(TheSparcelTarget); + RegisterTargetMachine<SparcV8TargetMachine> X(getTheSparcTarget()); + RegisterTargetMachine<SparcV9TargetMachine> Y(getTheSparcV9Target()); + RegisterTargetMachine<SparcelTargetMachine> Z(getTheSparcelTarget()); } static std::string computeDataLayout(const Triple &T, bool is64Bit) { @@ -76,7 +76,7 @@ SparcTargetMachine::SparcTargetMachine(const Target &T, const Triple &TT, SparcTargetMachine::~SparcTargetMachine() {} -const SparcSubtarget * +const SparcSubtarget * SparcTargetMachine::getSubtargetImpl(const Function &F) const { Attribute CPUAttr = F.getFnAttribute("target-cpu"); Attribute FSAttr = F.getFnAttribute("target-features"); @@ -95,7 +95,7 @@ SparcTargetMachine::getSubtargetImpl(const Function &F) const { F.hasFnAttribute("use-soft-float") && F.getFnAttribute("use-soft-float").getValueAsString() == "true"; - if (softFloat) + if (softFloat) FS += FS.empty() ? "+soft-float" : ",+soft-float"; auto &I = SubtargetMap[CPU + FS]; @@ -115,7 +115,7 @@ namespace { class SparcPassConfig : public TargetPassConfig { public: SparcPassConfig(SparcTargetMachine *TM, PassManagerBase &PM) - : TargetPassConfig(TM, PM) {} + : TargetPassConfig(TM, PM) {} SparcTargetMachine &getSparcTargetMachine() const { return getTM<SparcTargetMachine>(); @@ -142,46 +142,31 @@ bool SparcPassConfig::addInstSelector() { return false; } -void SparcPassConfig::addPreEmitPass() { +void SparcPassConfig::addPreEmitPass(){ addPass(createSparcDelaySlotFillerPass(getSparcTargetMachine())); - if (this->getSparcTargetMachine().getSubtargetImpl()->ignoreZeroFlag()) { - addPass(new IgnoreZeroFlag(getSparcTargetMachine())); - } - if (this->getSparcTargetMachine().getSubtargetImpl()->performSDIVReplace()) { - addPass(new ReplaceSDIV(getSparcTargetMachine())); - } - if (this->getSparcTargetMachine().getSubtargetImpl()->fixCallImmediates()) { - addPass(new FixCALL(getSparcTargetMachine())); + + if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPLoad()) + { + addPass(new InsertNOPLoad(getSparcTargetMachine())); } - if (this->getSparcTargetMachine().getSubtargetImpl()->fixFSMULD()) { + if (this->getSparcTargetMachine().getSubtargetImpl()->fixFSMULD()) + { addPass(new FixFSMULD(getSparcTargetMachine())); } - if (this->getSparcTargetMachine().getSubtargetImpl()->replaceFMULS()) { + if (this->getSparcTargetMachine().getSubtargetImpl()->replaceFMULS()) + { addPass(new ReplaceFMULS(getSparcTargetMachine())); } - if (this->getSparcTargetMachine().getSubtargetImpl()->preventRoundChange()) { - addPass(new PreventRoundChange(getSparcTargetMachine())); + if (this->getSparcTargetMachine().getSubtargetImpl()->detectRoundChange()) { + addPass(new DetectRoundChange(getSparcTargetMachine())); } - if (this->getSparcTargetMachine().getSubtargetImpl()->fixAllFDIVSQRT()) { + if (this->getSparcTargetMachine().getSubtargetImpl()->fixAllFDIVSQRT()) + { addPass(new FixAllFDIVSQRT(getSparcTargetMachine())); } - if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPsLoadStore()) { - addPass(new InsertNOPsLoadStore(getSparcTargetMachine())); - } - if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPLoad()) { - addPass(new InsertNOPLoad(getSparcTargetMachine())); - } - if (this->getSparcTargetMachine().getSubtargetImpl()->flushCacheLineSWAP()) { - addPass(new FlushCacheLineSWAP(getSparcTargetMachine())); - } - if (this->getSparcTargetMachine() - .getSubtargetImpl() - ->insertNOPDoublePrecision()) { - addPass(new InsertNOPDoublePrecision(getSparcTargetMachine())); - } } -void SparcV8TargetMachine::anchor() {} +void SparcV8TargetMachine::anchor() { } SparcV8TargetMachine::SparcV8TargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, @@ -191,7 +176,7 @@ SparcV8TargetMachine::SparcV8TargetMachine(const Target &T, const Triple &TT, CodeGenOpt::Level OL) : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} -void SparcV9TargetMachine::anchor() {} +void SparcV9TargetMachine::anchor() { } SparcV9TargetMachine::SparcV9TargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, diff --git a/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.cpp b/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.cpp index 412e124..8fdde15 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.cpp @@ -16,20 +16,19 @@ using namespace llvm; const MCExpr *SparcELFTargetObjectFile::getTTypeGlobalReference( - const GlobalValue *GV, unsigned Encoding, Mangler &Mang, - const TargetMachine &TM, MachineModuleInfo *MMI, - MCStreamer &Streamer) const { + const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, + MachineModuleInfo *MMI, MCStreamer &Streamer) const { if (Encoding & dwarf::DW_EH_PE_pcrel) { MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); - MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", Mang, TM); + MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", 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()) { - MCSymbol *Sym = TM.getSymbol(GV, Mang); + MCSymbol *Sym = TM.getSymbol(GV); StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); } @@ -38,6 +37,6 @@ const MCExpr *SparcELFTargetObjectFile::getTTypeGlobalReference( MCSymbolRefExpr::create(SSym, Ctx), Ctx); } - return TargetLoweringObjectFileELF::getTTypeGlobalReference( - GV, Encoding, Mang, TM, MMI, Streamer); + return TargetLoweringObjectFileELF::getTTypeGlobalReference(GV, Encoding, TM, + MMI, Streamer); } diff --git a/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.h b/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.h index 76c8cca..fe88006 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.h +++ b/contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.h @@ -23,11 +23,11 @@ public: TargetLoweringObjectFileELF() {} - const MCExpr * - getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding, - Mangler &Mang, const TargetMachine &TM, - MachineModuleInfo *MMI, - MCStreamer &Streamer) const override; + const MCExpr *getTTypeGlobalReference(const GlobalValue *GV, + unsigned Encoding, + const TargetMachine &TM, + MachineModuleInfo *MMI, + MCStreamer &Streamer) const override; }; } // end namespace llvm diff --git a/contrib/llvm/lib/Target/Sparc/TargetInfo/SparcTargetInfo.cpp b/contrib/llvm/lib/Target/Sparc/TargetInfo/SparcTargetInfo.cpp index ab1c6be..66178ac 100644 --- a/contrib/llvm/lib/Target/Sparc/TargetInfo/SparcTargetInfo.cpp +++ b/contrib/llvm/lib/Target/Sparc/TargetInfo/SparcTargetInfo.cpp @@ -12,15 +12,24 @@ #include "llvm/Support/TargetRegistry.h" using namespace llvm; -Target llvm::TheSparcTarget; -Target llvm::TheSparcV9Target; -Target llvm::TheSparcelTarget; +Target &llvm::getTheSparcTarget() { + static Target TheSparcTarget; + return TheSparcTarget; +} +Target &llvm::getTheSparcV9Target() { + static Target TheSparcV9Target; + return TheSparcV9Target; +} +Target &llvm::getTheSparcelTarget() { + static Target TheSparcelTarget; + return TheSparcelTarget; +} extern "C" void LLVMInitializeSparcTargetInfo() { - RegisterTarget<Triple::sparc, /*HasJIT=*/true> X(TheSparcTarget, "sparc", + RegisterTarget<Triple::sparc, /*HasJIT=*/true> X(getTheSparcTarget(), "sparc", "Sparc"); - RegisterTarget<Triple::sparcv9, /*HasJIT=*/true> Y(TheSparcV9Target, + RegisterTarget<Triple::sparcv9, /*HasJIT=*/true> Y(getTheSparcV9Target(), "sparcv9", "Sparc V9"); - RegisterTarget<Triple::sparcel, /*HasJIT=*/true> Z(TheSparcelTarget, + RegisterTarget<Triple::sparcel, /*HasJIT=*/true> Z(getTheSparcelTarget(), "sparcel", "Sparc LE"); } |