)]}'
{
  "commit": "2aabe7eb739a16197ed0fcaacb45eeba76149c19",
  "tree": "fb76fc2d2c7e1c797a8cd6d7d044e1b2147fa1fc",
  "parents": [
    "22c1a3e67a06c498c94dd5fca85692f9ae80dd8f"
  ],
  "author": {
    "name": "Anthony Green",
    "email": "green@moxielogic.com",
    "time": "Fri Jun 19 20:04:09 2026 -0400"
  },
  "committer": {
    "name": "Anthony Green",
    "email": "green@moxielogic.com",
    "time": "Fri Jun 19 20:04:09 2026 -0400"
  },
  "message": "x86: support IEEE binary128 long double on x86_64 (e.g. Android)\n\nOn most x86_64 targets `long double` is the 80-bit x87 type, which the SysV\npsABI classifies X87/X87UP, passes in memory, and returns in st(0).  But some\nx86_64 targets -- notably Android (bionic), and anything built with\n-mlong-double-128 -- make `long double` the IEEE binary128 quad type, which the\npsABI passes and returns in SSE registers exactly like __float128 (class\nSSE/SSEUP, i.e. one %xmm register; _Complex binary128 is 32 bytes -\u003e memory).\n\nlibffi\u0027s x86_64 backend hardcoded the x87 path, so every long double call/return\non x86_64 Android produced garbage (sizeof(long double)\u003d\u003d16 for both formats, so\nthe configure check could not tell them apart).  This was misdiagnosed as a QEMU\nor bionic-on-host issue; it is a real ABI bug -- the binaries run natively, the\nABI is simply different.  Confirmed via the compiler: x86_64-linux-android sets\n__LDBL_MANT_DIG__\u003d113 (binary128) and emits __addtf3/%xmm, vs 64/fldt on glibc.\n\nDetect binary128 long double at compile time (__LDBL_MANT_DIG__ \u003d\u003d 113) and:\n  - classify scalar long double as SSE/SSEUP, returned in %xmm0 (new\n    UNIX64_RET_XMM128 store/load path: movups %xmm0);\n  - classify _Complex long double as memory (passed/returned via hidden pointer);\n  - copy the SSEUP eightbyte (the high half of the same %xmm register) in both\n    the call and closure argument marshalling, which previously dropped it.\n\nEverything is gated on the compile-time check, so x87 targets (glibc, *BSD,\nmacOS) are byte-for-byte unchanged.\n\nValidated by building with `-mlong-double-128` on x86_64 glibc (which reproduces\nthe Android ABI: __addtf3/%xmm) and round-tripping a full-precision binary128\nvalue through both ffi_call and a closure -- both preserve all 113 mantissa bits.\nx87 long double regression is clean (full testsuite, 0 unexpected failures).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "68974e52a063dc6539ae3fdb76ba6f27d58458f5",
      "old_mode": 33188,
      "old_path": "README.md",
      "new_id": "a6af555a0fb50362eb4ed8e0c6b1397e3c446fd1",
      "new_mode": 33188,
      "new_path": "README.md"
    },
    {
      "type": "modify",
      "old_id": "d311d6108118452db9dbeeb0e94253a7ae7602ef",
      "old_mode": 33188,
      "old_path": "src/x86/ffi64.c",
      "new_id": "db0aa563a879472ab462a6bbaf7c8fafb3a682df",
      "new_mode": 33188,
      "new_path": "src/x86/ffi64.c"
    },
    {
      "type": "modify",
      "old_id": "282b408027444e9abf3dda04257c17626ddb83b2",
      "old_mode": 33188,
      "old_path": "src/x86/internal64.h",
      "new_id": "ca2b0ade3b6d32632782cf3d9ed04d0102bb4cc2",
      "new_mode": 33188,
      "new_path": "src/x86/internal64.h"
    },
    {
      "type": "modify",
      "old_id": "d9c5bd4c720db1b2feda988dd5b1854331c163ad",
      "old_mode": 33188,
      "old_path": "src/x86/unix64.S",
      "new_id": "0b3085b20de79db669848175c792717a259f2346",
      "new_mode": 33188,
      "new_path": "src/x86/unix64.S"
    }
  ]
}
