Skip to content

purego: support structs on ppc64le#475

Merged
hajimehoshi merged 1 commit into
ebitengine:mainfrom
hajimehoshi:claude/trusting-khorana-c8f9eb
Jul 15, 2026
Merged

purego: support structs on ppc64le#475
hajimehoshi merged 1 commit into
ebitengine:mainfrom
hajimehoshi:claude/trusting-khorana-c8f9eb

Conversation

@hajimehoshi

Copy link
Copy Markdown
Member

What issue is this addressing?

Updates #474

What type of issue is this addressing?

feature

What this PR does | solves

Adds struct-by-value support for linux/ppc64le when calling C
functions, following the loong64 work in #473.

Under the ELFv2 ABI:

  • Homogeneous floating-point aggregates (1–8 members, all the same
    floating-point type) are passed and returned in the floating-point
    registers.
  • Other aggregates are passed by value across the general-purpose
    registers and the parameter save area. A floating-point argument
    shadows and skips a GPR, so an HFA argument advances the integer
    registers accordingly.
  • A non-HFA aggregate larger than two doublewords is returned through a
    caller-allocated buffer whose pointer is passed and returned in r3.

Struct arguments and returns in callbacks (NewCallback) remain
unsupported, as on the other non-amd64/arm64 architectures.

Not yet handled (skipped in the tests on ppc64le)

  • Calls needing more than eight floating-point argument registers
    (LargeFloatStructWithRegs, RectangleWithRegs); purego wires f1–f8.
  • A struct argument that follows a scalar floating-point argument
    (IdentityTwoInt64AfterPrims): the scalar float shadows a GPR, which
    purego does not model for scalars without also changing the callback
    path.

Testing

The register/stack placement and return-value reconstruction were
validated against GCC/Clang codegen by disassembling the test C for
ppc64le (ELFv2) with zig cc -target powerpc64le-linux-gnu, plus the
full host test suite. The QEMU-based ppc64le CI job exercises the struct
tests.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings July 7, 2026 05:19

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

This PR extends purego’s struct-by-value support to linux/ppc64le for RegisterFunc / RegisterLibFunc, aligning argument/return handling with the ELFv2 ABI (including HFAs), while explicitly keeping struct callbacks (NewCallback) unsupported.

Changes:

  • Add ppc64le support gating for struct arguments/returns in RegisterFunc and update platform documentation.
  • Extend the ppc64le syscall trampoline to preserve additional FP return registers (F1–F8) for HFA returns.
  • Update struct tests to run on ppc64le and skip known-unhandled register-allocation scenarios.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
sys_ppc64le.s Store FP return registers F1–F8 to support HFA returns spanning up to 8 members.
struct_test.go Enable tests on ppc64le and skip cases requiring >8 FP arg regs or scalar-float GPR shadowing.
struct_ppc64le.go Implement ppc64le-specific struct argument/return handling, including HFA classification/flattening.
README.md Update Linux platform notes to reflect ppc64le struct support tier/footnote.
func.go Allow ppc64le in struct support gate and add ppc64le-specific hidden return buffer decision logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread struct_ppc64le.go
Comment thread struct_ppc64le.go
Comment thread func.go Outdated
@hajimehoshi
hajimehoshi marked this pull request as draft July 7, 2026 06:26
@hajimehoshi
hajimehoshi marked this pull request as ready for review July 7, 2026 07:50
@hajimehoshi

Copy link
Copy Markdown
Member Author

@TotallyGamerJet PTAL

Comment thread func.go Outdated
return allFloats, numFields
}

// ppc64leLeaf is a scalar member of a flattened aggregate at byte offset offset.

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.

Shouldn't this be in struct_ppc64?

@hajimehoshi
hajimehoshi force-pushed the claude/trusting-khorana-c8f9eb branch from 228c2a8 to 57238c4 Compare July 8, 2026 15:41
Comment thread struct_notppc64le.go Outdated
@hajimehoshi
hajimehoshi marked this pull request as draft July 12, 2026 13:25
Pass and return structs by value when calling C functions under the
ELFv2 ABI: a homogeneous floating-point aggregate is passed and returned
in the floating-point registers whatever its size, any other aggregate
occupies successive doublewords in the general-purpose registers and the
parameter save area, and a non-homogeneous aggregate larger than two
doublewords is returned through a caller-allocated buffer. Scalar float32
arguments are passed in double-precision format, matching the FMOVD-based
convention already used for float32 struct members and float returns;
reading float32 callback arguments does the inverse conversion.

Widen structReturnInMemory to take the return type rather than its size,
so ppc64le can keep a homogeneous floating-point aggregate in registers
regardless of size while every other architecture keeps its size-only
rule.

Struct arguments and returns in callbacks remain unsupported, as on the
other non-amd64/arm64 architectures. Aggregates that need more than eight
floating-point argument registers, and functions taking mixed scalar
floating-point and integer arguments, are not yet handled; the latter
needs the ELFv2 general-purpose register shadowing that purego does not
model for scalar arguments.

Updates ebitengine#474

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@hajimehoshi
hajimehoshi force-pushed the claude/trusting-khorana-c8f9eb branch from fa5e1fb to e70cfc4 Compare July 13, 2026 02:55
@hajimehoshi
hajimehoshi marked this pull request as ready for review July 13, 2026 02:55

@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

@hajimehoshi
hajimehoshi merged commit b1a632f into ebitengine:main Jul 15, 2026
25 checks passed
@hajimehoshi
hajimehoshi deleted the claude/trusting-khorana-c8f9eb branch July 15, 2026 03:35
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.

3 participants