Use the ARM assembly code in mpi_arm.c for iOS.

For Mac OS X and iOS, use a forced include file
(mozilla/security/nss/lib/freebl/build_config_mac.h) to define the
processor architecture specific macros used by NSS's lib/freebl
code.

R=droger@chromium.org,mark@chromium.org,rsleevi@chromium.org
BUG=139432
TEST=no build error or net_unittests failure. Visit https://www.google.com/
on iOS.

Review URL: https://chromiumcodereview.appspot.com/10828060

git-svn-id: http://src.chromium.org/svn/trunk/deps/third_party/nss@179928 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
diff --git a/README.chromium b/README.chromium
index 09c93ac..5f01400 100644
--- a/README.chromium
+++ b/README.chromium
@@ -53,6 +53,14 @@
   building nss as a dynamic library (crnss.dll).
 - mozilla/security/nss/lib/ckfw/builtins/certdata.c: a generated file.
   Do an upstream NSS build and copy the generated certdata.c.
+- mozilla/security/nss/lib/freebl/build_config_mac.h: a header that defines
+  the target arch specific configuration macros for lib/freebl on iOS and
+  Mac OS X. This works around the lack of support for the xcode_settings
+  GCC_PREPROCESSOR_DEFINITIONS[arch=foo] by the ninja GYP generator
+  (http://crbug.com/122592).
+- mozilla/security/nss/lib/freebl/mpi/mpi_arm_mac.c: a wrapper file for
+  mpi_arm.c for iOS and Mac OS X. This works around the inability to
+  specify target arch specific source files in Xcode. 
 - patches/nss-remove-fortezza.patch: remove Fortezza certificate support
   from PK11_ImportPublicKey.  See NSS bug 668397
   (https://bugzilla.mozilla.org/show_bug.cgi?id=668397).
diff --git a/mozilla/security/nss/lib/freebl/build_config_mac.h b/mozilla/security/nss/lib/freebl/build_config_mac.h
new file mode 100644
index 0000000..7dee72a
--- /dev/null
+++ b/mozilla/security/nss/lib/freebl/build_config_mac.h
@@ -0,0 +1,36 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * This header defines the configuration macros used by lib/freebl files
+ * for iOS and Mac OS X. It is included with the -include compiler flag.
+ */
+#if !defined(__APPLE__)
+#error This file is intended for iOS and Mac OS X only
+#endif
+
+#if defined(__i386__)
+
+#define NSS_X86_OR_X64 1
+#define NSS_X86 1
+#define i386 1
+
+#elif defined(__x86_64__)
+
+#define NSS_USE_64 1
+#define NSS_X86_OR_X64 1
+#define NSS_X64 1
+
+#elif defined(__arm__)
+
+#define MP_ASSEMBLY_MULTIPLY 1
+#define MP_ASSEMBLY_SQUARE 1
+#define MP_USE_UINT_DIGIT 1
+#define SHA_NO_LONG_LONG 1
+
+#else
+
+#error unknown processor architecture
+
+#endif
diff --git a/mozilla/security/nss/lib/freebl/mpi/mpi_arm.c b/mozilla/security/nss/lib/freebl/mpi/mpi_arm.c
new file mode 100644
index 0000000..9199aab
--- /dev/null
+++ b/mozilla/security/nss/lib/freebl/mpi/mpi_arm.c
@@ -0,0 +1,171 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* This inlined version is for 32-bit ARM platform only */
+
+#if !defined(__arm__)
+#error "This is for ARM only"
+#endif
+
+/* 16-bit thumb doesn't work inlined assember version */
+#if (!defined(__thumb__) || defined(__thumb2__)) && !defined(__ARM_ARCH_3__)
+
+#include "mpi-priv.h"
+
+#ifdef MP_ASSEMBLY_MULTIPLY
+void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
+{
+  __asm__ __volatile__(
+    "mov     r5, #0\n"
+#ifdef __thumb2__
+    "cbz     %1, 2f\n"
+#else
+    "cmp     %1, r5\n" /* r5 is 0 now */
+    "beq     2f\n"
+#endif
+
+    "1:\n"
+    "mov     r4, #0\n"
+    "ldr     r6, [%0], #4\n"
+    "umlal   r5, r4, r6, %2\n"
+    "str     r5, [%3], #4\n"
+    "mov     r5, r4\n"
+
+    "subs    %1, #1\n"
+    "bne     1b\n"
+
+    "2:\n"
+    "str     r5, [%3]\n"
+  :
+  : "r"(a), "r"(a_len), "r"(b), "r"(c)
+  : "memory", "cc", "%r4", "%r5", "%r6");
+}
+
+void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
+{
+  __asm__ __volatile__(
+    "mov     r5, #0\n"
+#ifdef __thumb2__
+    "cbz     %1, 2f\n"
+#else
+    "cmp     %1, r5\n" /* r5 is 0 now */
+    "beq     2f\n"
+#endif
+
+    "1:\n"
+    "mov     r4, #0\n"
+    "ldr     r6, [%3]\n"
+    "adds    r5, r6\n"
+    "adc     r4, r4, #0\n"
+
+    "ldr     r6, [%0], #4\n"
+    "umlal   r5, r4, r6, %2\n"
+    "str     r5, [%3], #4\n"
+    "mov     r5, r4\n"
+
+    "subs    %1, #1\n"
+    "bne     1b\n"
+
+    "2:\n"
+    "str     r5, [%3]\n"
+    :
+    : "r"(a), "r"(a_len), "r"(b), "r"(c)
+    : "memory", "cc", "%r4", "%r5", "%r6");
+}
+
+void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
+{
+  if (!a_len)
+    return;
+
+  __asm__ __volatile__(
+    "mov     r5, #0\n"
+
+    "1:\n"
+    "mov     r4, #0\n"
+    "ldr     r6, [%3]\n"
+    "adds    r5, r6\n"
+    "adc     r4, r4, #0\n"
+    "ldr     r6, [%0], #4\n"
+    "umlal   r5, r4, r6, %2\n"
+    "str     r5, [%3], #4\n"
+    "mov     r5, r4\n"
+
+    "subs    %1, #1\n"
+    "bne     1b\n"
+
+#ifdef __thumb2__
+    "cbz     r4, 3f\n"
+#else
+    "cmp     r4, #0\n"
+    "beq     3f\n"
+#endif
+
+    "2:\n"
+    "mov     r4, #0\n"
+    "ldr     r6, [%3]\n"
+    "adds    r5, r6\n"
+    "adc     r4, r4, #0\n"
+    "str     r5, [%3], #4\n"
+    "movs    r5, r4\n"
+    "bne     2b\n"
+
+    "3:\n"
+    :
+    : "r"(a), "r"(a_len), "r"(b), "r"(c)
+    : "memory", "cc", "%r4", "%r5", "%r6");
+}
+#endif
+
+#ifdef MP_ASSEMBLY_SQUARE
+void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
+{
+  if (!a_len)
+    return;
+
+  __asm__ __volatile__(
+    "mov     r3, #0\n"
+
+    "1:\n"
+    "mov     r4, #0\n"
+    "ldr     r6, [%0], #4\n"
+    "ldr     r5, [%2]\n"
+    "adds    r3, r5\n"
+    "adc     r4, r4, #0\n"
+    "umlal   r3, r4, r6, r6\n" /* w = r3:r4 */
+    "str     r3, [%2], #4\n"
+
+    "ldr     r5, [%2]\n"
+    "adds    r3, r4, r5\n"
+    "mov     r4, #0\n"
+    "adc     r4, r4, #0\n"
+    "str     r3, [%2], #4\n"
+    "mov     r3, r4\n"
+
+    "subs    %1, #1\n"
+    "bne     1b\n"
+
+#ifdef __thumb2__
+    "cbz     r3, 3f\n"
+#else
+    "cmp     r3, #0\n"
+    "beq     3f\n"
+#endif
+
+    "2:\n"
+    "mov     r4, #0\n"
+    "ldr     r5, [%2]\n"
+    "adds    r3, r5\n"
+    "adc     r4, r4, #0\n"
+    "str     r3, [%2], #4\n"
+    "movs    r3, r4\n"
+    "bne     2b\n"
+
+    "3:"
+    :
+    : "r"(pa), "r"(a_len), "r"(ps)
+    : "memory", "cc", "%r3", "%r4", "%r5", "%r6");
+}
+#endif
+#endif
diff --git a/mozilla/security/nss/lib/freebl/mpi/mpi_arm_mac.c b/mozilla/security/nss/lib/freebl/mpi/mpi_arm_mac.c
new file mode 100644
index 0000000..4dafc11
--- /dev/null
+++ b/mozilla/security/nss/lib/freebl/mpi/mpi_arm_mac.c
@@ -0,0 +1,19 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* 
+ * A wrapper file for mpi_arm.c on iOS and Mac OS X.
+ *
+ * Xcode does not support target arch specific source files. This
+ * wrapper file allows Xcode to compile mpi_arm.c only when the
+ * target arch is arm.
+ */
+
+#if !defined(__APPLE__)
+#error This file is intended for iOS and Mac OS X only
+#endif
+
+#if defined(__arm__)
+#include "mpi_arm.c"
+#endif
diff --git a/nss.gyp b/nss.gyp
index f0b31d8..1322358 100644
--- a/nss.gyp
+++ b/nss.gyp
@@ -540,6 +540,7 @@
         'mozilla/security/nss/lib/freebl/blapi.h',
         'mozilla/security/nss/lib/freebl/blapii.h',
         'mozilla/security/nss/lib/freebl/blapit.h',
+        'mozilla/security/nss/lib/freebl/build_config_mac.h',
         'mozilla/security/nss/lib/freebl/camellia.c',
         'mozilla/security/nss/lib/freebl/camellia.h',
         'mozilla/security/nss/lib/freebl/ctr.c',
@@ -582,6 +583,8 @@
         'mozilla/security/nss/lib/freebl/mpi/mpi.c',
         'mozilla/security/nss/lib/freebl/mpi/mpi.h',
         'mozilla/security/nss/lib/freebl/mpi/mpi_amd64.c',
+        'mozilla/security/nss/lib/freebl/mpi/mpi_arm.c',
+        'mozilla/security/nss/lib/freebl/mpi/mpi_arm_mac.c',
         'mozilla/security/nss/lib/freebl/mpi/mpi_x86_asm.c',
         'mozilla/security/nss/lib/freebl/mpi/mplogic.c',
         'mozilla/security/nss/lib/freebl/mpi/mplogic.h',
@@ -946,6 +949,10 @@
         'mozilla/security/nss/lib/util/utilrename.h',
       ],
       'sources!': [
+        # mpi_arm.c is included by mpi_arm_mac.c.
+        # NOTE: mpi_arm.c can be used directly on Linux. mpi_arm.c will need
+        # to be excluded conditionally if we start to build NSS on Linux.
+        'mozilla/security/nss/lib/freebl/mpi/mpi_arm.c',
         # primes.c is included by mpprime.c.
         'mozilla/security/nss/lib/freebl/mpi/primes.c',
         # unix_rand.c and win_rand.c are included by sysrand.c.
@@ -1056,8 +1063,8 @@
           ],
         }],
         ['target_arch=="ia32"', {
-          'sources/': [
-            ['exclude', 'amd64'],
+          'sources!': [
+            'mozilla/security/nss/lib/freebl/mpi/mpi_amd64.c',
           ],
         }],
         ['OS=="mac" or OS=="ios"', {
@@ -1072,29 +1079,26 @@
           ],
           'sources!': [
             'mozilla/security/nss/lib/freebl/mpi/mpi_amd64.c',
-            'mozilla/security/nss/lib/freebl/mpi/mpi_x86_asm.c',
           ],
+          'variables': {
+            'forced_include_file': '<(DEPTH)/third_party/nss/mozilla/security/nss/lib/freebl/build_config_mac.h',
+          },
           'xcode_settings': {
             'conditions': [
               ['component == "shared_library"', {
                 'GCC_SYMBOLS_PRIVATE_EXTERN': 'NO',  # no -fvisibility=hidden
               }],
             ],
-            # Can't use 'target_arch=="ia32"' conditional because that is
-            # only checked at GYP file generation time.
-            'GCC_PREPROCESSOR_DEFINITIONS[arch=i386]': [
-              '$(inherited)',
-              'NSS_X86_OR_X64',
-              'NSS_X86',
-              'i386',
-            ],
-            'GCC_PREPROCESSOR_DEFINITIONS[arch=x86_64]': [
-              '$(inherited)',
-              'NSS_USE_64',
-              'NSS_X86_OR_X64',
-              'NSS_X64',
+            # Define processor architecture specific macros in
+            # <(forced_include_file).
+            'OTHER_CFLAGS': [
+              '-include', '<(forced_include_file)',
             ],
           },
+        }, { # else: OS!="mac" and OS!="ios"
+          'sources!': [
+            'mozilla/security/nss/lib/freebl/mpi/mpi_arm_mac.c',
+          ],
         }],
         ['OS=="win"', {
           'defines': [
@@ -1137,6 +1141,11 @@
               ],
             }],
           ],
