1dnl @synopsis AX_SIGNED_RIGHT_SHIFT
2dnl
3dnl Tests the behavior of a right shift on a negative signed int.
4dnl
5dnl This macro calls:
6dnl   AC_DEFINE(SIGNED_RIGHT_SHIFT_IS)
7dnl   AC_DEFINE(ARITHMETIC_RIGHT_SHIFT)
8dnl   AC_DEFINE(LOGICAL_RIGHT_SHIFT)
9dnl   AC_DEFINE(UNKNOWN_RIGHT_SHIFT)
10dnl
11dnl SIGNED_RIGHT_SHIFT_IS will be equal to one of the other macros.
12dnl It also leaves the shell variables "ax_signed_right_shift"
13dnl set to "arithmetic", "logical", or "unknown".
14dnl
15dnl NOTE: This macro does not work for cross-compiling.
16dnl
17dnl @category C
18dnl @version 2009-03-25
19dnl @license AllPermissive
20dnl
21dnl Copyright (C) 2009 David Reiss
22dnl Copying and distribution of this file, with or without modification,
23dnl are permitted in any medium without royalty provided the copyright
24dnl notice and this notice are preserved.
25
26AC_DEFUN([AX_SIGNED_RIGHT_SHIFT],
27         [
28
29          AC_MSG_CHECKING(the behavior of a signed right shift)
30
31          success_arithmetic=no
32          AC_RUN_IFELSE([AC_LANG_PROGRAM([[]], [[
33          return
34            /* 0xffffffff */
35            -1 >>  1 != -1 ||
36            -1 >>  2 != -1 ||
37            -1 >>  3 != -1 ||
38            -1 >>  4 != -1 ||
39            -1 >>  8 != -1 ||
40            -1 >> 16 != -1 ||
41            -1 >> 24 != -1 ||
42            -1 >> 31 != -1 ||
43            /* 0x80000000 */
44            (-2147483647 - 1) >>  1 != -1073741824 ||
45            (-2147483647 - 1) >>  2 != -536870912  ||
46            (-2147483647 - 1) >>  3 != -268435456  ||
47            (-2147483647 - 1) >>  4 != -134217728  ||
48            (-2147483647 - 1) >>  8 != -8388608    ||
49            (-2147483647 - 1) >> 16 != -32768      ||
50            (-2147483647 - 1) >> 24 != -128        ||
51            (-2147483647 - 1) >> 31 != -1          ||
52            /* 0x90800000 */
53            -1870659584 >>  1 != -935329792 ||
54            -1870659584 >>  2 != -467664896 ||
55            -1870659584 >>  3 != -233832448 ||
56            -1870659584 >>  4 != -116916224 ||
57            -1870659584 >>  8 != -7307264   ||
58            -1870659584 >> 16 != -28544     ||
59            -1870659584 >> 24 != -112       ||
60            -1870659584 >> 31 != -1         ||
61            0;
62          ]])], [
63          success_arithmetic=yes
64          ])
65
66
67          success_logical=no
68          AC_RUN_IFELSE([AC_LANG_PROGRAM([[]], [[
69          return
70            /* 0xffffffff */
71            -1 >>  1 != (signed)((unsigned)-1 >>  1) ||
72            -1 >>  2 != (signed)((unsigned)-1 >>  2) ||
73            -1 >>  3 != (signed)((unsigned)-1 >>  3) ||
74            -1 >>  4 != (signed)((unsigned)-1 >>  4) ||
75            -1 >>  8 != (signed)((unsigned)-1 >>  8) ||
76            -1 >> 16 != (signed)((unsigned)-1 >> 16) ||
77            -1 >> 24 != (signed)((unsigned)-1 >> 24) ||
78            -1 >> 31 != (signed)((unsigned)-1 >> 31) ||
79            /* 0x80000000 */
80            (-2147483647 - 1) >>  1 != (signed)((unsigned)(-2147483647 - 1) >>  1) ||
81            (-2147483647 - 1) >>  2 != (signed)((unsigned)(-2147483647 - 1) >>  2) ||
82            (-2147483647 - 1) >>  3 != (signed)((unsigned)(-2147483647 - 1) >>  3) ||
83            (-2147483647 - 1) >>  4 != (signed)((unsigned)(-2147483647 - 1) >>  4) ||
84            (-2147483647 - 1) >>  8 != (signed)((unsigned)(-2147483647 - 1) >>  8) ||
85            (-2147483647 - 1) >> 16 != (signed)((unsigned)(-2147483647 - 1) >> 16) ||
86            (-2147483647 - 1) >> 24 != (signed)((unsigned)(-2147483647 - 1) >> 24) ||
87            (-2147483647 - 1) >> 31 != (signed)((unsigned)(-2147483647 - 1) >> 31) ||
88            /* 0x90800000 */
89            -1870659584 >>  1 != (signed)((unsigned)-1870659584 >>  1) ||
90            -1870659584 >>  2 != (signed)((unsigned)-1870659584 >>  2) ||
91            -1870659584 >>  3 != (signed)((unsigned)-1870659584 >>  3) ||
92            -1870659584 >>  4 != (signed)((unsigned)-1870659584 >>  4) ||
93            -1870659584 >>  8 != (signed)((unsigned)-1870659584 >>  8) ||
94            -1870659584 >> 16 != (signed)((unsigned)-1870659584 >> 16) ||
95            -1870659584 >> 24 != (signed)((unsigned)-1870659584 >> 24) ||
96            -1870659584 >> 31 != (signed)((unsigned)-1870659584 >> 31) ||
97            0;
98          ]])], [
99          success_logical=yes
100          ])
101
102
103          AC_DEFINE([ARITHMETIC_RIGHT_SHIFT], 1, [Possible value for SIGNED_RIGHT_SHIFT_IS])
104          AC_DEFINE([LOGICAL_RIGHT_SHIFT], 2, [Possible value for SIGNED_RIGHT_SHIFT_IS])
105          AC_DEFINE([UNKNOWN_RIGHT_SHIFT], 3, [Possible value for SIGNED_RIGHT_SHIFT_IS])
106
107          if test "$success_arithmetic" = "yes" && test "$success_logical" = "yes" ; then
108            AC_MSG_ERROR("Right shift appears to be both arithmetic and logical!")
109          elif test "$success_arithmetic" = "yes" ; then
110            ax_signed_right_shift=arithmetic
111            AC_DEFINE([SIGNED_RIGHT_SHIFT_IS], 1,
112                      [Indicates the effect of the right shift operator
113                       on negative signed integers])
114          elif test "$success_logical" = "yes" ; then
115            ax_signed_right_shift=logical
116            AC_DEFINE([SIGNED_RIGHT_SHIFT_IS], 2,
117                      [Indicates the effect of the right shift operator
118                       on negative signed integers])
119          else
120            ax_signed_right_shift=unknown
121            AC_DEFINE([SIGNED_RIGHT_SHIFT_IS], 3,
122                      [Indicates the effect of the right shift operator
123                       on negative signed integers])
124          fi
125
126          AC_MSG_RESULT($ax_signed_right_shift)
127         ])
128