OpenWrt Forum Archive

Topic: libgcrypt failed to compile on OpenWRT SVN trunk r16235

The content of this topic has been archived on 15 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

When I tried to compile OpenWRT SVN trunk for my FON2100 with r16235, I got the following error messages:

 mips-openwrt-linux-uclibc-gcc -DHAVE_CONFIG_H -I. -I.. -I../src -I../src -I/opt/tmp/openwrt-svn-trunk-private/staging_dir/target-mips_uClibc-0.9.30.1/usr/include -I/opt/tmp/openwrt-svn-trunk-private/staging_dir/target-mips_uClibc-0.9.30.1/include -I/opt/tmp/openwrt-svn-trunk-private/staging_dir/target-mips_uClibc-0.9.30.1/usr/include -Os -pipe -mips32 -mtune=mips32 -funit-at-a-time -fhonour-copts -fpic -fvisibility=hidden -Wall -MT mpih-div.lo -MD -MP -MF .deps/mpih-div.Tpo -c mpih-div.c  -fPIC -DPIC -o .libs/mpih-div.o
mpih-div.c: In function '_gcry_mpih_mod_1':
mpih-div.c:98: error: impossible constraint in 'asm'
mpih-div.c:98: error: impossible constraint in 'asm'
mpih-div.c:104: error: impossible constraint in 'asm'
mpih-div.c:104: error: impossible constraint in 'asm'
mpih-div.c:134: error: impossible constraint in 'asm'
mpih-div.c:134: error: impossible constraint in 'asm'
make[5]: *** [mpih-div.lo] Error 1
make[5]: Leaving directory `/opt/tmp/openwrt-svn-trunk-private/build_dir/target-mips_uClibc-0.9.30.1/libgcrypt-1.4.4/mpi'
make[4]: *** [all-recursive] Error 1
make[4]: Leaving directory `/opt/tmp/openwrt-svn-trunk-private/build_dir/target-mips_uClibc-0.9.30.1/libgcrypt-1.4.4'
make[3]: *** [all] Error 2
make[3]: Leaving directory `/opt/tmp/openwrt-svn-trunk-private/build_dir/target-mips_uClibc-0.9.30.1/libgcrypt-1.4.4'
make[2]: *** [/opt/tmp/openwrt-svn-trunk-private/build_dir/target-mips_uClibc-0.9.30.1/libgcrypt-1.4.4/.built] Error 2
make[2]: Leaving directory `/opt/tmp/openwrt-svn-trunk-private/feeds/packages/libs/libgcrypt'
make[1]: *** [package/feeds/packages/libgcrypt/compile] Error 2
make[1]: Leaving directory `/opt/tmp/openwrt-svn-trunk-private'
make: *** [package/feeds/packages/libgcrypt/compile] Error 2

Does anyone know how to fix this issue?

Hi,

the reason for this error message is the gcc 4.4.0 change:
http://gcc.gnu.org/gcc-4.4/changes.html
...
The MIPS port no longer recognizes the h  asm constraint. It was necessary to remove this constraint in order to avoid generating unpredictable code sequences.

One of the main uses of the h constraint was to extract the high part of a multiplication on 64-bit targets. For example:

    asm ("dmultu\t%1,%2" : "=h" (result) : "r" (x), "r" (y));

You can now achieve the same effect using 128-bit types:

    typedef unsigned int uint128_t __attribute__((mode(TI)));
    result = ((uint128_t) x * y) >> 64;
...

You might trying this patch, (derivate of a patch applied to gmp library recently)
--- libgcrypt-1.4.4.orig/mpi/longlong.h    2008-08-19 17:20:03.000000000 +0200
+++ libgcrypt-1.4.4/mpi/longlong.h    2009-06-14 19:45:28.000000000 +0200
@@ -710,18 +710,35 @@ extern USItype __udiv_qrnnd ();
#endif /* __m88110__ */
#endif /* __m88000__ */

+/* Test for gcc >= maj.min, as per __GNUC_PREREQ in glibc */
+#if defined (__GNUC__) && defined (__GNUC_MINOR__)
+#define __GNUC_PREREQ(maj, min) \
+  ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#define __GNUC_PREREQ(maj, min)  0
+#endif
+
/***************************************
  **************  MIPS  *****************
  ***************************************/
#if defined (__mips__) && W_TYPE_SIZE == 32
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#if __GNUC_PREREQ (4,4)
+#define umul_ppmm(w1, w0, u, v) \
+  do {                                                                 \
+    UDItype __ll = (UDItype)(u) * (v);                                 \
+    w1 = __ll >> 32;                                                   \
+    w0 = __ll;                                                         \
+  } while (0)
+#endif
+#if !defined (umul_ppmm) && __GNUC_PREREQ (2,7)
#define umul_ppmm(w1, w0, u, v) \
   __asm__ ("multu %2,%3"                                                \
       : "=l" ((USItype)(w0)),                                      \
         "=h" ((USItype)(w1))                                       \
       : "d" ((USItype)(u)),                                        \
         "d" ((USItype)(v)))
-#else
+#endif
+#if !defined (umul_ppmm)
#define umul_ppmm(w1, w0, u, v) \
   __asm__ ("multu %2,%3 \n" \
       "mflo %0 \n"     \
@@ -739,14 +756,24 @@ extern USItype __udiv_qrnnd ();
  **************  MIPS/64  **************
  ***************************************/
#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#if __GNUC_PREREQ (4,4)
+#define umul_ppmm(w1, w0, u, v) \
+  do {                                                                 \
+    typedef unsigned int __ll_UTItype __attribute__((mode(TI)));       \
+    __ll_UTItype __ll = (__ll_UTItype)(u) * (v);                       \
+    w1 = __ll >> 64;                                                   \
+    w0 = __ll;                                                         \
+  } while (0)
+#endif
+#if !defined (umul_ppmm) && __GNUC_PREREQ (2,7)
#define umul_ppmm(w1, w0, u, v) \
   __asm__ ("dmultu %2,%3"                                               \
       : "=l" ((UDItype)(w0)),                                      \
         "=h" ((UDItype)(w1))                                       \
       : "d" ((UDItype)(u)),                                        \
         "d" ((UDItype)(v)))
-#else
+#endif
+#if !defined (umul_ppmm)
#define umul_ppmm(w1, w0, u, v) \
   __asm__ ("dmultu %2,%3 \n"    \
       "mflo %0 \n"         \

Don't know if it works at runtime, at least you get an idea what needs to be done.

The discussion might have continued from here.