Discussion:
[fpc-devel] Where to set proper alignment default of const strings?
Michael Ring
2018-11-28 16:49:57 UTC
Permalink
Hi,

I am debugging an issue that I see on mipsel embedded target (and
perhaps also on arm-embedded for corteX-m0, I had crashes in the same
rtl routine a while ago)

because RAM is small on embedded devices I use:

{$WRITEABLECONST OFF}

which means that const are read from flash and not from ram.

problem is now that const strings are sometimes not 32-bit aligned and
this causes an unaligned access exception on pic32mx because date from
flash must be read 32-bit aligned.

I thought that I had seen the correct place to configure this alignment
in the past but my google/grep foo is weak at the moment, I cannot find
something in the fpc sourcecode that rings a bell.

{$CODEALIGN CONSTMIN=4}

also does not work, I recompiled and in my case the const is still
improperly alligned.


Thanks in advance,


Michael



_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/ma
Michael Ring
2018-11-28 18:51:44 UTC
Permalink
The more I dig the more I ask myself if not the rtl routine is to blame
for the issue in the first place because it only takes alignment of the
destination into account when doing it's job.

Aligncount is calculated base on destination (which is RAM), for this
reason the last line always crashes because psrc can be unaligned.

I most likely completely misunderstand the meaning of
FPC_REQUIRES_PROPER_ALIGNMENT but usually ram can be written byte
aligned but flash has often limitations on read access so alignment
should look for psrc as this can come from flash.

Unless of course FPC_REQUIRES_PROPER_ALIGNMENT is  primarily meant for
speed improovement only, then it would make sense to look at pdest to
try to optimize write performance by having as much aligned access as
possible.I only found an old discussion in lazarus list from 2011 on
this topic, where it looks like structs were manually aligned in
lazarus, but I did not look too deep into the patches.

procedure Move(const source;var dest;count:SizeInt);[public, alias:
'FPC_MOVE']; from generic.inc line77:

        begin
          { Align on native pointer size }
--> *aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1));*
          dec(count,aligncount);
          pend:=psrc+aligncount;
          while psrc<pend do
            begin
              pdest^:=psrc^;
              inc(pdest);
              inc(psrc);
            end;
          { use sizeuint typecast to force shr optimization }
          pptruint(pend):=pptruint(psrc)+(sizeuint(count) div
sizeof(ptruint));
          while psrc<pend do
            begin
              pptruint(pdest)^:=pptruint(psrc)^;
Post by Michael Ring
Hi,
I am debugging an issue that I see on mipsel embedded target (and
perhaps also on arm-embedded for corteX-m0, I had crashes in the same
rtl routine a while ago)
{$WRITEABLECONST OFF}
which means that const are read from flash and not from ram.
problem is now that const strings are sometimes not 32-bit aligned and
this causes an unaligned access exception on pic32mx because date from
flash must be read 32-bit aligned.
I thought that I had seen the correct place to configure this
alignment in the past but my google/grep foo is weak at the moment, I
cannot find something in the fpc sourcecode that rings a bell.
{$CODEALIGN CONSTMIN=4}
also does not work, I recompiled and in my case the const is still
improperly alligned.
Thanks in advance,
Michael
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Michael Ring
2018-11-28 19:25:01 UTC
Permalink
After a little more fun in the debugger I came up with the following patch:

Index: generic.inc
===================================================================
--- generic.inc    (revision 40381)
+++ generic.inc    (working copy)
@@ -77,6 +77,8 @@
         begin
           { Align on native pointer size }
           aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1));
+          if aligncount > 0 then
+            aligncount := sizeof(PtrUInt)-aligncount;
           dec(count,aligncount);
           pend:=psrc+aligncount;
           while psrc<pend do


from my point of view the routine is wrongly calculating the numbers of
bytes that need to be read byte aligned before a pointer-sized copy can
be done

