Fix unified asm syntax issue

Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h
index 3c82bd5..35b0ee8 100644
--- a/library/constant_time_impl.h
+++ b/library/constant_time_impl.h
@@ -134,14 +134,39 @@
     return (mbedtls_ct_condition_t) x;
 #elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32)
     uint32_t s;
-    asm volatile ("neg %[s], %[x]                       \n\t"
-                  "orr %[x], %[x], %[s]                 \n\t"
-                  "asr %[x], %[x], #31"
+    /*
+     * Selecting unified syntax is needed for gcc, and harmless on clang.
+     *
+     * This is needed because on Thumb 1, condition flags are always set, so
+     * e.g. "negs" is supported but "neg" is not (on Thumb 2, both exist).
+     *
+     * Under Thumb 1 unified syntax, only the "negs" form is accepted, and
+     * under divided syntax, only the "neg" form is accepted. clang only
+     * supports unified syntax.
+     *
+     * On Thumb 2 and Arm, both compilers are happy with the "s" suffix,
+     * although we don't actually care about setting the flags.
+     *
+     * For gcc, restore divided syntax afterwards - otherwise old versions of gcc
+     * seem to apply unified syntax globally, which breaks other asm code.
+     */
+#if !defined(__clang__)
+#define RESTORE_ASM_SYNTAX  ".syntax divided             \n\t"
+#else
+#define RESTORE_ASM_SYNTAX
+#endif
+
+    asm volatile (".syntax unified                       \n\t"
+                  "negs %[s], %[x]                       \n\t"
+                  "orrs %[x], %[x], %[s]                 \n\t"
+                  "asrs %[x], %[x], #31                  \n\t"
+                  RESTORE_ASM_SYNTAX
                   :
                   [s] "=&l" (s),
                   [x] "+&l" (x)
                   :
                   :
+                  "cc" /* clobbers flag bits */
                   );
     return (mbedtls_ct_condition_t) x;
 #else
@@ -178,16 +203,19 @@
                   );
     return (mbedtls_ct_uint_t) condition;
 #elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32)
-    asm volatile ("and %[if1], %[if1], %[condition]          \n\t"
-                  "mvn %[condition], %[condition]            \n\t"
-                  "and %[condition], %[condition], %[if0]    \n\t"
-                  "orr %[condition], %[if1], %[condition]"
+    asm volatile (".syntax unified                           \n\t"
+                  "ands %[if1], %[if1], %[condition]         \n\t"
+                  "mvns %[condition], %[condition]           \n\t"
+                  "ands %[condition], %[condition], %[if0]   \n\t"
+                  "orrs %[condition], %[if1], %[condition]   \n\t"
+                  RESTORE_ASM_SYNTAX
                   :
                   [condition] "+&l" (condition),
                   [if1] "+&l" (if1)
                   :
                   [if0] "l" (if0)
                   :
+                  "cc"
                   );
     return (mbedtls_ct_uint_t) condition;
 #else
@@ -215,20 +243,23 @@
 #elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32)
     uint32_t s1;
     asm volatile (
+        ".syntax unified                    \n\t"
 #if defined(__thumb__) && !defined(__thumb2__)
-        "mov     %[s1], %[x]                \n\t"
-        "eor     %[s1], %[s1], %[y]         \n\t"
+        "movs     %[s1], %[x]               \n\t"
+        "eors     %[s1], %[s1], %[y]        \n\t"
 #else
-        "eor     %[s1], %[x], %[y]          \n\t"
+        "eors     %[s1], %[x], %[y]         \n\t"
 #endif
-        "sub     %[x], %[x], %[y]           \n\t"
-        "bic     %[x], %[x], %[s1]          \n\t"
-        "and     %[y], %[s1], %[y]          \n\t"
-        "orr     %[x], %[x], %[y]           \n\t"
-        "asr     %[x], %[x], #31"
+        "subs    %[x], %[x], %[y]           \n\t"
+        "bics    %[x], %[x], %[s1]          \n\t"
+        "ands    %[y], %[s1], %[y]          \n\t"
+        "orrs    %[x], %[x], %[y]           \n\t"
+        "asrs    %[x], %[x], #31            \n\t"
+        RESTORE_ASM_SYNTAX
         : [s1] "=&l" (s1), [x] "+&l" (x),  [y] "+&l" (y)
         :
         :
+        "cc"
         );
     return (mbedtls_ct_condition_t) x;
 #else