Skip to content

purego: support arm soft-float abi - #494

Merged
hajimehoshi merged 1 commit into
ebitengine:mainfrom
xakep666:arm-softfloat
Aug 12, 2026
Merged

purego: support arm soft-float abi#494
hajimehoshi merged 1 commit into
ebitengine:mainfrom
xakep666:arm-softfloat

Conversation

@xakep666

Copy link
Copy Markdown
Contributor

What issue is this addressing?

Closes #490

What type of issue is this addressing?

feature

What this PR does | solves

This PR improves support of arm architecture for CPUs without FPU and for linux distros built with softfp abi.

Implementation details:

  • Pull runtime variable 'goarmsoftfp' to detect if soft-float ABI is used.
  • Assembly trampolines skips load/store to FP registers if soft-float is detected. This was implemented in exactly same way how it's done in Go runtime.
  • Apply integer passing rules for float arguments/return values.
  • Run tests for GOARM=5 (no FPU) in test workflow and add some arm-specific test cases.

Possible concerns: a way soft-float ABI usage is detected. I've decided to import a variable from 'runtime' package via //go:linkname in a specific way to ensure that &purego.runtime_goarmsoftfp == &runtime.goarmsoftfp. Last one has //go:linkname too because it's widely used across assembly routines.

Verification:

  • Added test running for with soft-float ABI to test workflow and added specific test cases.
  • Verified on real ARMv5TE CPU (Marvell Kirkwood, no FPU) by @Hirador (co-author of commit, pin-pointed some places to fix).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds ARM soft-float ABI support to purego so callbacks and registered functions work correctly on ARM CPUs/distros without an FPU (e.g., GOARM=5 / softfp), addressing SIGILL crashes caused by unconditional VFP register save/restore and incorrect float argument handling.

Changes:

  • Detect ARM soft-float ABI via runtime.goarmsoftfp and adjust argument/return handling so float32/float64 follow integer passing rules under soft-float.
  • Update ARM assembly trampolines to skip VFP register load/store when soft-float is active.
  • Extend ABI tests and CI workflow to exercise GOARM=5 (soft-float) under QEMU, including new ARM-specific ABI test cases.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
testdata/abitest/abi_test.c Adds ARM-focused float64 ABI test functions for register vs stack passing.
syscall_unix.go Adjusts callback argument restoration for float types when ARM soft-float ABI is detected.
sys_unix_arm.s Skips saving/restoring VFP regs in callback trampoline when runtime.goarmsoftfp != 0.
sys_arm.s Skips loading/saving VFP argument/return registers in syscall trampoline when soft-float is active.
internal/fakecgo/trampolines_arm.s Skips saving/restoring VFP callee-saved regs for thread-entry trampoline under soft-float.
internal/fakecgo/asm_arm.s Skips saving/restoring VFP callee-saved regs in crosscall2 under soft-float.
go_runtime.go Adds linkname reference to runtime.goarmsoftfp for soft-float detection in Go code.
func.go Implements soft-float detection and applies integer ABI rules for float args/returns on ARM soft-float.
func_test.go Adds ABI tests covering unaligned float64 passing/return (registers vs stack).
.github/workflows/test.yml Expands Linux ARM CI to also build/test GOARM=5 soft-float binaries under QEMU.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread func.go Outdated
* Pull runtime variable 'goarmsoftfp' to detect if soft-float ABI is used.
* Assembly trampolines skips load/store to FP registers if soft-float is detected. This was implemented in exactly same way how it's done in Go runtime.
* Apply integer passing rules for float arguments/return values.
* Run tests for GOARM=5 (no FPU) in test workflow and add some arm-specific test cases.

Co-authored-by: Hirador <63920290+Hirador@users.noreply.github.com>
@xakep666

Copy link
Copy Markdown
Contributor Author

Looks like android/amd64 test should be restarted. I see OOM in job logs.

@hajimehoshi hajimehoshi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems ok to depend on the runtime variable goarmsoftfp.

LGTM

@TotallyGamerJet PTAL

@TotallyGamerJet TotallyGamerJet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I do have some concern that this adds a linkname to another stdlib symbol that currently isn't marked as sticking around but since arm is tier 2 I think that's okay.

https://github.com/golang/go/blob/e9a161bda9c56e2116714785f49a83adcb3f8fd0/src/runtime/runtime2.go#L1464

@hajimehoshi
hajimehoshi merged commit f9d41fc into ebitengine:main Aug 12, 2026
49 of 50 checks passed
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.

All function/callback calls triggers SIGILL on ARMv5 cpus without FPU

5 participants