CMSIS-DSP: Improve IPSS support in test framework.
diff --git a/CMSIS/DSP/Testing/FrameworkInclude/Test.h b/CMSIS/DSP/Testing/FrameworkInclude/Test.h
index 65ca317..699d4bf 100644
--- a/CMSIS/DSP/Testing/FrameworkInclude/Test.h
+++ b/CMSIS/DSP/Testing/FrameworkInclude/Test.h
@@ -570,7 +570,15 @@
          return(v->run(this));
       }
 
+      // Check if, for benchmark, we want to run the code once
+      // before benchmarking it, to force it to be in the I-cache.
+      bool isForcedInCache();
+
+      // Change the status of the forceInCache mode.
+      void setForceInCache(bool);
+
     private:
+        bool m_forcedInCache=false;
         // List of tests
         std::vector<test> m_tests;
         // List of tests IDs (since they are not contiguous
diff --git a/CMSIS/DSP/Testing/FrameworkSource/IORunner.cpp b/CMSIS/DSP/Testing/FrameworkSource/IORunner.cpp
index d195dc2..b975cde 100644
--- a/CMSIS/DSP/Testing/FrameworkSource/IORunner.cpp
+++ b/CMSIS/DSP/Testing/FrameworkSource/IORunner.cpp
@@ -206,7 +206,17 @@
                 // and do specific initialization for the tests
                 s->setUp(m_io->CurrentTestID(),params,m_mgr);
                 
-                   // Run the test
+                // Run the test once to force the code to be in cache.
+                // By default it is disabled in the suite.
+                if (s->isForcedInCache())
+                {
+                   if (!m_mgr->HasMemError())
+                   {
+                      (s->*t)();
+                   }
+                }
+
+                // Run the test
                 cycleMeasurementStart();
 #ifdef EXTBENCH
                 startSection();
diff --git a/CMSIS/DSP/Testing/FrameworkSource/Test.cpp b/CMSIS/DSP/Testing/FrameworkSource/Test.cpp
index 41c80f8..69a6215 100644
--- a/CMSIS/DSP/Testing/FrameworkSource/Test.cpp
+++ b/CMSIS/DSP/Testing/FrameworkSource/Test.cpp
@@ -70,6 +70,15 @@
     return(m_tests.size());
   }
 
+  bool Suite::isForcedInCache()
+  {
+      return(m_forcedInCache);
+  }
+      
+  void Suite::setForceInCache(bool status)
+  {
+      m_forcedInCache = status;
+  }
  
 
 
