Fix MSVC C89 build: portable unaligned 64-bit store in pputile.h

The per-tile fast path used a GCC-only typedef
  typedef uint64_t fceu_u64_unaligned __attribute__((may_alias, aligned(1)));
which MSVC cannot parse, producing C2146/C2065/C2143 at every point
pputile.h is textually included in ppu.c.

Split the store by compiler: keep the may_alias typedef for GCC/Clang
(preserving the direct movq) and use memcpy on MSVC, which is
strict-aliasing-safe and lowers to the same unaligned 64-bit store.
ppu.c already includes <string.h> and is the only includer, so memcpy
is always in scope. The packed value stays declared at the top of the
block, keeping the C89 declaration-before-statement rule intact.
This commit is contained in:
LibretroAdmin
2026-06-14 13:54:13 +00:00
committed by U-DESKTOP-SPFP6AQ\twistedtechre
parent a502ceafc4
commit e4b039b604

View File

@@ -31,13 +31,21 @@ if (X1 >= 2) {
* a stack scratch (which the obvious __builtin_memcpy / packed- * a stack scratch (which the obvious __builtin_memcpy / packed-
* struct form would force, costing the optimisation entirely). */ * struct form would force, costing the optimisation entirely). */
{ {
typedef uint64_t fceu_u64_unaligned __attribute__((may_alias, aligned(1)));
uint64_t packed = uint64_t packed =
(uint64_t)fceu_bg_pair_lut[ pixdata & 0xFF] | (uint64_t)fceu_bg_pair_lut[ pixdata & 0xFF] |
((uint64_t)fceu_bg_pair_lut[(pixdata >> 8) & 0xFF] << 16) | ((uint64_t)fceu_bg_pair_lut[(pixdata >> 8) & 0xFF] << 16) |
((uint64_t)fceu_bg_pair_lut[(pixdata >> 16) & 0xFF] << 32) | ((uint64_t)fceu_bg_pair_lut[(pixdata >> 16) & 0xFF] << 32) |
((uint64_t)fceu_bg_pair_lut[(pixdata >> 24) & 0xFF] << 48); ((uint64_t)fceu_bg_pair_lut[(pixdata >> 24) & 0xFF] << 48);
#if defined(__GNUC__) || defined(__clang__)
/* may_alias + aligned(1) lets gcc emit a direct movq without
* routing through a stack scratch. */
typedef uint64_t fceu_u64_unaligned __attribute__((may_alias, aligned(1)));
*(fceu_u64_unaligned *)P = packed; *(fceu_u64_unaligned *)P = packed;
#else
/* MSVC has no may_alias; memcpy is strict-aliasing-safe and is
* lowered to the same unaligned 64-bit store. */
memcpy(P, &packed, sizeof(packed));
#endif
} }
P += 8; P += 8;
} }