Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2017-11

Regarding issue/patch 0032637

10 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

J. Gareth Moreton

I'm guessing my code is not correct or causes problems. I haven't had much luck in finding a straight answer regarding proper exception handling with assembler code (where correcting non-volatile registers and stack space are concerned), although I'll keep trying. I tried asking on the forum, but Thaddy gave me a response that is somewhat discouraging.

http://forum.lazarus.freepascal.org/index.php/topic,39071.msg266937

If you rather I didn't contribute, say so. I guess I'm not good enough.

Reply by email

J. Gareth Moreton

Hi everyone,

Re: https://bugs.freepascal.org/view.php?id=32637

I apologise for my slight outburst. I didn't quite appreciate Thaddy's response when I asked how to get SEH to keep track of pushed registers ( http://forum.lazarus.freepascal.org/index.php/topic,39071.msg266937 ), but Marcov gave me the answer.

Long story short, I have now modified my assembler code that contains ".seh_pushreg %rdi" after each "push %rdi" instruction (the Linux versions don't actually push any registers because the required %rdi register is volatile on that platform). I'm just doing a compilation of FPC, then I'll upload a new patch to the bug report in question (any way to remove the old ones?).

Question though (although, by coincidence, it doesn't apply here), for the sake of SEH, must the stack be aligned in ALL circumstances - for example, if you push a register halfway through the procedure, must you then do something to ensure the stack returns to a 16-byte boundary and the SEH made aware of it?

Gareth

Reply by email

J. Gareth Moreton

Hi everyone,

Re: https://bugs.freepascal.org/view.php?id=32637

I apologise for my slight outburst. I didn't quite appreciate Thaddy's response when I asked how to get SEH to keep track of pushed registers ( http://forum.lazarus.freepascal.org/index.php/topic,39071.msg266937 ), but Marcov gave me the answer.

Long story short, I have now modified my assembler code that contains ".seh_pushreg %rdi" after each "push %rdi" instruction (the Linux versions don't actually push any registers because the required %rdi register is volatile on that platform). I'm just doing a compilation of FPC, then I'll upload a new patch to the bug report in question (any way to remove the old ones?).

Question though (although, by coincidence, it doesn't apply here), for the sake of SEH, must the stack be aligned in ALL circumstances - for example, if you push a register halfway through the procedure, must you then do something to ensure the stack returns to a 16-byte boundary and the SEH made aware of it?

Gareth

Reply by email

J. Gareth Moreton

Hi everyone,

Re: https://bugs.freepascal.org/view.php?
id=32637

I have now modified my assembler code that
contains ".seh_pushreg %rdi" after each
"push %rdi" instruction (the Linux
versions don't actually push any registers
because the required %rdi register is
volatile on that platform). It has now
been uploaded to the bug report in
question (any way to remove the old
ones?).

Question though (although, by coincidence,
it doesn't apply here), for the sake of
SEH, must the stack be aligned in ALL
circumstances - for example, if you push a
register halfway through the procedure,
must you then do something to ensure the
stack returns to a 16-byte boundary and
the SEH made aware of it?

Gareth aka. Kit

Reply by email

Christo
to J. Gareth Moreton: I'm guessing my code is not correct or causes problems. I haven't had much luck in…
J. Gareth Moreton wrote 7 lines
I'm guessing my code is not correct or causes problems.  I haven't had much luck in finding a straight answer  regarding proper exception handling with assembler code (where correcting non-volatile registers and stack  space are concerned), although I'll keep trying.  I tried asking on the forum, but Thaddy gave me a response  that is somewhat discouraging.

Thaddy has a somewhat unique perspective of things. As per normal when reading things on the internet, try to recognize the difference between fact and opinion.  Facts are very useful, opinions are sometimes useful (if the person has a good overview of the subject matter) but can also reflect a person's bias.

Reply by email

J. Gareth Moreton

Thanks Christo.

Apologies for 4 messages coming think there were a few technical glitches with the mailing list. Either way, I have submitted an updated patch to the bug report in question that corrects the stack unwinding for Windows. Any testing would be greatly appreciated (I'm not in a position to rigorously test the code for Linux).

Yeah, I got a little emotional with Thaddy's response (which has since been deleted), partly because he mocked me a bit for even attempting to use assembly language for optimisation. Granted, I tend to do more low-level and mathematical programming than higher-level components, where assembler optimisation can really pay dividends. Plus in a perverted way, I actually enjoy trying to squeeze another microsecond out of running time!

Gareth aka. Kit.

On Wed 29/11/17 05:19 , Christo sent:

Show quoted text 32 lines
On Sun, 2017-11-26 at 09:29 +0000, J. Gareth Moreton wrote: > I'm guessing my code is not correct or causes problems.  I haven't > had much luck in finding a straight answer  > regarding proper exception handling with assembler code (where > correcting non-volatile registers and stack  > space are concerned), although I'll keep trying.  I tried asking on > the forum, but Thaddy gave me a response  > that is somewhat discouraging. Thaddy has a somewhat unique perspective of things. As per normal when reading things on the internet, try to recognize the difference between fact and opinion.  Facts are very useful, opinions are sometimes useful (if the person has a good overview of the subject matter) but can also reflect a person's bias.

Reply by email

Sergei Gorelkin
to J. Gareth Moreton
J. Gareth Moreton wrote 15 lines
Thanks Christo. Apologies for 4 messages coming think there were a few technical glitches with the mailing list. Either way, I have submitted an updated patch to the bug report in question that corrects the stack unwinding for Windows. Any testing would be greatly appreciated (I'm not in a position to rigorously test the code for Linux). Yeah, I got a little emotional with Thaddy's response (which has since been deleted), partly because he mocked me a bit for even attempting to use assembly language for optimisation. Granted, I tend to do more low-level and mathematical programming than higher-level components, where assembler optimisation can really pay dividends. Plus in a perverted way, I actually enjoy trying to squeeze another microsecond out of running time! Gareth aka. Kit.

I should have read and answered earlier, but better late than never.

The x86-64 target (actually, all targets except i386 and m68k) use concept of fixed stack. This means: all changes to the stack pointer are done at the beginning and at the end of procedure. Pushing something in the middle is illegal. The stack pointer itself needs to be aligned only at the point of calling another procedure. As a consequence, simple procedures that don't call other procedures and don't use nonvolatile registers can have the stack pointer misaligned by 8 bytes as it naturally is at the first instruction (such procedures don't need any SEH annotations at all, which is a way to simplify things).
Now, several first instructions where is stack pointer is changed and nonvolatile registers are saved is called prologue. It is delimited by .seh_endprologue directive and can be at most 255 bytes in size.
The advice given at forum to insert .seh_endprologue at the very beginning is plain wrong. .seh_endprologue must be the last SEH directive in procedure. Compiler probably needs to do more checks and reject SEH directives coming after .seh_endprologue.

Regards,
Sergei

Reply by email

J. Gareth Moreton

Ooh right, okay. Thanks for that Sergei. I just put it in somewhat blindly because the compiler inserts it for Pascal code after the normal prologue after creating a stack frame, but complained and threw an error if I used .seh_pushreg but then neglected to use .seh_endprologue. I agree that the compiler should complain if it finds things out of order like I did, otherwise one may not know any better.

I'm still learning the nuances! I'll just fix my code.

Gareth aka. Kit

P.S. Is there any way to remove the other patches from that bug report.

P.P.S. Would you be able to say my advice was plain wrong on the forum post and correct it, just for the sake of anyone else who stumbles across it.

P.P.P.S. Any possibility of inserting similar functionality for Intel-style assembler at some point?

On Wed 29/11/17 14:58 , "Sergei Gorelkin via fpc-devel" sent:

Show quoted text 84 lines
29.11.2017 15:12, J. Gareth Moreton wrote: > Thanks Christo. > > Apologies for 4 messages coming think there were a few technical glitches with the mailing > list. Either way, I have submitted an updated patch to the bug report in question that corrects the stack > unwinding for Windows. Any testing would be greatly appreciated (I'm not in a position to rigorously test > the code for Linux). > > Yeah, I got a little emotional with Thaddy's response (which has since been deleted), partly because he > mocked me a bit for even attempting to use assembly language for optimisation. Granted, I tend to do more > low-level and mathematical programming than higher-level components, where assembler optimisation can really > pay dividends. Plus in a perverted way, I actually enjoy trying to squeeze another microsecond out of > running time! > > Gareth aka. Kit. > I should have read and answered earlier, but better late than never. The x86-64 target (actually, all targets except i386 and m68k) use concept of fixed stack. This means: all changes to the stack pointer are done at the beginning and at the end of procedure. Pushing something in the middle is illegal. The stack pointer itself needs to be aligned only at the point of calling another procedure. As a consequence, simple procedures that don't call other procedures and don't use nonvolatile registers can have the stack pointer misaligned by 8 bytes as it naturally is at the first instruction (such procedures don't need any SEH annotations at all, which is a way to simplify things). Now, several first instructions where is stack pointer is changed and nonvolatile registers are saved is called prologue. It is delimited by .seh_endprologue directive and can be at most 255 bytes in size. The advice given at forum to insert .seh_endprologue at the very beginning is plain wrong. .seh_endprologue must be the last SEH directive in procedure. Compiler probably needs to do more checks and reject SEH directives coming after .seh_endprologue. Regards, Sergei _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

J. Gareth Moreton

Would code like this be correct?

Procedure FillWord(var x; count: SizeInt; value: Word); assembler; nostackframe; asm
{ win64: rcx dest, rdx count, r8w value
linux: rdi dest, rsi count, dx value }

  {$ifdef win64}
    push    %rdi

.seh_pushreg %rdi
.seh_endprologue
cmp $0x0, %rdx

...

I recall now an assembler routine where RBX was modified midway through a procedure, but instead of pushing and popping it, it was written to a reserved part of the stack (configured in the prologue) and given a .seh_savereg hint - still trying to get my head around all of this!

Kit

On Thu 30/11/17 04:26 , "J. Gareth Moreton" sent:

Show quoted text 213 lines
Ooh right, okay. Thanks for that Sergei. I just put it in somewhat blindly because the compiler inserts it for Pascal code after the normal prologue after creating a stack frame, but complained and threw an error if I used .seh_pushreg but then neglected to use .seh_endprologue. I agree that the compiler should complain if it finds things out of order like I did, otherwise one may not know any better. I'm still learning the nuances! I'll just fix my code. Gareth aka. Kit P.S. Is there any way to remove the other patches from that bug report. P.P.S. Would you be able to say my advice was plain wrong on the forum post and correct it, just for the sake of anyone else who stumbles across it. P.P.P.S. Any possibility of inserting similar functionality for Intel-style assembler at some point? On Wed 29/11/17 14:58 , "Sergei Gorelkin via fpc-devel" sent: > > > > > 29.11.2017 15:12, J. Gareth Moreton wrote: > > > Thanks Christo. > > > > > > Apologies for 4 messages coming in at once. I > think there were a few technical glitches with the mailing > > list. Either way, I have submitted an updated > patch to the bug report in question that corrects the stack > > unwinding for Windows. Any testing would be > greatly appreciated (I'm not in a position to rigorously test > > the code for Linux). > > > > > > Yeah, I got a little emotional with Thaddy's > response (which has since been deleted), partly because he > > mocked me a bit for even attempting to use > assembly language for optimisation. Granted, I tend to do more > > low-level and mathematical programming than > higher-level components, where assembler optimisation can really > > pay dividends. Plus in a perverted way, I > actually enjoy trying to squeeze another microsecond out of > > running time! > > > > > > Gareth aka. Kit. > > > > > > > I should have read and answered earlier, but better late than never. > > > > The x86-64 target (actually, all targets except i386 and m68k) use concept > of fixed stack. This > means: all changes to the stack pointer are done at the beginning and at > the end of procedure. > Pushing something in the middle is illegal. The stack pointer itself needs > to be aligned only at the > point of calling another procedure. As a consequence, simple procedures > that don't call other > procedures and don't use nonvolatile registers can have the stack pointer > misaligned by 8 bytes as > it naturally is at the first instruction (such procedures don't need any > SEH annotations at all, > which is a way to simplify things). > > Now, several first instructions where is stack pointer is changed and > nonvolatile registers are > saved is called prologue. It is delimited by .seh_endprologue directive and > can be at most 255 bytes > in size. > > The advice given at forum to insert .seh_endprologue at the very beginning > is plain wrong. > .seh_endprologue must be the last SEH directive in procedure. Compiler > probably needs to do more > checks and reject SEH directives coming after .seh_endprologue. > > > > Regards, > > Sergei > > > > _______________________________________________ > > fpc-devel maillist - > http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel > > > > _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

J. Gareth Moreton

With no further objections, I've uploaded the patch to https://bugs.freepascal.org/view.php?id=32637 - it is prefixed with "STACK_FRAME_" - ignore the other 3 patches, as they're incorrect.

Gareth aka. Kit

On Thu 30/11/17 04:47 , "J. Gareth Moreton" sent:

Show quoted text 476 lines
Would code like this be correct? Procedure FillWord(var x; count: SizeInt; value: Word); assembler; nostackframe; asm { win64: rcx dest, rdx count, r8w value linux: rdi dest, rsi count, dx value } {$ifdef win64} push %rdi .seh_pushreg %rdi .seh_endprologue cmp $0x0, %rdx ... I recall now an assembler routine where RBX was modified midway through a procedure, but instead of pushing and popping it, it was written to a reserved part of the stack (configured in the prologue) and given a .seh_savereg hint - still trying to get my head around all of this! Kit On Thu 30/11/17 04:26 , "J. Gareth Moreton" gar sent: > Ooh right, okay. Thanks for that Sergei. I just put it in somewhat > blindly because the compiler inserts it > for Pascal code after the normal prologue after creating a stack frame, but > complained and threw an error if > I used .seh_pushreg but then neglected to use .seh_endprologue. I agree > that the compiler should complain > if it finds things out of order like I did, otherwise one may not know any > better. > > > I'm still learning the nuances! I'll just fix my code. > > > > Gareth aka. Kit > > > > P.S. Is there any way to remove the other patches from that bug report. > > > > P.P.S. Would you be able to say my advice was plain wrong on the forum post > and correct it, just for the > sake of anyone else who stumbles across it. > > > > P.P.P.S. Any possibility of inserting similar functionality for Intel-style > assembler at some point? > > > > > > > On Wed 29/11/17 14:58 , "Sergei Gorelkin via fpc-devel" sent: > > > > > > > > > > > > > > 29.11.2017 15:12, J. Gareth Moreton wrote: > > > > > > > Thanks Christo. > > > > > > > > > > > > > > Apologies for 4 messages coming in at once. > I > > think there were a few technical glitches with > the mailing > > > list. Either way, I have submitted an > updated > > patch to the bug report in question that > corrects the stack > > > unwinding for Windows. Any testing would > be > > greatly appreciated (I'm not in a position to > rigorously test > > > the code for Linux). > > > > > > > > > > > > > > Yeah, I got a little emotional with > Thaddy's > > response (which has since been deleted), partly > because he > > > mocked me a bit for even attempting to use > > > assembly language for optimisation. Granted, I > tend to do more > > > low-level and mathematical programming than > > > higher-level components, where assembler > optimisation can really > > > pay dividends. Plus in a perverted way, I > > > actually enjoy trying to squeeze another > microsecond out of > > > running time! > > > > > > > > > > > > > > Gareth aka. Kit. > > > > > > > > > > > > > > > > > > > I should have read and answered earlier, but > better late than never. > > > > > > > > > > > The x86-64 target (actually, all targets except > i386 and m68k) use concept > > of fixed stack. This > > > means: all changes to the stack pointer are done > at the beginning and at > > the end of procedure. > > > Pushing something in the middle is illegal. The > stack pointer itself needs > > to be aligned only at the > > > point of calling another procedure. As a > consequence, simple procedures > > that don't call other > > > procedures and don't use nonvolatile registers > can have the stack pointer > > misaligned by 8 bytes as > > > it naturally is at the first instruction (such > procedures don't need any > > SEH annotations at all, > > > which is a way to simplify things). > > > > > > Now, several first instructions where is stack > pointer is changed and > > nonvolatile registers are > > > saved is called prologue. It is delimited by > .seh_endprologue directive and > > can be at most 255 bytes > > > in size. > > > > > > The advice given at forum to insert > .seh_endprologue at the very beginning > > is plain wrong. > > > .seh_endprologue must be the last SEH directive > in procedure. Compiler > > probably needs to do more > > > checks and reject SEH directives coming after > .seh_endprologue. > > > > > > > > > > > Regards, > > > > > > Sergei > > > > > > > > > > > > _______________________________________________ > > > > > > fpc-devel maillist - > > http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel > > > > > > > > > > > > > > > _______________________________________________ > > fpc-devel maillist - > http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel > > > >

Reply by email