From 4e457165ee019fb9002b53ffa9a5f95b99b22113 Mon Sep 17 00:00:00 2001
From: Jorrit Rouwe <jrouwe@gmail.com>
Date: Mon, 10 Apr 2023 16:46:28 +0200
Subject: [PATCH] Experimental linux armv7a support (#500)

---
 Build/Android/build.gradle |  2 +-
 Jolt/Core/FPControlWord.h  | 33 ++++++++++++++++++++++++++++++++-
 Jolt/Core/TickCounter.h    |  4 +++-
 3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/Build/Android/build.gradle b/Build/Android/build.gradle
index 04bc67d84..de0c8f88b 100644
--- a/Build/Android/build.gradle
+++ b/Build/Android/build.gradle
@@ -5,7 +5,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:7.4.1'
+        classpath 'com.android.tools.build:gradle:7.4.2'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
diff --git a/Jolt/Core/FPControlWord.h b/Jolt/Core/FPControlWord.h
index 9c47a040a..b66344da0 100644
--- a/Jolt/Core/FPControlWord.h
+++ b/Jolt/Core/FPControlWord.h
@@ -60,7 +60,7 @@ class FPControlWord : public NonCopyable
 	unsigned int mPrevState;
 };
 
-#elif defined(JPH_CPU_ARM)
+#elif defined(JPH_CPU_ARM) && defined(JPH_USE_NEON)
 
 /// Helper class that needs to be put on the stack to update the state of the floating point control word.
 /// This state is kept per thread.
@@ -91,6 +91,37 @@ class FPControlWord : public NonCopyable
 	uint64		mPrevState;
 };
 
+#elif defined(JPH_CPU_ARM)
+
+/// Helper class that needs to be put on the stack to update the state of the floating point control word.
+/// This state is kept per thread.
+template <uint32 Value, uint32 Mask>
+class FPControlWord : public NonCopyable
+{
+public:
+	FPControlWord()
+	{
+		uint32 val;
+		asm volatile("vmrs %0, fpscr" : "=r" (val));
+		mPrevState = val;
+		val &= ~Mask;
+		val |= Value;
+		asm volatile("vmsr fpscr, %0" : /* no output */ : "r" (val));
+	}
+
+	~FPControlWord()
+	{
+		uint32 val;
+		asm volatile("vmrs %0, fpscr" : "=r" (val));
+		val &= ~Mask;
+		val |= mPrevState & Mask;
+		asm volatile("vmsr fpscr, %0" : /* no output */ : "r" (val));
+	}
+
+private:
+	uint32		mPrevState;
+};
+
 #elif defined(JPH_CPU_WASM)
 
 // Not supported
diff --git a/Jolt/Core/TickCounter.h b/Jolt/Core/TickCounter.h
index a9d1272a3..9a8967d31 100644
--- a/Jolt/Core/TickCounter.h
+++ b/Jolt/Core/TickCounter.h
@@ -27,10 +27,12 @@ JPH_INLINE uint64 GetProcessorTickCount()
 	return JPH_PLATFORM_BLUE_GET_TICKS();
 #elif defined(JPH_CPU_X86)
 	return __rdtsc();
-#elif defined(JPH_CPU_ARM)
+#elif defined(JPH_CPU_ARM) && defined(JPH_USE_NEON)
 	uint64 val;
 	asm volatile("mrs %0, cntvct_el0" : "=r" (val));
 	return val;
+#elif defined(JPH_CPU_ARM)
+	return 0; // Not supported
 #elif defined(JPH_CPU_WASM)
 	return 0; // Not supported
 #else