diff --git a/CMSIS/DSP/Testing/FrameworkSource/Timing.cpp b/CMSIS/DSP/Testing/FrameworkSource/Timing.cpp
index b51be60..ccf7c13 100644
--- a/CMSIS/DSP/Testing/FrameworkSource/Timing.cpp
+++ b/CMSIS/DSP/Testing/FrameworkSource/Timing.cpp
@@ -69,7 +69,7 @@
 void initCycleMeasurement()
 {
 #ifdef CORTEXM
-    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk;
+    SysTick->CTRL = 0;
     SysTick->LOAD = SYSTICK_INITIAL_VALUE;
 #endif 
 
@@ -106,17 +106,15 @@
 {
 #ifndef EXTBENCH
 #ifdef CORTEXM
-    /* 
-    TODO:
-    This code is likely to be wrong. Don't rely on it for benchmarks.
-
-    */
-    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk;
+   
+    SysTick->CTRL = 0;
     SysTick->LOAD = SYSTICK_INITIAL_VALUE;
+    SysTick->VAL = 0;
 
     SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_CLKSOURCE_Msk;  
 
     while(SysTick->VAL == 0);
+    
 
     startCycles = SysTick->VAL;
 
@@ -138,7 +136,7 @@
 {
 #ifndef EXTBENCH
 #ifdef CORTEXM
-    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk;
+    SysTick->CTRL = 0;
     SysTick->LOAD = SYSTICK_INITIAL_VALUE;
 #endif
 #endif
@@ -148,7 +146,16 @@
 {
 #ifdef CORTEXM
     uint32_t v = SysTick->VAL;
-    return(startCycles - v);
+    Testing::cycles_t result;
+    if (v < startCycles)
+    {
+      result = startCycles - v;
+    }
+    else
+    {
+      result = SYSTICK_INITIAL_VALUE - (v - startCycles);
+    }
+    return(result);
 #endif 
 
 #ifdef CORTEXA
diff --git a/CMSIS/DSP/Testing/TestScripts/Regression/Commands.py b/CMSIS/DSP/Testing/TestScripts/Regression/Commands.py
index a9e94c8..128fdb6 100755
--- a/CMSIS/DSP/Testing/TestScripts/Regression/Commands.py
+++ b/CMSIS/DSP/Testing/TestScripts/Regression/Commands.py
@@ -8,6 +8,7 @@
 import shutil
 import glob
 from pathlib import Path
+import sys
 
 DEBUGMODE = False
 KEEPBUILDFOLDER = False
@@ -141,9 +142,9 @@
            with open(os.path.join(self.archiveLogPath(),"makelog_%s.txt" % test),"w") as makelog:
                with open(os.path.join(self.archiveErrorPath(),"makeerror_%s.txt" % test),"w") as makeerr:
                     if DEBUGMODE:
-                       completed=subprocess.run(["make","-j8","VERBOSE=1"],timeout=3600)
+                       completed=subprocess.run(["make","-j4","VERBOSE=1"],timeout=3600)
                     else:
-                       completed=subprocess.run(["make","-j8","VERBOSE=1"],stdout=makelog,stderr=makeerr,timeout=3600)
+                       completed=subprocess.run(["make","-j4","VERBOSE=1"],stdout=makelog,stderr=makeerr,timeout=3600)
         # Restore environment variables
         self.restoreEnv()
         check(completed)
@@ -281,7 +282,7 @@
 
     # Process a test from the test description file
     def processTest(self):
-        completed=subprocess.run(["python","processTests.py","-e",self.testName()],timeout=3600)
+        completed=subprocess.run([sys.executable,"processTests.py","-e",self.testName()],timeout=3600)
         check(completed)
 
     def getResultPath(self):
@@ -309,7 +310,7 @@
     def processResult(self):
         msg("  Parse result for %s\n" % self.testName())
         with open(os.path.join(self.buildConfig().archiveResultPath(),"processedResult_%s.txt" % self.testName()),"w") as presult:
-             completed=subprocess.run(["python","processResult.py","-e","-r",self.getResultPath()],stdout=presult,timeout=3600)
+             completed=subprocess.run([sys.executable,"processResult.py","-e","-r",self.getResultPath()],stdout=presult,timeout=3600)
         # When a test fail, the regression is continuing but we
         # track that a test has failed
         if completed.returncode==0:
@@ -345,14 +346,14 @@
 # Preprocess the test description
 def preprocess(desc):
     msg("Process test description file %s\n" % desc)
-    completed = subprocess.run(["python", "preprocess.py","-f",desc],timeout=3600)
+    completed = subprocess.run([sys.executable, "preprocess.py","-f",desc],timeout=3600)
     check(completed)
 
 # Generate all missing C code by using all classes in the
 # test description file
 def generateAllCCode():
     msg("Generate all missing C files\n")
-    completed = subprocess.run(["python","processTests.py", "-e"],timeout=3600)
+    completed = subprocess.run([sys.executable,"processTests.py", "-e"],timeout=3600)
     check(completed)
 
 
diff --git a/CMSIS/DSP/Testing/main.cpp b/CMSIS/DSP/Testing/main.cpp
index d9de3636..4999047 100644
--- a/CMSIS/DSP/Testing/main.cpp
+++ b/CMSIS/DSP/Testing/main.cpp
@@ -1,5 +1,7 @@
+#include <stdio.h>
 extern int testmain();
 
+
 int main()
 {
     return(testmain());
diff --git a/CMSIS/DSP/Testing/testmain.cpp b/CMSIS/DSP/Testing/testmain.cpp
index a7ff79c..14293c6 100644
--- a/CMSIS/DSP/Testing/testmain.cpp
+++ b/CMSIS/DSP/Testing/testmain.cpp
@@ -27,9 +27,6 @@
 {
     char *memoryBuf=NULL;
 
-
-
-  
     memoryBuf = (char*)malloc(MEMSIZE);
     if (memoryBuf !=NULL)
     {