]> granicus.if.org Git - llvm/commitdiff
This pass, fixing an erratum in some LEON 2 processors ensures that the SDIV instruct...
authorChris Dewhurst <chris.dewhurst@lero.ie>
Mon, 10 Oct 2016 08:53:06 +0000 (08:53 +0000)
committerChris Dewhurst <chris.dewhurst@lero.ie>
Mon, 10 Oct 2016 08:53:06 +0000 (08:53 +0000)
Differential Review: https://reviews.llvm.org/D24660

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283727 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Sparc/LeonFeatures.td
lib/Target/Sparc/Sparc.td
lib/Target/Sparc/SparcISelDAGToDAG.cpp
lib/Target/Sparc/SparcSubtarget.cpp
lib/Target/Sparc/SparcSubtarget.h
test/CodeGen/SPARC/LeonReplaceSDIVPassUT.ll [new file with mode: 0644]

index e2282abbbdba34bf808961604a580a6a996fcbb8..27d739b5a8583420dcf793507c422f3897409c39 100755 (executable)
@@ -37,6 +37,14 @@ def LeonCASA : SubtargetFeature<
   "Enable CASA instruction for LEON3 and LEON4 processors"
 >;
 
+
+def ReplaceSDIV : SubtargetFeature<
+  "replacesdiv",
+  "PerformSDIVReplace",
+  "true",
+  "AT697E erratum fix: Do not emit SDIV, emit SDIVCC instead"
+>;
+          
 def InsertNOPLoad: SubtargetFeature<
   "insertnopload",
   "InsertNOPLoad",
index bdbdc1c6c1a3afc23449b258196540587a9c7628..11004c5a952fc9b934eef0b9ade4d14dc483b193 100644 (file)
@@ -110,7 +110,7 @@ def : Processor<"leon2", LEON2Itineraries,
 // LEON 2 FT (AT697E)
 // TO DO: Place-holder: Processor specific features will be added *very* soon here.
 def : Processor<"at697e", LEON2Itineraries,
-                [FeatureLeon, InsertNOPLoad]>;
+                [FeatureLeon, ReplaceSDIV, InsertNOPLoad]>;
 
 // LEON 2 FT (AT697F)
 // TO DO: Place-holder: Processor specific features will be added *very* soon here.
index a16cd32484acecfbbb75529fddc46897fffd00c8..c36e75d1b0761f2023f48ecc571c7b7543007607 100644 (file)
@@ -360,6 +360,12 @@ 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;
   }
index 97d4aef3378cc30f9a0cd935cdfdfb51970c4b07..75ea4c7c8f57710d8576ab8daf868c0815c9aff6 100644 (file)
@@ -39,6 +39,7 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU,
   // Leon features
   HasLeonCasa = false;
   HasUmacSmac = false;
+  PerformSDIVReplace = false;
   InsertNOPLoad = false;
   FixFSMULD = false;
   ReplaceFMULS = false;
index 9122f54f7c85a6b1d23298748f20e31ccaf745bb..25dc4291c44f3de5c10ab63a99a649ff1cc4dbf4 100644 (file)
@@ -48,6 +48,7 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
   bool FixFSMULD;
   bool ReplaceFMULS;
   bool FixAllFDIVSQRT;
+  bool PerformSDIVReplace;
 
   SparcInstrInfo InstrInfo;
   SparcTargetLowering TLInfo;
@@ -86,6 +87,7 @@ public:
 
   // 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; }
diff --git a/test/CodeGen/SPARC/LeonReplaceSDIVPassUT.ll b/test/CodeGen/SPARC/LeonReplaceSDIVPassUT.ll
new file mode 100644 (file)
index 0000000..4c5ccc0
--- /dev/null
@@ -0,0 +1,11 @@
+; 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 
+}