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.
_______________________________________________
fpc-devel maillist - [email protected]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel