[Lazarus] fpc bug with M1 [[was: Re: UTF8LengthFast returning incorrect results on AARCH64 (MacOS)]]
Noel Duffy
noelduffy at xtra.co.nz
Tue Dec 28 23:18:30 CET 2021
On 29/12/21 10:47, Martin Frb via lazarus wrote:
> On 28/12/2021 22:05, Noel Duffy via lazarus wrote:
>> On 29/12/21 01:26, Bart via lazarus wrote:
>>> fpc -al ulen.pas
>>
>> > This will produce the file ulen.s
>> > You can attach or copy that here.
>>
>> File is attached.
>
> Thanks.
> And I think there is a bug in FPC
>
> This is the signed version
>
> # [43] Result += (pn8^ shr 7) and ((not pn8^) shr 6);
> ldr x0,[sp]
> ldrsb w0,[x0] # <<<<< sign extend to a 32bit value
> (32bit register).
> eor w0,w0,#255 # <<<<< But only "not" the lowest 8 bit. That
> is wrong. The calculation uses 32 bit at this point
> lsr w0,w0,#6
> ldr x2,[sp]
> ldrsb w2,[x2]
> lsr w2,w2,#7
> and w0,w2,w0 # <<<<<< here the full 32 bit are used.
>
>
> Had the full 32 bits been "not"ed, the the upper 24 bit where 0 (because
> they had been sign extended to 1).
> This would mask all the 1, that were sign extended in w2.
>
> Had the char been < 128 (high bit = 0), then w0 would have the upper 24
> bit = 1 / but w2 would have them 0.
>
> And that is why the code worked, even with signed values. (signed values
> were still a bad idea)
>
Interesting. As I noted in my message with the ulen.s attached, I tested
and found the problem is not present in fpc 3.2.2. That's the version of
fpc packaged by Lazarus, and I used that to compile fpc 3.3.1.
The assembler produced by 3.2.2 looks like this:
# [43] Result += (pn8^ shr 7) and ((not pn8^) shr 6);
ldr x0,[sp]
ldrsb w0,[x0]
mvn w0,w0
sxtb w0,w0
lsr w1,w0,#6
ldr x0,[sp]
ldrsb w0,[x0]
lsr w0,w0,#7
and w0,w0,w1
sxtw x0,w0
ldr x1,[sp, #16]
add x0,x1,x0
str x0,[sp, #16]
More information about the lazarus
mailing list