From d7e34aeba2c18ca2e520d4805b6e2fa246bfa399 Mon Sep 17 00:00:00 2001 From: rofl0r <rofl0r@users.noreply.github.com> Date: Wed, 2 Mar 2022 03:22:01 +0000 Subject: [PATCH] z80: fix compatibility with big-endian the macros used are exposed by default on gcc >= 4.8.x, and clang 3.1 and most other compilers. before: $ qemu-ppc z80test zexall.cim *** TEST: zexall.cim *** 25390418 instructions executed on 25390418 cycles (expected=268500992, diff=46734978649) after: $ qemu-ppc z80test zexall.cim *** TEST: zexall.cim Z80all instruction exerciser <adc,sbc> hl,<bc,de,hl,sp>.... OK add hl,<bc,de,hl,sp>.......... OK ... --- chips/z80.h | 30 +++++++++++++++++++----------- codegen/z80.template.h | 30 +++++++++++++++++++----------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/chips/z80.h b/chips/z80.h index 309b3f37..69b35d7c 100644 --- a/chips/z80.h +++ b/chips/z80.h @@ -294,6 +294,14 @@ extern "C" { #define Z80_ZF (1<<6) // zero #define Z80_SF (1<<7) // sign +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define Z80_REGDEF(A, B, AB) \ + union { struct { uint8_t B; uint8_t A; }; uint16_t AB; } +#else +#define Z80_REGDEF(A, B, AB) \ + union { struct { uint8_t A; uint8_t B; }; uint16_t AB; } +#endif + // CPU state typedef struct { uint16_t step; // the currently active decoder step @@ -304,23 +312,23 @@ typedef struct { bool prefix_active; // true if any prefix currently active (only needed in z80_opdone()) uint64_t pins; // last pin state, used for NMI detection uint64_t int_bits; // track INT and NMI state - union { struct { uint8_t pcl; uint8_t pch; }; uint16_t pc; }; + Z80_REGDEF(pch, pcl, pc); // NOTE: These unions are fine in C, but not C++. - union { struct { uint8_t f; uint8_t a; }; uint16_t af; }; - union { struct { uint8_t c; uint8_t b; }; uint16_t bc; }; - union { struct { uint8_t e; uint8_t d; }; uint16_t de; }; + Z80_REGDEF(a, f, af); + Z80_REGDEF(b, c, bc); + Z80_REGDEF(d, e, de); union { struct { - union { struct { uint8_t l; uint8_t h; }; uint16_t hl; }; - union { struct { uint8_t ixl; uint8_t ixh; }; uint16_t ix; }; - union { struct { uint8_t iyl; uint8_t iyh; }; uint16_t iy; }; + Z80_REGDEF(h, l, hl); + Z80_REGDEF(ixh, ixl, ix); + Z80_REGDEF(iyh, iyl, iy); }; - struct { union { struct { uint8_t l; uint8_t h; }; uint16_t hl; }; } hlx[3]; + struct { Z80_REGDEF(h, l, hl); } hlx[3]; }; - union { struct { uint8_t wzl; uint8_t wzh; }; uint16_t wz; }; - union { struct { uint8_t spl; uint8_t sph; }; uint16_t sp; }; - union { struct { uint8_t r; uint8_t i; }; uint16_t ir; }; + Z80_REGDEF(wzh, wzl, wz); + Z80_REGDEF(sph, spl, sp); + Z80_REGDEF(i, r, ir); uint16_t af2, bc2, de2, hl2; // shadow register bank uint8_t im; bool iff1, iff2; diff --git a/codegen/z80.template.h b/codegen/z80.template.h index a9305eff..a60c6a72 100644 --- a/codegen/z80.template.h +++ b/codegen/z80.template.h @@ -294,6 +294,14 @@ extern "C" { #define Z80_ZF (1<<6) // zero #define Z80_SF (1<<7) // sign +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define Z80_REGDEF(A, B, AB) \ + union { struct { uint8_t B; uint8_t A; }; uint16_t AB; } +#else +#define Z80_REGDEF(A, B, AB) \ + union { struct { uint8_t A; uint8_t B; }; uint16_t AB; } +#endif + // CPU state typedef struct { uint16_t step; // the currently active decoder step @@ -304,23 +312,23 @@ typedef struct { bool prefix_active; // true if any prefix currently active (only needed in z80_opdone()) uint64_t pins; // last pin state, used for NMI detection uint64_t int_bits; // track INT and NMI state - union { struct { uint8_t pcl; uint8_t pch; }; uint16_t pc; }; + Z80_REGDEF(pch, pcl, pc); // NOTE: These unions are fine in C, but not C++. - union { struct { uint8_t f; uint8_t a; }; uint16_t af; }; - union { struct { uint8_t c; uint8_t b; }; uint16_t bc; }; - union { struct { uint8_t e; uint8_t d; }; uint16_t de; }; + Z80_REGDEF(a, f, af); + Z80_REGDEF(b, c, bc); + Z80_REGDEF(d, e, de); union { struct { - union { struct { uint8_t l; uint8_t h; }; uint16_t hl; }; - union { struct { uint8_t ixl; uint8_t ixh; }; uint16_t ix; }; - union { struct { uint8_t iyl; uint8_t iyh; }; uint16_t iy; }; + Z80_REGDEF(h, l, hl); + Z80_REGDEF(ixh, ixl, ix); + Z80_REGDEF(iyh, iyl, iy); }; - struct { union { struct { uint8_t l; uint8_t h; }; uint16_t hl; }; } hlx[3]; + struct { Z80_REGDEF(h, l, hl); } hlx[3]; }; - union { struct { uint8_t wzl; uint8_t wzh; }; uint16_t wz; }; - union { struct { uint8_t spl; uint8_t sph; }; uint16_t sp; }; - union { struct { uint8_t r; uint8_t i; }; uint16_t ir; }; + Z80_REGDEF(wzh, wzl, wz); + Z80_REGDEF(sph, spl, sp); + Z80_REGDEF(i, r, ir); uint16_t af2, bc2, de2, hl2; // shadow register bank uint8_t im; bool iff1, iff2;