[Feature] Support for "inline" on some pure x86 assembler routines (subject to certain restrictions)
Original Reporter info from Mantis: CuriousKit @CuriousKit
-
Reporter name: J. Gareth Moreton
Original Reporter info from Mantis: CuriousKit @CuriousKit
- Reporter name: J. Gareth Moreton
Description:
This has been a work in progress for a few weeks now, and after some testing and bug fixing, it is ready for full testing and presentation.
This patch serves to permit the use of the "inline" directive with certain x86 pure assembler routines, subject to a few restrictions for safety reasons. This feature aims to give limited support for intrinsics (but is not a direct replacement for them) and the inlining of small assembler functions where the procedure call may give unnecessary overhead.
Currently, only i386 and x86_64 are supported - other platforms will not yet allow the inlining of assembler routines (it requires careful programming on each platform due to how certain operations behave).
Steps to reproduce:
Apply "x86-inline-assembler.patch" and confirm successful compilation and operation on all platforms.
Optionally apply "x86-inline-assembler-rtl-samples.patch" to apply the "inline" directive to some RTL assembler functions, and "x86-inline-assembler-tests.patch" for tests specific to this feature (some of which use the modified RTL functions).
Additional information:
Regression tests for i386-win32 and x86_64-win64 have passed. Regression tests have not been performed under Linux yet due to configuration difficulties, so I would be extremely grateful if someone is able to test this platform.
Find attached the PDF file containing the full design and implementation specification for this feature; it explains the reasons behind certain design and coding choices.
For an assembler routine to be successfully inlined, the following rules must be followed:
• The routine must be pure assembler. A Pascal function with an asm block won't count.
• The routine must have the "nostackframe" directive.
• No parameters or results can be passed on the stack. This is because the locations are different depending on if the routine is inlined or called (e.g. using CALL from another assembler routine, which pushes the return address to the stack). Pointers, including var parameters, are fine so long as they are passed via a register.
• The stack and stack pointer must not be modified under any circumstances, since it is impossible to predict what is being overwritten. This includes the use of PUSH and POP.
• No non-volatile registers can be modified, since there's no safe means to preserve them. This includes the use of CALL, since the compiler cannot predict whether the callee behaves itself in regards to preserving non-volatile registers. Just reading a non-volatile register, including the stack pointer, is permitted.
• The routine must not have any directives for structured exception handling.
Mantis conversion info:
- Mantis ID: 35232
- OS: Microsoft Windows
- OS Build: 10 Professional
- Build: r41707
- Platform: i386 and x86_64
- Version: 3.3.1
- Monitored by: » @engkin (engkin), » @MageSlayer (Denis Golovan)
- Target version: 3.3.1