summaryrefslogtreecommitdiff
path: root/vmac.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2020-07-08 03:21:58 -0400
committerJeffrey Walton <noloader@gmail.com>2020-07-08 03:21:58 -0400
commitcd6ed6aeda23218582ef6a4452adde6b820b7090 (patch)
treebe27e04ab8e49c4e8e62a0208deab6872278c864 /vmac.cpp
parentd1764c9e8b8109f7fef4986d4c280e67967dd99d (diff)
downloadcryptopp-git-cd6ed6aeda23218582ef6a4452adde6b820b7090.tar.gz
Fix VMAC compile on 32-bit Solaris
The change tested good on 32-bit Linux and 32-bit OS X
Diffstat (limited to 'vmac.cpp')
-rw-r--r--vmac.cpp33
1 files changed, 21 insertions, 12 deletions
diff --git a/vmac.cpp b/vmac.cpp
index 5c59a771..2d1ddfee 100644
--- a/vmac.cpp
+++ b/vmac.cpp
@@ -193,22 +193,24 @@ void VMAC_Base::VHASH_Update_SSE2(const word64 *data, size_t blocksRemainingInWo
CRYPTOPP_UNUSED(blocksRemainingInWord64);
// This inline ASM is tricky, and down right difficult when PIC is
- // in effect. The ASM uses all the general purpose registers. When
- // PIC is in effect, GCC uses EBX as a base register. Saving EBX with
+ // in effect. The ASM uses all the general purpose registers and all
+ // the XMM registers on 32-bit machines. When PIC is in effect on a
+ // 32-bit machine, GCC uses EBX as a base register. Saving EBX with
// 'mov %%ebx, %0' and restoring EBX with 'mov %0, %%ebx' causes GCC
// to generate 'mov -0x40(%ebx), %ebx' for the restore. That obviously
- // won't work. We can push and pop EBX, but then we have to be careful
- // because GCC references %1 (L1KeyLength) relative to ESP, which is
- // also used in the function and no longer accurate. Attempting to
- // sidestep the issues with clobber lists results in "error: ‘asm’
- // operand has impossible constraints", though we were able to tell
- // GCC that ESP is dirty. The problems with GCC are the reason for the
- // pushes and pops rather than the original moves.
+ // won't work because EBX is no longer accurate. We can push and pop
+ // EBX, but that breaks stack-based references. Attempting to sidestep
+ // the issues with clobber lists results in "error: ‘asm’ operand has
+ // impossible constraints". Eventually, we found we could save EBX to
+ // ESP-20, which is one word below our stack in the frame.
#ifdef __GNUC__
__asm__ __volatile__
(
- AS1( push %0) // L1KeyLength
- AS1( pop %%ebx)
+# if defined(__i386__) || defined(__i686__)
+ // Save EBX for PIC
+ AS2( mov %%ebx, -20(%%esp))
+# endif
+ AS2( mov %0, %%ebx) // L1KeyLength
INTEL_NOPREFIX
#else
#if defined(__INTEL_COMPILER)
@@ -427,11 +429,18 @@ void VMAC_Base::VHASH_Update_SSE2(const word64 *data, size_t blocksRemainingInWo
AS_POP_IF86( bp)
AS1( emms)
#ifdef __GNUC__
+
ATT_PREFIX
+
+# if defined(__i386__) || defined(__i686__)
+ // Restore EBX for PIC
+ AS2( mov -20(%%esp), %%ebx)
+# endif
+
:
: "m" (L1KeyLength), "c" (blocksRemainingInWord64), "S" (data),
"D" (nhK+tagPart*2), "d" (m_isFirstBlock), "a" (polyS+tagPart*4)
- : "ebx", "memory", "cc"
+ : "memory", "cc"
);
#endif
}