From cb4da6380c6af2bce871ae466f1ba445339adc3a Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Sun, 10 Nov 2013 23:20:46 +0100
Subject: [PATCH] Support MIPS atomic on pre-MIPS32 architectures

The atomic functions on MIPS are based on the sync opcode with an
immediate argument, which is something introduced in the MIPS32
instruction set. This prevent to use Qt on pre-MIPS32 CPU, like the
Loongson 2 CPU.

However some of the pre-MIPS32 CPUs interprets the sync opcode with and
immediate argument as a sync opcode without argument (which is a stronger
ordering than with the argument), and for the others the kernel emulates
it.

It is therefore fine to use the current MIPS atomic functions on
pre-MIPS32 CPU. This patch allows that by temporarily changing the
instruction set to MIPS32 around the sync instruction, so that binutils
doesn't choke on it.

Change-Id: I9cc984bd55b5f172736ce9e638a6f4e271b79fe7
---
 src/corelib/arch/qatomic_mips.h | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/corelib/arch/qatomic_mips.h b/src/corelib/arch/qatomic_mips.h
index 6eb9613..dab72a2 100644
--- a/src/corelib/arch/qatomic_mips.h
+++ b/src/corelib/arch/qatomic_mips.h
@@ -119,13 +119,19 @@ template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)>
 template <int size> template <typename T> inline
 void QBasicAtomicOps<size>::acquireMemoryFence(const T &) Q_DECL_NOTHROW
 {
-    asm volatile ("sync 0x11" ::: "memory");
+    asm volatile (".set push\n"
+                  ".set mips32\n"
+                  "sync 0x11\n"
+                  ".set pop\n" ::: "memory");
 }
 
 template <int size> template <typename T> inline
 void QBasicAtomicOps<size>::releaseMemoryFence(const T &) Q_DECL_NOTHROW
 {
-    asm volatile ("sync 0x12" ::: "memory");
+    asm volatile (".set push\n"
+                  ".set mips32\n"
+                  "sync 0x11\n"
+                  ".set pop\n" ::: "memory");
 }
 
 template <int size> template <typename T> inline
-- 
1.8.4.2