Michael
Post by Michael Ring
The more I dig the more I ask myself if not the rtl routine is to
blame for the issue in the first place because it only takes alignment
of the destination into account when doing it's job.
Aligncount is calculated base on destination (which is RAM), for this
reason the last line always crashes because psrc can be unaligned.
I most likely completely misunderstand the meaning of
FPC_REQUIRES_PROPER_ALIGNMENT but usually ram can be written byte
aligned but flash has often limitations on read access so alignment
should look for psrc as this can come from flash.
Unless of course FPC_REQUIRES_PROPER_ALIGNMENT is  primarily meant for
speed improovement only, then it would make sense to look at pdest to
try to optimize write performance by having as much aligned access as
possible.I only found an old discussion in lazarus list from 2011 on
this topic, where it looks like structs were manually aligned in
lazarus, but I did not look too deep into the patches.
        begin
          { Align on native pointer size }
--> *aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1));*
          dec(count,aligncount);
          pend:=psrc+aligncount;
          while psrc<pend do
            begin
              pdest^:=psrc^;
              inc(pdest);
              inc(psrc);
            end;
          { use sizeuint typecast to force shr optimization }
          pptruint(pend):=pptruint(psrc)+(sizeuint(count) div
sizeof(ptruint));
          while psrc<pend do
            begin
              pptruint(pdest)^:=pptruint(psrc)^;
Post by Michael Ring
Hi,
I am debugging an issue that I see on mipsel embedded target (and
perhaps also on arm-embedded for corteX-m0, I had crashes in the same
rtl routine a while ago)
{$WRITEABLECONST OFF}
which means that const are read from flash and not from ram.
problem is now that const strings are sometimes not 32-bit aligned
and this causes an unaligned access exception on pic32mx because date
from flash must be read 32-bit aligned.
I thought that I had seen the correct place to configure this
alignment in the past but my google/grep foo is weak at the moment, I
cannot find something in the fpc sourcecode that rings a bell.
{$CODEALIGN CONSTMIN=4}
also does not work, I recompiled and in my case the const is still
improperly alligned.
Thanks in advance,
Michael
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Sven Barth via fpc-devel
2018-11-28 19:45:14 UTC
Permalink
Post by Michael Ring
The more I dig the more I ask myself if not the rtl routine is to
blame for the issue in the first place because it only takes alignment
of the destination into account when doing it's job.
Aligncount is calculated base on destination (which is RAM), for this
reason the last line always crashes because psrc can be unaligned.
I most likely completely misunderstand the meaning of
FPC_REQUIRES_PROPER_ALIGNMENT but usually ram can be written byte
aligned but flash has often limitations on read access so alignment
should look for psrc as this can come from flash.
Unless of course FPC_REQUIRES_PROPER_ALIGNMENT is  primarily meant for
speed improovement only, then it would make sense to look at pdest to
try to optimize write performance by having as much aligned access as
possible.I only found an old discussion in lazarus list from 2011 on
this topic, where it looks like structs were manually aligned in
lazarus, but I did not look too deep into the patches.
The purpose of the FPC_REQUIRES_PROPER_ALIGNMENT is mainly for compiler
generated data structures like the RTTI which uses packed records on
targets where the define is not set (e.g. x86).

Regards,
Sven
_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fp
Benito van der Zander
2018-11-28 19:38:53 UTC
Permalink
Hi Michael,

there was a discussion in this issue
https://bugs.freepascal.org/view.php?id=33323


Cheers,
Benito
Post by Michael Ring
The more I dig the more I ask myself if not the rtl routine is to
blame for the issue in the first place because it only takes alignment
of the destination into account when doing it's job.
Aligncount is calculated base on destination (which is RAM), for this
reason the last line always crashes because psrc can be unaligned.
I most likely completely misunderstand the meaning of
FPC_REQUIRES_PROPER_ALIGNMENT but usually ram can be written byte
aligned but flash has often limitations on read access so alignment
should look for psrc as this can come from flash.
Unless of course FPC_REQUIRES_PROPER_ALIGNMENT is  primarily meant for
speed improovement only, then it would make sense to look at pdest to
try to optimize write performance by having as much aligned access as
possible.I only found an old discussion in lazarus list from 2011 on
this topic, where it looks like structs were manually aligned in
lazarus, but I did not look too deep into the patches.
        begin
          { Align on native pointer size }
