948728c4a6
In C, shift distances equal to or larger than the number of bits in the operand result in undefined behaviour. As part of eliminating undefined behaviour in arithmetic, mask off the distance like Java and JavaScript specify and C on x86 usually does. Assumption: conversion from unsigned to signed retains the two's complement bits. Assumption: uintmax_t has no padding bits.
41 lines
756 B
Plaintext
41 lines
756 B
Plaintext
# $FreeBSD$
|
|
# Check that <</>> use the low bits of the shift count.
|
|
|
|
if [ $((1<<16<<16)) = 0 ]; then
|
|
width=32
|
|
elif [ $((1<<32<<32)) = 0 ]; then
|
|
width=64
|
|
elif [ $((1<<64<<64)) = 0 ]; then
|
|
width=128
|
|
elif [ $((1<<64>>64)) = 1 ]; then
|
|
# Integers are wider than 128 bits; assume arbitrary precision.
|
|
# Nothing to test here.
|
|
exit 0
|
|
else
|
|
echo "Cannot determine integer width"
|
|
exit 2
|
|
fi
|
|
|
|
twowidth=$((width * 2))
|
|
j=43 k=$((1 << (width - 2))) r=0
|
|
|
|
i=0
|
|
while [ $i -lt $twowidth ]; do
|
|
if [ "$((j << i))" != "$((j << (i + width)))" ]; then
|
|
echo "Problem with $j << $i"
|
|
r=2
|
|
fi
|
|
i=$((i + 1))
|
|
done
|
|
|
|
i=0
|
|
while [ $i -lt $twowidth ]; do
|
|
if [ "$((k >> i))" != "$((k >> (i + width)))" ]; then
|
|
echo "Problem with $k >> $i"
|
|
r=2
|
|
fi
|
|
i=$((i + 1))
|
|
done
|
|
|
|
exit $r
|