Skip to content

Spill floating-point status registers in stackman_switch. - #5

Closed
kristjanvalur wants to merge 4 commits into
armhffrom
fp-spill
Closed

kristjanvalur wants to merge 4 commits into
armhffrom
fp-spill

Conversation

@kristjanvalur

Copy link
Copy Markdown
Owner

Where a thread switch saves a floating-point control or status register, stackman_switch now 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_call does not touch these registers.

  • armhf: FPSCR, in an 8-byte slot below the pointer passed to the callback.
  • aarch64 and darwin_arm64: FPCR and FPSR, in a 16-byte slot at that pointer. The x29 adjustment is taken from the lowered stack pointer.
  • win_arm64: FPSR next to the existing FPCR spill. 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 as arm32 and runs, and that assembly does not preserve FPSCR.

This branch is stacked on the armhf port: stackless-dev#22. Merge that change first.

qemu-arm ran the armhf tests. qemu-aarch64 ran a two-stack switch of the Linux assembly. qemu-riscv64 ran the test suite, and a separate two-stack probe checked fcsr. The Darwin object assembled and was not executed. Windows ARM64 was not assembled here.

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.
@kristjanvalur

Copy link
Copy Markdown
Owner Author

Superseded. The branch is rebased onto master after stackless-dev#22 and will be opened against stackless-dev/stackman.

@kristjanvalur

Copy link
Copy Markdown
Owner Author

Replacement: stackless-dev#23

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant