This is essentially Intel 32-bit compiler tune-up. To start with all
authorAndy Polyakov <appro@openssl.org>
Sun, 28 Mar 2004 21:27:47 +0000 (21:27 +0000)
committerAndy Polyakov <appro@openssl.org>
Sun, 28 Mar 2004 21:27:47 +0000 (21:27 +0000)
available compiler versions generated bogus machine code trying to
compile new crypto/des/cfb_enc.c. Secondly, 8th version defines
__GNUC__ macro, but fails to compile *some* inline assembler correctly.
Note that all versions of icc implement MSC-like _lrot[rl] intrinsic,
which is used now instead of offensive asm. Finally, unnecessary linker
dependencies are eliminated. Most notably dependency from libirc.a
caused trouble at application start-up, if libcrypto.so is linked with
-Bsymbolic (which it is).

Configure
crypto/des/cfb_enc.c
crypto/des/des_locl.h
crypto/md32_common.h
crypto/rc5/rc5_locl.h

index 829f9b3..d52e90d 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -378,7 +378,7 @@ my %table=(
 
 # The intel boxes :-), It would be worth seeing if bsdi-gcc can use the
 # bn86-elf.o file file since it is hand tweaked assembler.
-"linux-ia32-icc",      "icc:-DL_ENDIAN -DTERMIO -O2::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-ia32-icc",      "icc:-DL_ENDIAN -DTERMIO -O2 -no_cpprt::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-elf",   "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-pentium",       "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -mcpu=pentium -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-ppro",  "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -mcpu=pentiumpro -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
@@ -1164,6 +1164,21 @@ else
        $openssl_other_defines.="#define OPENSSL_NO_STATIC_ENGINE\n";
        }
 
+# Compiler fix-ups
+if ($target =~ /icc$/)
+       {
+       my($iccver)=`$cc -V 2>&1`;
+       if ($iccver =~ /Version ([0-9]+)\./)    { $iccver=$1; }
+       else                                    { $iccver=0;  }
+       if ($iccver>=8)
+               {
+               # Eliminate unnecessary dependency from libirc.a. This is
+               # essential for shared library support, as otherwise
+               # apps/openssl can end up in endless loop upon startup...
+               $cflags.=" -Dmemcpy=__builtin_memcpy -Dmemset=__builtin_memset";
+               }
+       }
+
 if ($sys_id ne "")
        {
        #$cflags="-DOPENSSL_SYSNAME_$sys_id $cflags";
index 0013556..6738e7c 100644 (file)
@@ -58,6 +58,7 @@
 
 #include "e_os.h"
 #include "des_locl.h"
+#include <assert.h>
 
 /* The input and output are loaded in multiples of 8 bits.
  * What this means is that if you hame numbits=12 and length=2
@@ -73,12 +74,22 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
        {
        register DES_LONG d0,d1,v0,v1;
        register unsigned long l=length;
-       register int num=numbits,n=(numbits+7)/8,i;
+       register int num=numbits/8,n=(numbits+7)/8,i,rem=numbits%8;
        DES_LONG ti[2];
        unsigned char *iv;
+#ifndef L_ENDIAN
        unsigned char ovec[16];
+#else
+       unsigned int  sh[4];
+       unsigned char *ovec=(unsigned char *)sh;
 
-       if (num > 64) return;
+       /* I kind of count that compiler optimizes away this assertioni,*/
+       assert (sizeof(sh[0])==4);      /* as this holds true for all,  */
+                                       /* but 16-bit platforms...      */
+                                       
+#endif
+
+       if (numbits<=0 || numbits > 64) return;
        iv = &(*ivec)[0];
        c2l(iv,v0);
        c2l(iv,v1);
@@ -98,29 +109,34 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
                        out+=n;
                        /* 30-08-94 - eay - changed because l>>32 and
                         * l<<32 are bad under gcc :-( */
-                       if (num == 32)
+                       if (numbits == 32)
                                { v0=v1; v1=d0; }
-                       else if (num == 64)
+                       else if (numbits == 64)
                                { v0=d0; v1=d1; }
                        else
                                {
+#ifndef L_ENDIAN
                                iv=&ovec[0];
                                l2c(v0,iv);
                                l2c(v1,iv);
                                l2c(d0,iv);
                                l2c(d1,iv);
-                               /* shift ovec left most of the bits... */
-                               memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0));
-                               /* now the remaining bits */
-                               if(num%8 != 0)
+#else
+                               sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1;
+#endif
+                               if (rem==0)
+                                       memcpy(ovec,ovec+num,8);
+                               else
                                        for(i=0 ; i < 8 ; ++i)
