Fix OPENSSL_BN_ASM_MONT5 for corner cases; add a test.
[openssl.git] / crypto / bn / bn_lcl.h
index 8e5e98e3f2b87fd80a1d33511df3ba495e60414a..ce085b5d3f3b4d38edd462f3489553046d5c7e0b 100644 (file)
@@ -238,7 +238,7 @@ extern "C" {
 #  if defined(__DECC)
 #   include <c_asm.h>
 #   define BN_UMULT_HIGH(a,b)  (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
-#  elif defined(__GNUC__)
+#  elif defined(__GNUC__) && __GNUC__>=2
 #   define BN_UMULT_HIGH(a,b)  ({      \
        register BN_ULONG ret;          \
        asm ("umulh     %1,%2,%0"       \
@@ -247,7 +247,7 @@ extern "C" {
        ret;                    })
 #  endif       /* compiler */
 # elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
-#  if defined(__GNUC__)
+#  if defined(__GNUC__) && __GNUC__>=2
 #   define BN_UMULT_HIGH(a,b)  ({      \
        register BN_ULONG ret;          \
        asm ("mulhdu    %0,%1,%2"       \
@@ -257,7 +257,7 @@ extern "C" {
 #  endif       /* compiler */
 # elif (defined(__x86_64) || defined(__x86_64__)) && \
        (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
-#  if defined(__GNUC__)
+#  if defined(__GNUC__) && __GNUC__>=2
 #   define BN_UMULT_HIGH(a,b)  ({      \
        register BN_ULONG ret,discard;  \
        asm ("mulq      %3"             \
@@ -280,6 +280,19 @@ extern "C" {
 #   define BN_UMULT_HIGH(a,b)          __umulh((a),(b))
 #   define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high)))
 #  endif
+# elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
+#  if defined(__GNUC__) && __GNUC__>=2
+#   define BN_UMULT_HIGH(a,b)  ({      \
+       register BN_ULONG ret;          \
+       asm ("dmultu    %1,%2"          \
+            : "=h"(ret)                \
+            : "r"(a), "r"(b) : "l");   \
+       ret;                    })
+#   define BN_UMULT_LOHI(low,high,a,b) \
+       asm ("dmultu    %2,%3"          \
+            : "=l"(low),"=h"(high)     \
+            : "r"(a), "r"(b));
+#  endif
 # endif                /* cpu */
 #endif         /* OPENSSL_NO_ASM */
 
@@ -484,6 +497,9 @@ BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
        int cl, int dl);
 int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
 
+BIGNUM *int_bn_mod_inverse(BIGNUM *in,
+       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx, int *noinv);
+
 #ifdef  __cplusplus
 }
 #endif