ack
ack copied to clipboard
Define behaviour of rot and ror (and probably sli, sri, slu, sri) if shift is 0 or >wordsize
Some architectures, like the MIPS, only consider the bottom 5 bits of the shift amount when shifting. These means that shifting by values >= 32 does nothing, which is surprising. mcg's rotation emulation expects this to result in 0, which works on older platforms.
This all needs sorting out.
I made a mistake in 9077b3a. I used /* a rol b -> (a << b) | (a >> (32 - b)) */, where 32 is the size in bits. This is wrong when b is zero. We get (a << 0) | (a >> 32), but a >> 32 has undefined behavior. It might work by accident. If a >> 32 is zero, then we get a | 0, so a. If a >> 32 is a, then we get a | a, also a. If a >> 32 has some other value, then we may get the wrong answer.
http://tack.sourceforge.net/olddocs/em.pdf, page 41, says,
The shift count for SHL, SHR, ROL and ROR must be in the range 0 to object size in bits - 1. The effect of a count not in this range is undefined.
This means that a >> 32 is undefined in EM. This is good enough for C, where shifts < or >= bits are also undefined. Some languages, like Perl, define such shifts. perlop says,
Shifting by negative number of bits means the reverse shift: left shift becomes right shift, right shift becomes left shift. This is unlike in C, where negative shift is undefined.
Shifting by more bits than the size of the integers means most of the time zero (all bits fall off), except that under use integer right overshifting a negative shiftee results in -1. This is unlike in C, where shifting by too many bits is undefined. A common C behavior is "shift by modulo wordbits"... but that is completely accidental.