-                                               {
-                                               ovec[i]<<=num%8;
-                                               ovec[i]|=ovec[i+1]>>(8-num%8);
-                                               }
+                                               ovec[i]=ovec[i+num]<<rem |
+                                                       ovec[i+num+1]>>(8-rem);
+#ifdef L_ENDIAN
+                               v0=sh[0], v1=sh[1];
+#else
                                iv=&ovec[0];
                                c2l(iv,v0);
                                c2l(iv,v1);
+#endif
                                }
                        }
                }
@@ -136,29 +152,34 @@ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
                        in+=n;
                        /* 30-08-94 - eay - changed because l>>32 and
                         * l<<32 are bad under gcc :-( */
-                       if (num == 32)
+                       if (numbits == 32)
                                { v0=v1; v1=d0; }
-                       else if (num == 64)
+                       else if (numbits == 64)
                                { v0=d0; v1=d1; }
                        else
                                {
+#ifndef L_ENDIAN
                                iv=&ovec[0];
                                l2c(v0,iv);
                                l2c(v1,iv);
                                l2c(d0,iv);
                                l2c(d1,iv);
-                               /* shift ovec left most of the bits... */
-                               memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0));
-                               /* now the remaining bits */
-                               if(num%8 != 0)
+#else
+                               sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1;
+#endif
+                               if (rem==0)
+                                       memcpy (ovec,ovec+num,8);
+                               else
                                        for(i=0 ; i < 8 ; ++i)
-                                               {
-                                               ovec[i]<<=num%8;
-                                               ovec[i]|=ovec[i+1]>>(8-num%8);
-                                               }
+                                               ovec[i]=ovec[i+num]<<rem |
+                                                       ovec[i+num+1]>>(8-rem);
+#ifdef L_ENDIAN
+                               v0=sh[0], v1=sh[1];
+#else
                                iv=&ovec[0];
                                c2l(iv,v0);
                                c2l(iv,v1);
+#endif
                                }
                        d0^=ti[0];
                        d1^=ti[1];
index e44e8e9..f992697 100644 (file)
                                } \
                        }
 
-#if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)
+#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC)
 #define        ROTATE(a,n)     (_lrotr(a,n))
 #elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
 # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
index 0cdc06e..307ec30 100644 (file)
  */
 #undef ROTATE
 #ifndef PEDANTIC
-# if 0 /* defined(_MSC_VER) */
+# if defined(_MSC_VER) || defined(__ICC)
 #  define ROTATE(a,n)  _lrotl(a,n)
 # elif defined(__MWERKS__)
 #  if defined(__POWERPC__)
 #   define ROTATE(a,n) __rlwinm(a,n,0,31)
-#  elif defined(OPENSSL_SYSNAME_NETWARE)
-#   define ROTATE(a,n)  _lrotl(a,n)
 #  elif defined(__MC68K__)
     /* Motorola specific tweak. <appro@fy.chalmers.se> */
 #   define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) )
index f4ebc23..282dd38 100644 (file)
                          *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
                          *((c)++)=(unsigned char)(((l)     )&0xff))
 
-#if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)
+#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC)
 #define ROTATE_l32(a,n)     _lrotl(a,n)
 #define ROTATE_r32(a,n)     _lrotr(a,n)
 #elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)