[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
code/instruction.
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