Repository navigation
Spill floating-point status registers in stackman_switch. - #23
Open
kristjanvalur wants to merge 9 commits into
Open
kristjanvalur wants to merge 9 commits into
kristjanvalur wants to merge 9 commits into
Conversation
Linux saves and restores the whole FPSCR on a VFP context switch. stackman_switch stores it in an 8-byte slot below the pointer passed to the callback and writes it back after the restore callback, ahead of the d8-d15 pop. The caller-saved flag bits travel with that copy. stackman_call does not change FPSCR.
A thread switch saves both registers. Linux and macOS stackman_switch store them in a 16-byte slot at the pointer passed to the callback and write them back after the restore callback, before the epilogue pops the callee-saved registers. Windows already stored FPCR and now stores FPSR at [sp, #176]; the frame is 192 bytes. The caller-saved status bits are included. stackman_call does not touch either register. qemu-aarch64 ran a two-stack switch of the Linux assembly. The Darwin object assembled and was not executed. Windows ARM64 was not assembled here.
A softfp build does not define __ARM_PCS_VFP, so it selects arm32 and runs. The soft-float assembly does not preserve FPSCR. Do not add that spill to switch_arm_gcc.S: the file is softvfp, and vmrs fpscr is an undefined instruction without VFP.
A thread switch saves the whole fcsr. stackman_switch stores it in the existing 8-byte pad at the pointer passed to the callback and writes it back after the restore callback, before the epilogue pops fs0-fs11. The caller-saved exception flags are included. stackman_call does not touch fcsr. qemu-riscv64 ran a two-stack switch of this assembly.
The squash of the armhf port said FPSCR was still not spilled. This branch stores the whole register, so those applied-fix sentences now say so.
Later ports were being written into docs/abi-register-audit.md. That file is restored to the audit as it was merged. Current ABI, switching, and spill rules for each platform are in docs/platform-abi.md.
Later ports stay in docs/platform-abi.md.
The 16-byte spill lowered sp without telling the CFI, so callee-saved slots were described 16 bytes low across both callbacks. The CFA is sp+176 until the slot is popped. The macros sit outside the shared asm block, so the Darwin assembly stays empty there. The armhf note says the published pointer is the FPSCR slot. The Windows ARM64 note puts FPSR at [sp, #176] and says the epilogue reloads x18. The audit banner says the body is the PR 21 outcome and is not the current tree.
test_09 sets FE_DOWNWARD, lets the callback switch to FE_TOWARDZERO, and checks that the caller sees FE_DOWNWARD again on ABIs that spill the floating-point control register. A second check saves a stack while that mode is current, switches away with FE_UPWARD live, and checks that the resumed copy still has FE_DOWNWARD. Soft-float arm32 does not spill FPSCR, and the test expects the callback's mode to remain. The test programs link libm for fesetround.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Where a thread switch saves a floating-point control or status register,
stackman_switchnow saves the whole register and writes it back after the restore callback, before the epilogue pops the callee-saved registers. The caller-saved flag bits are included.stackman_calldoes not touch these registers.armhf:FPSCR, in an 8-byte slot below the pointer passed to the callback.aarch64anddarwin_arm64:FPCRandFPSR, in a 16-byte slot at that pointer. Thex29adjustment is taken from the lowered stack pointer.win_arm64:FPSRnext to the existingFPCRspill. The frame grows from 176 to 192 bytes. No SEH unwind codes were added.riscv64:fcsr, in the existing 8-byte pad at the published stack pointer. The frame stays 208 bytes.Softfp (
-mfloat-abi=softfp) is not a supported platform. It still builds asarm32and runs, and that assembly does not preserveFPSCR.qemu-armran the armhf tests.qemu-aarch64ran a two-stack switch of the Linux assembly.qemu-riscv64ran the test suite, and a separate two-stack probe checkedfcsr. The Darwin object assembled and was not executed. Windows ARM64 was not assembled here.