summaryrefslogtreecommitdiff
path: root/aclocal/ax_signed_right_shift.m4
blob: 9c3ceb7989d1880a47390b7e6ee3cd843d19e213 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
dnl @synopsis AX_SIGNED_RIGHT_SHIFT
dnl
dnl Tests the behavior of a right shift on a negative signed int.
dnl
dnl This macro calls:
dnl   AC_DEFINE(SIGNED_RIGHT_SHIFT_IS)
dnl   AC_DEFINE(ARITHMETIC_RIGHT_SHIFT)
dnl   AC_DEFINE(LOGICAL_RIGHT_SHIFT)
dnl   AC_DEFINE(UNKNOWN_RIGHT_SHIFT)
dnl
dnl SIGNED_RIGHT_SHIFT_IS will be equal to one of the other macros.
dnl It also leaves the shell variables "ax_signed_right_shift"
dnl set to "arithmetic", "logical", or "unknown".
dnl
dnl NOTE: This macro does not work for cross-compiling.
dnl
dnl @category C
dnl @version 2009-03-25
dnl @license AllPermissive
dnl
dnl Copyright (C) 2009 David Reiss
dnl Copying and distribution of this file, with or without modification,
dnl are permitted in any medium without royalty provided the copyright
dnl notice and this notice are preserved.

AC_DEFUN([AX_SIGNED_RIGHT_SHIFT],
         [

          AC_MSG_CHECKING(the behavior of a signed right shift)

          success_arithmetic=no
          AC_RUN_IFELSE([AC_LANG_PROGRAM([[]], [[
          return
            /* 0xffffffff */
            -1 >>  1 != -1 ||
            -1 >>  2 != -1 ||
            -1 >>  3 != -1 ||
            -1 >>  4 != -1 ||
            -1 >>  8 != -1 ||
            -1 >> 16 != -1 ||
            -1 >> 24 != -1 ||
            -1 >> 31 != -1 ||
            /* 0x80000000 */
            (-2147483647 - 1) >>  1 != -1073741824 ||
            (-2147483647 - 1) >>  2 != -536870912  ||
            (-2147483647 - 1) >>  3 != -268435456  ||
            (-2147483647 - 1) >>  4 != -134217728  ||
            (-2147483647 - 1) >>  8 != -8388608    ||
            (-2147483647 - 1) >> 16 != -32768      ||
            (-2147483647 - 1) >> 24 != -128        ||
            (-2147483647 - 1) >> 31 != -1          ||
            /* 0x90800000 */
            -1870659584 >>  1 != -935329792 ||
            -1870659584 >>  2 != -467664896 ||
            -1870659584 >>  3 != -233832448 ||
            -1870659584 >>  4 != -116916224 ||
            -1870659584 >>  8 != -7307264   ||
            -1870659584 >> 16 != -28544     ||
            -1870659584 >> 24 != -112       ||
            -1870659584 >> 31 != -1         ||
            0;
          ]])], [
          success_arithmetic=yes
          ])


          success_logical=no
          AC_RUN_IFELSE([AC_LANG_PROGRAM([[]], [[
          return
            /* 0xffffffff */
            -1 >>  1 != (signed)((unsigned)-1 >>  1) ||
            -1 >>  2 != (signed)((unsigned)-1 >>  2) ||
            -1 >>  3 != (signed)((unsigned)-1 >>  3) ||
            -1 >>  4 != (signed)((unsigned)-1 >>  4) ||
            -1 >>  8 != (signed)((unsigned)-1 >>  8) ||
            -1 >> 16 != (signed)((unsigned)-1 >> 16) ||
            -1 >> 24 != (signed)((unsigned)-1 >> 24) ||
            -1 >> 31 != (signed)((unsigned)-1 >> 31) ||
            /* 0x80000000 */
            (-2147483647 - 1) >>  1 != (signed)((unsigned)(-2147483647 - 1) >>  1) ||
            (-2147483647 - 1) >>  2 != (signed)((unsigned)(-2147483647 - 1) >>  2) ||
            (-2147483647 - 1) >>  3 != (signed)((unsigned)(-2147483647 - 1) >>  3) ||
            (-2147483647 - 1) >>  4 != (signed)((unsigned)(-2147483647 - 1) >>  4) ||
            (-2147483647 - 1) >>  8 != (signed)((unsigned)(-2147483647 - 1) >>  8) ||
            (-2147483647 - 1) >> 16 != (signed)((unsigned)(-2147483647 - 1) >> 16) ||
            (-2147483647 - 1) >> 24 != (signed)((unsigned)(-2147483647 - 1) >> 24) ||
            (-2147483647 - 1) >> 31 != (signed)((unsigned)(-2147483647 - 1) >> 31) ||
            /* 0x90800000 */
            -1870659584 >>  1 != (signed)((unsigned)-1870659584 >>  1) ||
            -1870659584 >>  2 != (signed)((unsigned)-1870659584 >>  2) ||
            -1870659584 >>  3 != (signed)((unsigned)-1870659584 >>  3) ||
            -1870659584 >>  4 != (signed)((unsigned)-1870659584 >>  4) ||
            -1870659584 >>  8 != (signed)((unsigned)-1870659584 >>  8) ||
            -1870659584 >> 16 != (signed)((unsigned)-1870659584 >> 16) ||
            -1870659584 >> 24 != (signed)((unsigned)-1870659584 >> 24) ||
            -1870659584 >> 31 != (signed)((unsigned)-1870659584 >> 31) ||
            0;
          ]])], [
          success_logical=yes
          ])


          AC_DEFINE([ARITHMETIC_RIGHT_SHIFT], 1, [Possible value for SIGNED_RIGHT_SHIFT_IS])
          AC_DEFINE([LOGICAL_RIGHT_SHIFT], 2, [Possible value for SIGNED_RIGHT_SHIFT_IS])
          AC_DEFINE([UNKNOWN_RIGHT_SHIFT], 3, [Possible value for SIGNED_RIGHT_SHIFT_IS])

          if test "$success_arithmetic" = "yes" && test "$success_logical" = "yes" ; then
            AC_MSG_ERROR("Right shift appears to be both arithmetic and logical!")
          elif test "$success_arithmetic" = "yes" ; then
            ax_signed_right_shift=arithmetic
            AC_DEFINE([SIGNED_RIGHT_SHIFT_IS], 1,
                      [Indicates the effect of the right shift operator
                       on negative signed integers])
          elif test "$success_logical" = "yes" ; then
            ax_signed_right_shift=logical
            AC_DEFINE([SIGNED_RIGHT_SHIFT_IS], 2,
                      [Indicates the effect of the right shift operator
                       on negative signed integers])
          else
            ax_signed_right_shift=unknown
            AC_DEFINE([SIGNED_RIGHT_SHIFT_IS], 3,
                      [Indicates the effect of the right shift operator
                       on negative signed integers])
          fi

          AC_MSG_RESULT($ax_signed_right_shift)
         ])