Commit 49548b09e0fa9fddb64e3cd47266193e36b73144 [MIPS: math-emu: Cleanup definition of structs describe sp/dp floats.] introduced a regression for pre-4.7 GCC versions that apparently have issues with static initialisers setting anonymous struct/union members, even though such members have been supported by GCC in other uses for a little bit longer. This has been figured out by Al Viro and documented in commit 05064084e82d057f8d74590c51581650e060fbb8 [fix __swap_writepage() compile failure on old gcc versions] (thanks Al!). The regression manifests itself by a load of compilation errors like: arch/mips/math-emu/ieee754.c:45: error: unknown field 'sign' specified in initializer arch/mips/math-emu/ieee754.c:45: warning: missing braces around initializer arch/mips/math-emu/ieee754.c:45: warning: (near initialization for '__ieee754dp_spcvals[0].<anonymous>') arch/mips/math-emu/ieee754.c:45: error: unknown field 'bexp' specified in initializer arch/mips/math-emu/ieee754.c:45: warning: excess elements in union initializer arch/mips/math-emu/ieee754.c:45: warning: (near initialization for '__ieee754dp_spcvals[0]') arch/mips/math-emu/ieee754.c:45: error: unknown field 'mant' specified in initializer arch/mips/math-emu/ieee754.c:45: warning: excess elements in union initializer arch/mips/math-emu/ieee754.c:45: warning: (near initialization for '__ieee754dp_spcvals[0]') -- and so on, and so on. This change gives a name back to the anonymous union members and reverts parts of the problematic commit while retaining what I believe were the good parts of the cleanup. I concluded a workaround such as one made by Al in his commit is infeasible in this context, there's simply too much static initialisation across math-emu. It is worth noting here that we still in principle support GCC versions back to 3.2: $ grep 'Gnu C' Documentation/Changes o Gnu C 3.2 # gcc --version $ and I think it makes sense to keep this support where feasible as I think from the perspective of the Linux kernel it is better if developers' time is spent on the kernel itself rather than on sorting out GCC versions. These anonymous struct/union members are a semi-standard language extension BTW, citing from a recent version of the GCC manual: -------------------------------------------------------------------------- 6 Extensions to the C Language Family ************************************* GNU C provides several language features not found in ISO standard C. (The `-pedantic' option directs GCC to print a warning message if any of these features is used.) To test for the availability of these features in conditional compilation, check for a predefined macro `__GNUC__', which is always defined under GCC. 6.59 Unnamed struct/union fields within structs/unions ====================================================== As permitted by ISO C11 and for compatibility with other compilers, GCC allows you to define a structure or union that contains, as fields, structures and unions without names. -------------------------------------------------------------------------- -- note the term "permitted" rather than "required". We do make use of a few GCC language extensions, most notably inline assembly, however in this case we merely save a couple of characters here and there and this is IMO not worth breaking people's development environments. Signed-off-by: Maciej W. Rozycki <macro@xxxxxxxxxxxxxx> --- linux-mips-anon-ieee754.patch Index: linux-20140623-4maxp64/arch/mips/math-emu/dp_sqrt.c =================================================================== --- linux-20140623-4maxp64.orig/arch/mips/math-emu/dp_sqrt.c +++ linux-20140623-4maxp64/arch/mips/math-emu/dp_sqrt.c @@ -110,13 +110,13 @@ union ieee754dp ieee754dp_sqrt(union iee /* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */ /* t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */ z = t = ieee754dp_mul(y, y); - t.bexp += 0x001; + t.parts.bexp += 0x001; t = ieee754dp_add(t, z); z = ieee754dp_mul(ieee754dp_sub(x, z), y); /* t=z/(t+x) ; pt[n0]+=0x00100000; y+=t; */ t = ieee754dp_div(z, ieee754dp_add(t, x)); - t.bexp += 0x001; + t.parts.bexp += 0x001; y = ieee754dp_add(y, t); /* twiddle last bit to force y correctly rounded */ @@ -155,7 +155,7 @@ union ieee754dp ieee754dp_sqrt(union iee } /* py[n0]=py[n0]+scalx; ...scale back y */ - y.bexp += scalx; + y.parts.bexp += scalx; /* restore rounding mode, possibly set inexact */ ieee754_csr = oldcsr; Index: linux-20140623-4maxp64/arch/mips/math-emu/ieee754.c =================================================================== --- linux-20140623-4maxp64.orig/arch/mips/math-emu/ieee754.c +++ linux-20140623-4maxp64/arch/mips/math-emu/ieee754.c @@ -36,9 +36,11 @@ #define DPCNST(s, b, m) \ { \ - .sign = (s), \ - .bexp = (b) + DP_EBIAS, \ - .mant = (m) \ + .parts = { \ + .sign = (s), \ + .bexp = (b) + DP_EBIAS, \ + .mant = (m) \ + } \ } const union ieee754dp __ieee754dp_spcvals[] = { @@ -63,9 +65,11 @@ const union ieee754dp __ieee754dp_spcval #define SPCNST(s, b, m) \ { \ - .sign = (s), \ - .bexp = (b) + SP_EBIAS, \ - .mant = (m) \ + .parts = { \ + .sign = (s), \ + .bexp = (b) + SP_EBIAS, \ + .mant = (m) \ + } \ } const union ieee754sp __ieee754sp_spcvals[] = { Index: linux-20140623-4maxp64/arch/mips/math-emu/ieee754.h =================================================================== --- linux-20140623-4maxp64.orig/arch/mips/math-emu/ieee754.h +++ linux-20140623-4maxp64/arch/mips/math-emu/ieee754.h @@ -37,7 +37,7 @@ union ieee754dp { __BITFIELD_FIELD(unsigned int bexp:11, __BITFIELD_FIELD(u64 mant:52, ;))) - }; + } parts; u64 bits; }; @@ -47,7 +47,7 @@ union ieee754sp { __BITFIELD_FIELD(unsigned bexp:8, __BITFIELD_FIELD(unsigned mant:23, ;))) - }; + } parts; u32 bits; }; Index: linux-20140623-4maxp64/arch/mips/math-emu/ieee754dp.h =================================================================== --- linux-20140623-4maxp64.orig/arch/mips/math-emu/ieee754dp.h +++ linux-20140623-4maxp64/arch/mips/math-emu/ieee754dp.h @@ -36,9 +36,9 @@ #define DP_HIDDEN_BIT DP_MBIT(DP_FBITS) #define DP_SIGN_BIT DP_MBIT(63) -#define DPSIGN(dp) (dp.sign) -#define DPBEXP(dp) (dp.bexp) -#define DPMANT(dp) (dp.mant) +#define DPSIGN(dp) (dp.parts.sign) +#define DPBEXP(dp) (dp.parts.bexp) +#define DPMANT(dp) (dp.parts.mant) static inline int ieee754dp_finite(union ieee754dp x) { @@ -70,9 +70,9 @@ static inline union ieee754dp builddp(in && (bx) <= DP_EMAX + 1 + DP_EBIAS); assert(((m) >> DP_FBITS) == 0); - r.sign = s; - r.bexp = bx; - r.mant = m; + r.parts.sign = s; + r.parts.bexp = bx; + r.parts.mant = m; return r; } Index: linux-20140623-4maxp64/arch/mips/math-emu/ieee754sp.h =================================================================== --- linux-20140623-4maxp64.orig/arch/mips/math-emu/ieee754sp.h +++ linux-20140623-4maxp64/arch/mips/math-emu/ieee754sp.h @@ -36,9 +36,9 @@ #define SP_HIDDEN_BIT SP_MBIT(SP_FBITS) #define SP_SIGN_BIT SP_MBIT(31) -#define SPSIGN(sp) (sp.sign) -#define SPBEXP(sp) (sp.bexp) -#define SPMANT(sp) (sp.mant) +#define SPSIGN(sp) (sp.parts.sign) +#define SPBEXP(sp) (sp.parts.bexp) +#define SPMANT(sp) (sp.parts.mant) static inline int ieee754sp_finite(union ieee754sp x) { @@ -75,9 +75,9 @@ static inline union ieee754sp buildsp(in && (bx) <= SP_EMAX + 1 + SP_EBIAS); assert(((m) >> SP_FBITS) == 0); - r.sign = s; - r.bexp = bx; - r.mant = m; + r.parts.sign = s; + r.parts.bexp = bx; + r.parts.mant = m; return r; }