)]}'
{
  "commit": "a7ae7a0e1e4ce10dbd25af8099af2085c5e8b76f",
  "tree": "72f43e749197e816eb61bdd1b7edbee449a61348",
  "parents": [
    "9760868682cc9a33008761f158d86481d56738aa"
  ],
  "author": {
    "name": "Anthony Green",
    "email": "green@moxielogic.com",
    "time": "Fri May 22 11:31:49 2026 -0400"
  },
  "committer": {
    "name": "Anthony Green",
    "email": "green@moxielogic.com",
    "time": "Fri May 22 11:31:49 2026 -0400"
  },
  "message": "powerpc64: support FFI_TYPE_COMPLEX under ELFv2\n\nThe reporter of #962 hits a 1-slot drift on ppc64le when passing a\nfloat _Complex argument followed by an int: the C callee, compiled by\nGCC, treats the complex per ELFv2 §2.2.3.2.2 (split_complex_arg) and\nreserves *two* GPR shadow slots for the two halves, while libffi has\nno complex support for PowerPC and sees only the user\u0027s surrogate\nstruct{float;float;} (one GPR shadow slot under HFA packing). All\nsubsequent integer args land in the wrong register.\n\nAdd FFI_TYPE_COMPLEX support for the LINUX64 / ELFv2 path:\n\n  * ffitarget.h: define FFI_TARGET_HAS_COMPLEX_TYPE for POWERPC64 +\n    _CALL_ELF \u003d\u003d 2 so prep_cif accepts the type and types.c emits the\n    ffi_type_complex_{float,double,longdouble} symbols.\n\n  * ffi_linux64.c, arg path (prep_cif + prep_args64 + closure helper):\n    each half of a _Complex argument is now passed independently —\n    float/double halves go to consecutive FPRs and consume one GPR\n    shadow slot each; integer halves go to consecutive GPR slots\n    sign-/zero-extended to doublewords. This matches what GCC\u0027s\n    split_complex_arg emits and fixes the 1-slot drift.\n\n  * ffi_linux64.c, return path: float/double complex are returned via\n    the existing 2-element FP-HFA assembly path (PPC64_LD_FLOAT_HOMOG /\n    PPC64_LD_DOUBLE_HOMOG, FLAG_RETURNS_SMST + FLAG_RETURNS_FP).\n    Integer complex are returned via .Lsmall_struct with FLAG_RETURNS_SMST\n    only; ffi.c repacks the bounce buffer (real in slot 0, imag in\n    slot 8) into the caller\u0027s natural packed layout, and the closure\n    helper repacks the user-written packed value into two doublewords\n    before returning PPC_LD_R3R4.\n\n  * discover_homogeneous_aggregate now recurses through FFI_TYPE_COMPLEX\n    of float/double, so a struct containing _Complex float/double members\n    is recognised as an FP HFA (matches GCC\u0027s HFA rule for aggregates\n    containing complex). The top-level complex arg/return paths bypass\n    this and use their own switch cases.\n\n64-bit long double complex is treated as _Complex double. IBM-128 and\nIEEE-binary128 _Complex are explicitly rejected (FFI_BAD_TYPEDEF) and\nleft as follow-up work; the same applies to PPC32 SysV and ELFv1.\n\nFixes #962.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) \u003cnoreply@anthropic.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "3601cc4ab1e2aa8b15771ebb7c403ee05674eb18",
      "old_mode": 33188,
      "old_path": "src/powerpc/ffi.c",
      "new_id": "1afa582ebead82f39fe60192eaeaa3bc3cc27f97",
      "new_mode": 33188,
      "new_path": "src/powerpc/ffi.c"
    },
    {
      "type": "modify",
      "old_id": "3c2e19ada6cd8ae10f253b599722757e56e449a4",
      "old_mode": 33188,
      "old_path": "src/powerpc/ffi_linux64.c",
      "new_id": "4a4fe86beff1f2a0f823812b04c09ddd655e180b",
      "new_mode": 33188,
      "new_path": "src/powerpc/ffi_linux64.c"
    },
    {
      "type": "modify",
      "old_id": "2088cd699011076845a3293b323e8a9159f843f5",
      "old_mode": 33188,
      "old_path": "src/powerpc/ffitarget.h",
      "new_id": "cf67a9bba6ee3342b33717ecb829d9d4c131e6be",
      "new_mode": 33188,
      "new_path": "src/powerpc/ffitarget.h"
    }
  ]
}
