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]


--
_______________________________________________
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus

Reply via email to