[fpc-devel] bitwise shift oddity a << b

Martin Frb lazarus at mfriebe.de
Tue May 19 13:15:43 CEST 2015

On 19/05/2015 09:22, Mark Morgan Lloyd wrote:
> Jonas Maebe wrote:
>> Martin Frb wrote:
>>> What is supposed to happen if the 2nd argument is negative?
>> I would propose to document it as "undefined behaviour", just like C 
>> does (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf , 
>> section 4.5.7). The reason is that the behaviour can differ depending 
>> on the cpu, so if you want to guarantee consistent behaviour on all 
>> platforms, you can no longer just emit a shift left/right instruction 
>> and have to add all kinds of checks.
>> Maybe we should support emitting range checks for the right operand 
>> though (to give an error if it falls outside the range of shift 
>> values whose behaviour is defined).
> Alternatively, could it be coopted into something useful e.g. a count 
> of the zero bits on the left/right of the operand?

"can differ depending on the cpu" IMHO applies to the underlying asm 

But I would expect that the compiler should know how this instruction 
behaves? And then can generate correct code. (Note, I am not asking for 
negative to work, never expected that. I am puzzled about the diff 
between constant eval, and run time eval.

I do not know, if any cpu actually takes a negative argument as the 
shift count, but of course future cpu may do.
In any case the compiler can cast the argument to a unsigned type 
(making it a very big number)
    a << cardinal(b)

Then there is also the maximum size of this argument (on a 64 bit cpu,  
any number greater 63 will empty the 1st operand). So unless there is a 
cpu that does not allow 64 as argument, the expression becomes either
    a << byte(b)
or an a cpu that takes the sign bit into consideration:
    a << byte(b) AND $7F

Afaik for i386 the 2nd argument is a byte size register. So oni386 the 
typecast to bye already happens without any overhead.

More information about the fpc-devel mailing list