summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/Sparc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/Sparc')
-rw-r--r--contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp32
-rw-r--r--contrib/llvm/lib/Target/Sparc/DelaySlotFiller.cpp6
-rw-r--r--contrib/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp10
-rwxr-xr-xcontrib/llvm/lib/Target/Sparc/LeonFeatures.td131
-rwxr-xr-xcontrib/llvm/lib/Target/Sparc/LeonPasses.cpp645
-rwxr-xr-xcontrib/llvm/lib/Target/Sparc/LeonPasses.h114
-rw-r--r--contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp3
-rw-r--r--contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp17
-rw-r--r--contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp15
-rw-r--r--contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h10
-rw-r--r--contrib/llvm/lib/Target/Sparc/Sparc.td147
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp10
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcFrameLowering.cpp49
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp21
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp151
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp46
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcInstrInfo.h10
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcInstrInfo.td24
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcRegisterInfo.td1
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcSubtarget.cpp9
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcSubtarget.h20
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp57
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.cpp13
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcTargetObjectFile.h10
-rw-r--r--contrib/llvm/lib/Target/Sparc/TargetInfo/SparcTargetInfo.cpp21
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");
}
OpenPOWER on IntegriCloud