Removing undefined behavior of bitshifts

s_lange s_lange at ira.uka.de
Tue Jun 7 17:50:22 PDT 2011


Am 07.06.2011 01:20, schrieb Timon Gehr:
> I'd much prefer the behavior to be defined as 1<<x; being equivalent to
> 1<<(0x1f&x); (That's what D effectively does during runtime. It is also what
> the machine code supports, at least in x87).
Well, you probably mean what x86 processors do.

The behaviour of x86 processors in this regard is (at leas) well 
defined, but not uniform. It all depends whether you use general-purpose 
integer instructions or some 64, 128, or 256-bit SIMD instructions (MMX, 
SSE, AVX).

Int denotes 32-bit integers, operations on differently sized integer are 
analoguous.

For general-purpose integer instructions, the following identities hold 
true:
(l<<x == l<<(x & 0x1F)) and (l>>x == l>>(x & 0x1F)) for any (signed | 
unsigned) int l and x , regardless whether arithmetical or logical right 
shifts are used.

However, for SIMD integer instructions, things are a little different 
and the following identities hold true:
(l<<x == (unsigned int)x >= 0x20 ? 0 : l<<x) for any (signed | unsigned) 
int l and x ,
(l>>x == (unsigned int)x >= 0x20 ? 0 : l>>x) for any (signed | unsigned) 
int x and any unsigned int l (using logical right shifts)
(l>>x == (unsigned int)x >= 0x20 ? -1 : l>>x) for any (signed | 
unsigned) int x and any signed int l (using arithmetic right shifts)

As of yet, there are only general-pupose integer rotate instructions on 
x86 processors, and very few other CPUs and µCs actually implement 
rotate instructions.


More information about the Digitalmars-d mailing list