Mike Gibson mike.gibson@storagecraft.com writes:
+/******************************************************************************
_allshr (NTDLL.@)
- Right arithmetic shift a 64 bit integer
- PARAMS
- a [I] Initial number.
- count [I] Number of bits to shift by.
- RETURNS
- The value of a following the shift.
- */
+LONGLONG WINAPI _allshr( LONGLONG a, INT count ) +{
- return a >> count;
+}
There's no guarantee that this would be an arithmetic shift, it's compiler-dependent.
Alexandre Julliard [julliard@winehq.org] writes:
Mike Gibson mike.gibson@storagecraft.com writes:
+/******************************************************************************
_allshr (NTDLL.@)
- Right arithmetic shift a 64 bit integer
- PARAMS
- a [I] Initial number.
- count [I] Number of bits to shift by.
- RETURNS
- The value of a following the shift.
- */
+LONGLONG WINAPI _allshr( LONGLONG a, INT count ) +{
- return a >> count;
+}
There's no guarantee that this would be an arithmetic shift, it's compiler-dependent.
RtlLargeIntegerArithmeticShift doesn't handle this case either, but of course, that's not the point. Once we determine a solution, I'll fix it up as well. The following code would work regardless or right shift behavior. Of course, it's a bit slower.
/* create mask to extend the sign bit */ LONGLONG mask; mask = ( LONGLONG ) 1 << 63; mask &= a; mask >>= count;
/* do the shift */ a >>= count;
/* add the mask */ a |= mask;
return a;
The vast majority of platforms seem to do arithmetic right shift. It would be better to have a #define that indicates what the right shifting behavior is. Only on those platforms where right shift isn't arithmetic would the slower code be used.
AFAIK, this sort of thing is determined in the configure step. I can write a test for it, but I have a suspicion someone may have already done this. Anyone know? If not, I would appreciate some pointers (or links) on how to go about adding such a test.
Mike Gibson
On Tue, Dec 7, 2010 at 10:51 AM, Mike Gibson mike.gibson@storagecraft.com wrote:
... The vast majority of platforms seem to do arithmetic right shift. It would be better to have a #define that indicates what the right shifting behavior is. Only on those platforms where right shift isn't arithmetic would the slower code be used.
AFAIK, this sort of thing is determined in the configure step. I can write a test for it, but I have a suspicion someone may have already done this. Anyone know? If not, I would appreciate some pointers (or links) on how to go about adding such a test.
You should be able to test this behavior with AC_COMPILE_IFELSE: ---- dnl **** Check for arithmetic right shifting **** AC_CACHE_CHECK([whether the right shift operator is an arithmetic right shift], wine_cv_arithmetic_right_shift, AC_COMPILE_IFELSE([AC_LANG_PROGRAM( [[#if ((-4 >> 1) != -2) #error "No simple arithmetic right shift" #endif]], [[]])], [wine_cv_arithmetic_right_shift=yes], [wine_cv_arithmetic_right_shift=no])) if test "$wine_cv_arithmetic_right_shift" = "yes" then AC_DEFINE(HAVE_SIMPLE_ARITHMETIC_RIGHT_SHIFT,1,[Define if the right shift operator is an arithmetic shift]) fi ---- Throw the above in configure.ac and test with "autoconf && autoheader && ./configure".
Erich Hoover ehoover@mines.edu