"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",
// LEON 2 FT (AT697E)
// TO DO: Place-holder: Processor specific features will be added *very* soon here.
def : Processor<"at697e", LEON2Itineraries,
- [FeatureLeon, InsertNOPLoad]>;
+ [FeatureLeon, ReplaceSDIV, InsertNOPLoad]>;
// LEON 2 FT (AT697F)
// TO DO: Place-holder: Processor specific features will be added *very* soon here.
// 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;
}
// Leon features
HasLeonCasa = false;
HasUmacSmac = false;
+ PerformSDIVReplace = false;
InsertNOPLoad = false;
FixFSMULD = false;
ReplaceFMULS = false;
bool FixFSMULD;
bool ReplaceFMULS;
bool FixAllFDIVSQRT;
+ bool PerformSDIVReplace;
SparcInstrInfo InstrInfo;
SparcTargetLowering TLInfo;
// Leon options
bool hasUmacSmac() const { return HasUmacSmac; }
+ bool performSDIVReplace() const { return PerformSDIVReplace; }
bool hasLeonCasa() const { return HasLeonCasa; }
bool insertNOPLoad() const { return InsertNOPLoad; }
bool fixFSMULD() const { return FixFSMULD; }
--- /dev/null
+; RUN: llc %s -O0 -march=sparc -o - | FileCheck %s -check-prefix=NO_REPLACE_SDIV
+; RUN: llc %s -O0 -march=sparc -mcpu=at697e -o - | FileCheck %s -check-prefix=REPLACE_SDIV
+
+; REPLACE_SDIV: sdivcc %o0, %o1, %o0
+; NO_REPLACE_SDIV: sdiv %o0, %o1, %o0
+
+define i32 @lbr59(i32 %a, i32 %b)
+{
+ %r = sdiv i32 %a, %b
+ ret i32 %r
+}