Add a control to disable the Poly1305 NEON code.

Some phones have a buggy NEON unit and the Poly1305 NEON code fails on
them, even though other NEON code appears to work fine.

This change:

1) Fixes a bug where NEON was assumed even when the code wasn't compiled
   in NEON mode.

2) Adds a second NEON control bit that can be disabled in order to run
   NEON code, but not the Poly1305 NEON code.

https://code.google.com/p/chromium/issues/detail?id=341598

Change-Id: Icb121bf8dba47c7a46c7667f676ff7a4bc973625
Reviewed-on: https://boringssl-review.googlesource.com/1351
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/cpu-arm.c b/crypto/cpu-arm.c
index 8b97fc1..814df26 100644
--- a/crypto/cpu-arm.c
+++ b/crypto/cpu-arm.c
@@ -64,9 +64,9 @@
 #include "arm_arch.h"
 
 #if defined(__ARM_NEON__)
-uint32_t OPENSSL_armcap_P = ARMV7_NEON;
+uint32_t OPENSSL_armcap_P = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
 #else
-uint32_t OPENSSL_armcap_P = ARMV7_NEON;
+uint32_t OPENSSL_armcap_P = ARMV7_NEON_FUNCTIONAL;
 #endif
 
 char CRYPTO_is_NEON_capable() {
@@ -81,4 +81,17 @@
   }
 }
 
+char CRYPTO_is_NEON_functional() {
+  static const uint32_t kWantFlags = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
+  return (OPENSSL_armcap_P & kWantFlags) == kWantFlags;
+}
+
+void CRYPTO_set_NEON_functional(char neon_functional) {
+  if (neon_functional) {
+    OPENSSL_armcap_P |= ARMV7_NEON_FUNCTIONAL;
+  } else {
+    OPENSSL_armcap_P &= ~ARMV7_NEON_FUNCTIONAL;
+  }
+}
+
 #endif  /* defined(OPENSSL_ARM) */