--> *aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1));*
          dec(count,aligncount);
          pend:=psrc+aligncount;
          while psrc<pend do
            begin
              pdest^:=psrc^;
              inc(pdest);
              inc(psrc);
            end;
          { use sizeuint typecast to force shr optimization }
          pptruint(pend):=pptruint(psrc)+(sizeuint(count) div
sizeof(ptruint));
          while psrc<pend do
            begin
              pptruint(pdest)^:=pptruint(psrc)^;
Post by Michael Ring
Hi,
I am debugging an issue that I see on mipsel embedded target (and
perhaps also on arm-embedded for corteX-m0, I had crashes in the same
rtl routine a while ago)
{$WRITEABLECONST OFF}
which means that const are read from flash and not from ram.
problem is now that const strings are sometimes not 32-bit aligned
and this causes an unaligned access exception on pic32mx because date
from flash must be read 32-bit aligned.
I thought that I had seen the correct place to configure this
alignment in the past but my google/grep foo is weak at the moment, I
cannot find something in the fpc sourcecode that rings a bell.
{$CODEALIGN CONSTMIN=4}
also does not work, I recompiled and in my case the const is still
improperly alligned.
Thanks in advance,
Michael
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Michael Ring
2018-11-28 20:06:48 UTC
Permalink
I see a fix in the bug description but I cannot see that it was
implemented on trun:

current trunk:

{ Align on native pointer size }
79 aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1));
80 dec(count,aligncount);
81


patch:

--- rtl/inc/generic.inc (revision 38836)
+++ rtl/inc/generic.inc (working copy)
@@ -59,7 +59,7 @@
then
begin
{ Align on native pointer size }
- aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1));
+ aligncount:=(sizeof(PtrUInt)-PtrInt(pdest)) and (sizeof(PtrUInt)-1);
dec(count,aligncount);
pend:=psrc+aligncount;
while psrc<pend do
Post by Benito van der Zander
Hi Michael,
there was a discussion in this issue
https://bugs.freepascal.org/view.php?id=33323
Cheers,
Benito
Post by Michael Ring
The more I dig the more I ask myself if not the rtl routine is to
blame for the issue in the first place because it only takes
alignment of the destination into account when doing it's job.
Aligncount is calculated base on destination (which is RAM), for this
reason the last line always crashes because psrc can be unaligned.
I most likely completely misunderstand the meaning of
FPC_REQUIRES_PROPER_ALIGNMENT but usually ram can be written byte
aligned but flash has often limitations on read access so alignment
should look for psrc as this can come from flash.
Unless of course FPC_REQUIRES_PROPER_ALIGNMENT is  primarily meant
for speed improovement only, then it would make sense to look at
pdest to try to optimize write performance by having as much aligned
access as possible.I only found an old discussion in lazarus list
from 2011 on this topic, where it looks like structs were manually
aligned in lazarus, but I did not look too deep into the patches.
        begin
          { Align on native pointer size }
--> *aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1));*
          dec(count,aligncount);
          pend:=psrc+aligncount;
          while psrc<pend do
            begin
              pdest^:=psrc^;
              inc(pdest);
              inc(psrc);
            end;
          { use sizeuint typecast to force shr optimization }
          pptruint(pend):=pptruint(psrc)+(sizeuint(count) div
sizeof(ptruint));
          while psrc<pend do
            begin
              pptruint(pdest)^:=pptruint(psrc)^;
Post by Michael Ring
Hi,
I am debugging an issue that I see on mipsel embedded target (and
perhaps also on arm-embedded for corteX-m0, I had crashes in the
same rtl routine a while ago)
{$WRITEABLECONST OFF}
which means that const are read from flash and not from ram.
problem is now that const strings are sometimes not 32-bit aligned
and this causes an unaligned access exception on pic32mx because
date from flash must be read 32-bit aligned.
I thought that I had seen the correct place to configure this
alignment in the past but my google/grep foo is weak at the moment,
I cannot find something in the fpc sourcecode that rings a bell.
{$CODEALIGN CONSTMIN=4}
also does not work, I recompiled and in my case the const is still
improperly alligned.
Thanks in advance,
Michael
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Loading...