From 4f024b7ba9b472d1ec80b05cec49e8d41c370aa3 Mon Sep 17 00:00:00 2001
From: Paul Bakker <p.j.bakker@polarssl.org>
Date: Tue, 30 Oct 2012 07:29:57 +0000
Subject: [PATCH]  - Fixed for SPARC64

---
 ChangeLog                 |  1 +
 include/polarssl/bn_mul.h | 90 ++++++++++++++++++++++++++++++---------
 2 files changed, 71 insertions(+), 20 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2d9891135d..ae404d8448 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -61,6 +61,7 @@ Bugfix
    * mpi_add_abs() now correctly handles adding short numbers to long numbers
      with carry rollover (found by Ruslan Yushchenko)
    * Handle existence of OpenSSL Trust Extensions at end of X.509 DER blob
+   * Fixed MPI assembly for SPARC64 platform
 
 Security
    * Fixed potential memory corruption on miscrafted client messages (found by
diff --git a/include/polarssl/bn_mul.h b/include/polarssl/bn_mul.h
index 5965563424..ae6e2d658b 100644
--- a/include/polarssl/bn_mul.h
+++ b/include/polarssl/bn_mul.h
@@ -395,32 +395,82 @@
 #endif /* PPC32 */
 #endif /* PPC64 */
 
-#if defined(__sparc__)
+#if defined(__sparc__) && defined(__sparc64__)
 
 #define MULADDC_INIT                            \
-    asm( "ld     %0, %%o0       " :: "m" (s));  \
-    asm( "ld     %0, %%o1       " :: "m" (d));  \
-    asm( "ld     %0, %%o2       " :: "m" (c));  \
-    asm( "ld     %0, %%o3       " :: "m" (b));
+    asm(                                        \
+         "                                      \
+                ldx     %3, %%o0;               \
+                ldx     %4, %%o1;               \
+                ld      %5, %%o2;               \
+                ld      %6, %%o3;               \
+         "
 
 #define MULADDC_CORE                            \
-    asm( "ld    [%o0], %o4      " );            \
-    asm( "inc      4,  %o0      " );            \
-    asm( "ld    [%o1], %o5      " );            \
-    asm( "umul   %o3,  %o4, %o4 " );            \
-    asm( "addcc  %o4,  %o2, %o4 " );            \
-    asm( "rd      %y,  %g1      " );            \
-    asm( "addx   %g1,    0, %g1 " );            \
-    asm( "addcc  %o4,  %o5, %o4 " );            \
-    asm( "st     %o4, [%o1]     " );            \
-    asm( "addx   %g1,    0, %o2 " );            \
-    asm( "inc      4,  %o1      " );
+         "                                      \
+                ld      [%%o0], %%o4;           \
+                inc     4, %%o0;                \
+                ld      [%%o1], %%o5;           \
+                umul    %%o3, %%o4, %%o4;       \
+                addcc   %%o4, %%o2, %%o4;       \
+                rd      %%y, %%g1;              \
+                addx    %%g1, 0, %%g1;          \
+                addcc   %%o4, %%o5, %%o4;       \
+                st      %%o4, [%%o1];           \
+                addx    %%g1, 0, %%o2;          \
+                inc     4, %%o1;                \
+        "
 
 #define MULADDC_STOP                            \
-    asm( "st     %%o2, %0       " : "=m" (c));  \
-    asm( "st     %%o1, %0       " : "=m" (d));  \
-    asm( "st     %%o0, %0       " : "=m" (s) :: \
-    "g1", "o0", "o1", "o2", "o3", "o4", "o5" );
+        "                                       \
+                st      %%o2, %0;               \
+                stx     %%o1, %1;               \
+                stx     %%o0, %2;               \
+        "                                       \
+        : "=m" (c), "=m" (d), "=m" (s)          \
+        : "m" (s), "m" (d), "m" (c), "m" (b)    \
+        : "g1", "o0", "o1", "o2", "o3", "o4",   \
+          "o5"                                  \
+        );
+#endif /* SPARCv9 */
+
+#if defined(__sparc__) && !defined(__sparc64__)
+
+#define MULADDC_INIT                            \
+    asm(                                        \
+         "                                      \
+                ld      %3, %%o0;               \
+                ld      %4, %%o1;               \
+                ld      %5, %%o2;               \
+                ld      %6, %%o3;               \
+         "
+
+#define MULADDC_CORE                            \
+         "                                      \
+                ld      [%%o0], %%o4;           \
+                inc     4, %%o0;                \
+                ld      [%%o1], %%o5;           \
+                umul    %%o3, %%o4, %%o4;       \
+                addcc   %%o4, %%o2, %%o4;       \
+                rd      %%y, %%g1;              \
+                addx    %%g1, 0, %%g1;          \
+                addcc   %%o4, %%o5, %%o4;       \
+                st      %%o4, [%%o1];           \
+                addx    %%g1, 0, %%o2;          \
+                inc     4, %%o1;                \
+        "
+
+#define MULADDC_STOP                            \
+        "                                       \
+                st      %%o2, %0;               \
+                st      %%o1, %1;               \
+                st      %%o0, %2;               \
+        "                                       \
+        : "=m" (c), "=m" (d), "=m" (s)          \
+        : "m" (s), "m" (d), "m" (c), "m" (b)    \
+        : "g1", "o0", "o1", "o2", "o3", "o4",   \
+          "o5"                                  \
+        );
 
 #endif /* SPARCv8 */