+        }, { # else: OS!="win"
+          'sources!': [
+            # mpi_x86_asm.c contains MSVC inline assembly code.
+            'mozilla/security/nss/lib/freebl/mpi/mpi_x86_asm.c',
+          ],
         }],
         ['clang==1', {
           'xcode_settings': {
diff --git a/scripts/nss-checkout.sh b/scripts/nss-checkout.sh
index f34a375..f977f5a 100755
--- a/scripts/nss-checkout.sh
+++ b/scripts/nss-checkout.sh
@@ -76,9 +76,9 @@
     ! -name mpcpucache.c \
     ! -name mpi-config.h \
     ! -name mpi-priv.h ! -name mpi.c ! -name mpi.h \
-    ! -name mpi_amd64.c ! -name mpi_x86_asm.c ! -name mplogic.c \
-    ! -name mplogic.h ! -name mpmontg.c ! -name mpprime.c \
-    ! -name mpprime.h \
+    ! -name mpi_amd64.c ! -name mpi_arm.c ! -name mpi_x86_asm.c \
+    ! -name mplogic.c ! -name mplogic.h ! -name mpmontg.c \
+    ! -name mpprime.c ! -name mpprime.h \
     ! -name mp_gf2m-priv.h ! -name mp_gf2m.c ! -name mp_gf2m.h \
     ! -name primes.c ! -name pqg.c ! -name pqg.h ! -name rawhash.c \
     ! -name rijndael.c ! -name rijndael.h ! -name rijndael32.tab \