Patchwork replace LIBGCC2_WORDS_BIG_ENDIAN with __WORDS_BIG_ENDIAN__

login
register
mail settings
Submitter Nathan Froyd
Date Oct. 12, 2010, 8:48 p.m.
Message ID <20101012204838.GE24720@nightcrawler>
Download mbox | patch
Permalink /patch/67611/
State New
Headers show

Comments

Nathan Froyd - Oct. 12, 2010, 8:48 p.m.
The patch below eliminates the need for LIBGCC2_WORDS_BIG_ENDIAN by
having the compiler define __WORDS_BIG_ENDIAN__ and appropriate places
use that instead.  The motivating idea here is that the compiler should
be queried for all target-specific knowledge when compiling target
libraries.  I plan to replace several other macros in a similar fashion.

Boostrapped on x86_64-unknown-linux-gnu, also tested with cross to
mips-elf and powerpc-eabispe as bi-endian targets.  Need C approval for
the cppbuiltin.c change and global approval for CPU changes etc.  OK to
commit?

-Nathan

gcc/
	* cppbuiltin.c (define_builtin_macros_for_type_sizes): Define
	__WORDS_BIG_ENDIAN__.
	* libgcc2.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	(struct DWstruct): Define based on __WORDS_BIG_ENDIAN__.
	* config/fixed-bit.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	(struct INTstruct): Define based on __WORDS_BIG_ENDIAN__.
	* config/dfp-bit.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	(LIBGCC2_FLOAT_WORDS_BIG_ENDIAN): Default to __WORDS_BIG_ENDIAN__.
	* system.h (LIBGCC2_WORDS_BIG_ENDIAN): Poison identifier.
	* config/arc/arc.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/arm/arm.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/ia64/ia64.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/iq2000/iq2000.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/lm32/lm32.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/m32r/m32r.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/mcore/mcore.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/mep/mep.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/mips/mips.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/rs6000/sysv4.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/rx/rx.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/score/score.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/sh/sh.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/sparc/sparc.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* config/xtensa/xtensa.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* doc/tm.texi.in (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	* doc/tm.texi: Regenerate.

libdecnumber/
	* dconfig.h (LIBGCC2_WORDS_BIG_ENDIAN): Delete.
	(LIBGCC2_FLOAT_WORDS_BIG_ENDIAN): Default to __WORDS_BIG_ENDIAN__.

libgcc/
	* config/libbid/bid_gcc_intrinsics.h (LIBGCC2_WORDS_BIG_ENDIAN):
	Delete.
	(LIBGCC2_FLOAT_WORDS_BIG_ENDIAN): Default to __WORDS_BIG_ENDIAN__.
Andrew Pinski - Oct. 12, 2010, 8:52 p.m.
On Tue, Oct 12, 2010 at 1:48 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> The patch below eliminates the need for LIBGCC2_WORDS_BIG_ENDIAN by
> having the compiler define __WORDS_BIG_ENDIAN__ and appropriate places
> use that instead.  The motivating idea here is that the compiler should
> be queried for all target-specific knowledge when compiling target
> libraries.  I plan to replace several other macros in a similar fashion.
>
> Boostrapped on x86_64-unknown-linux-gnu, also tested with cross to
> mips-elf and powerpc-eabispe as bi-endian targets.  Need C approval for
> the cppbuiltin.c change and global approval for CPU changes etc.  OK to
> commit?

I like this patch as it removes one more host vs target header issue.
That is it removes one more place where we need to include a header
from gcc/config/ in a target library.

Thanks,
Andrew Pinski
Jakub Jelinek - Oct. 12, 2010, 9:03 p.m.
On Tue, Oct 12, 2010 at 04:48:39PM -0400, Nathan Froyd wrote:
> The patch below eliminates the need for LIBGCC2_WORDS_BIG_ENDIAN by
> having the compiler define __WORDS_BIG_ENDIAN__ and appropriate places
> use that instead.  The motivating idea here is that the compiler should
> be queried for all target-specific knowledge when compiling target
> libraries.  I plan to replace several other macros in a similar fashion.

Wouldn't it be better to define something like __BYTE_ORDER__
to 1234, 4321 or 3421 for little endian (WORDS+BYTES), big endian
(WORDS+BYTES) and PDP endian (see glibc's endian.h+bits/endian.h)?
That would avoid having to define also __BYTES_BIG_ENDIAN__ macro
and would be less misleading (seeing __WORDS_BIG_ENDIAN__ defined, albeit to
0, can be easily thought as that words are big endian rather than little
endian).

	Jakub
Richard Henderson - Oct. 12, 2010, 9:12 p.m.
On 10/12/2010 02:03 PM, Jakub Jelinek wrote:
> On Tue, Oct 12, 2010 at 04:48:39PM -0400, Nathan Froyd wrote:
>> The patch below eliminates the need for LIBGCC2_WORDS_BIG_ENDIAN by
>> having the compiler define __WORDS_BIG_ENDIAN__ and appropriate places
>> use that instead.  The motivating idea here is that the compiler should
>> be queried for all target-specific knowledge when compiling target
>> libraries.  I plan to replace several other macros in a similar fashion.
> 
> Wouldn't it be better to define something like __BYTE_ORDER__
> to 1234, 4321 or 3421 for little endian (WORDS+BYTES), big endian
> (WORDS+BYTES) and PDP endian (see glibc's endian.h+bits/endian.h)?
> That would avoid having to define also __BYTES_BIG_ENDIAN__ macro
> and would be less misleading (seeing __WORDS_BIG_ENDIAN__ defined, albeit to
> 0, can be easily thought as that words are big endian rather than little
> endian).

FWIW, I prefer this scheme.


r~
Mark Mitchell - Oct. 12, 2010, 10:15 p.m.
On 10/12/2010 2:12 PM, Richard Henderson wrote:

>> Wouldn't it be better to define something like __BYTE_ORDER__
>> to 1234, 4321 or 3421 for little endian (WORDS+BYTES), big endian
>> (WORDS+BYTES) and PDP endian (see glibc's endian.h+bits/endian.h)?

> FWIW, I prefer this scheme.

Do you mean for __BYTE_ORDER__ to be a new built-in macro?  That has
some complexity; we have to consider 64-bit machines (where the values
might be things like 56781234) or machines without 8-bit bytes.

It seems to me that this is orthogonal to Nathan's patch, which seems
like a monotonic improvement over the existing codebase.  I'd rather see
that go in, and if someone wants to invent this other thing later...
Richard Henderson - Oct. 12, 2010, 10:40 p.m.
On 10/12/2010 03:15 PM, Mark Mitchell wrote:
> On 10/12/2010 2:12 PM, Richard Henderson wrote:
> 
>>> Wouldn't it be better to define something like __BYTE_ORDER__
>>> to 1234, 4321 or 3421 for little endian (WORDS+BYTES), big endian
>>> (WORDS+BYTES) and PDP endian (see glibc's endian.h+bits/endian.h)?
> 
>> FWIW, I prefer this scheme.
> 
> Do you mean for __BYTE_ORDER__ to be a new built-in macro? 

Yes.

> That has
> some complexity; we have to consider 64-bit machines (where the values
> might be things like 56781234)

Er.. honestly do you believe anyone will ever produce something like
pdp-endian again?  I don't.  It's too complicated.  I think (and hope
and pray) that the 3 states that we have are all we'll ever see.

> or machines without 8-bit bytes.

What has that got to do with anything?  We're already talking about
addressable units.

> It seems to me that this is orthogonal to Nathan's patch, which seems
> like a monotonic improvement over the existing codebase.  I'd rather see
> that go in, and if someone wants to invent this other thing later...

I don't think it's orthogonal at all.  I think it's clearly related
to choosing the API that we want to support.


r~
Joseph S. Myers - Oct. 12, 2010, 11:48 p.m.
On Tue, 12 Oct 2010, Nathan Froyd wrote:

> The patch below eliminates the need for LIBGCC2_WORDS_BIG_ENDIAN by
> having the compiler define __WORDS_BIG_ENDIAN__ and appropriate places
> use that instead.  The motivating idea here is that the compiler should
> be queried for all target-specific knowledge when compiling target
> libraries.  I plan to replace several other macros in a similar fashion.

I don't see any documentation of this new macro in cpp.texi.  Such 
documentation is needed - and I think it needs to explain in user terms 
exactly what is meant by "word" (is it always the same as what 
__attribute__((__mode__(__word__))) gives you? what is that anyway?) so 
that the exact implications for byte ordering of integer types in memory 
are clear.  The same applies to any other macro scheme - make clear 
exactly what is being asserted about type representations by the macro 
value.

As I understand it, the only current cases in GCC where WORDS_BIG_ENDIAN 
and BYTES_BIG_ENDIAN may differ are:

* pdp11.

* arm, with -mwords-little-endian.  "Note: this option should only be used 
if you require compatibility with code for big-endian ARM processors 
generated by versions of the compiler prior to 2.8.".  It could probably 
be removed by now.

* powerpc-wrs-vxworks and powerpc-wrs-vxworksae, with -mlittle-endian / 
-mlittle, because rs6000/sysv4.h allows both endiannesses but then 
rs6000/vxworks.h undefines and redefines only BYTES_BIG_ENDIAN, so 
allowing word endianness to vary but not byte endianness.  Redefining only 
one macro is clearly a bug here.
Mark Mitchell - Oct. 12, 2010, 11:52 p.m.
On 10/12/2010 3:40 PM, Richard Henderson wrote:

>> That has
>> some complexity; we have to consider 64-bit machines (where the values
>> might be things like 56781234)
> 
> Er.. honestly do you believe anyone will ever produce something like
> pdp-endian again?  I don't.  It's too complicated.  I think (and hope
> and pray) that the 3 states that we have are all we'll ever see.

Well, I hope we don't, but I don't feel that confident.  The hardware
designers keep doing things that surprise me, and old architectures keep
coming out of the woodwork.

>> or machines without 8-bit bytes.
> 
> What has that got to do with anything?  We're already talking about
> addressable units.

OK.

>> It seems to me that this is orthogonal to Nathan's patch, which seems
>> like a monotonic improvement over the existing codebase.  I'd rather see
>> that go in, and if someone wants to invent this other thing later...
> 
> I don't think it's orthogonal at all.  I think it's clearly related
> to choosing the API that we want to support.

My point was that the current codebase uses the WORDS_BIG_ENDIAN
approach; Nathan's patch just changes things to get this from the
compiler automatically rather than from target headers.  The change to a
different way of expressing this in the libgcc code seems like a
separate activity.  Am I missing something?

Nathan's trying to decouple libgcc from the target headers as part of
moving forward the top-level libgcc project; just seems unfortunate to
slow that down.  But, if you think that __BYTE_ORDER__ is a lot better,
I don't mind; just means we have to go implement that first.
Richard Henderson - Oct. 13, 2010, 4:02 p.m.
On 10/12/2010 04:52 PM, Mark Mitchell wrote:
> My point was that the current codebase uses the WORDS_BIG_ENDIAN
> approach; Nathan's patch just changes things to get this from the
> compiler automatically rather than from target headers.  The change to a
> different way of expressing this in the libgcc code seems like a
> separate activity.  Am I missing something?

The conversion to __WORDS_BIG_ENDIAN__ is exposed to end users.

If it were just moving macros around in gcc internal header files
that would be one thing, but this is a case of determining the
public api that gcc supports.


r~
Mark Mitchell - Oct. 13, 2010, 4:28 p.m.
On 10/13/2010 9:02 AM, Richard Henderson wrote:

> The conversion to __WORDS_BIG_ENDIAN__ is exposed to end users.
> 
> If it were just moving macros around in gcc internal header files
> that would be one thing, but this is a case of determining the
> public api that gcc supports.

OK.  I don't see this as a big deal either way, but since <endian.h> on
GNU/Linux systems already uses the convention Jakub suggested, it does
seem reasonable to follow that convention.
Nathan Froyd - Oct. 14, 2010, 12:10 a.m.
On Wed, Oct 13, 2010 at 09:02:46AM -0700, Richard Henderson wrote:
> On 10/12/2010 04:52 PM, Mark Mitchell wrote:
> > My point was that the current codebase uses the WORDS_BIG_ENDIAN
> > approach; Nathan's patch just changes things to get this from the
> > compiler automatically rather than from target headers.  The change to a
> > different way of expressing this in the libgcc code seems like a
> > separate activity.  Am I missing something?
> 
> The conversion to __WORDS_BIG_ENDIAN__ is exposed to end users.
> 
> If it were just moving macros around in gcc internal header files
> that would be one thing, but this is a case of determining the
> public api that gcc supports.

I understand the rationale here and am happy to revise the patch based
on the discussion here.

But your point about this being a public API raises an interesting
question: what to do about those macros which are legitimately used in
both the compiler and libgcc?  (Examples include HAS_INIT_SECTION,
EH_FRAME_SECTION_NAME, and CLEAR_CACHE.)  I don't think anybody would be
happy with duplicate definitions in libgcc/config and gcc/config.  Is it
legitimate to define macros for such target macros to effectively
transfer information from the compiler to runtime libraries, or is there
a better way?

-Nathan
Mark Mitchell - Oct. 14, 2010, 12:17 a.m.
On 10/13/2010 5:10 PM, Nathan Froyd wrote:

> But your point about this being a public API raises an interesting
> question: what to do about those macros which are legitimately used in
> both the compiler and libgcc?  (Examples include HAS_INIT_SECTION,
> EH_FRAME_SECTION_NAME, and CLEAR_CACHE.)

I think CLEAR_CACHE is actually a built-in now, right?  So, that should
be no problem.

For the other ones, I think a compiler pre-defined macro is reasonable.
 That's the only method I can think of that doesn't require replicating
configuration information, other than autoconf tests.  And, if this
information is useful in libgcc, it might well be useful in some other
low-level context.

I suppose autoconf tests are a possibility, but that seems pretty
fragile; for example, we'd have to compile something with initializers
and then grep around in the generated .s file to figure out whether
HAS_INIT_SECTION did something or not.
Nathan Froyd - Oct. 14, 2010, 12:26 a.m.
On Wed, Oct 13, 2010 at 05:17:39PM -0700, Mark Mitchell wrote:
> On 10/13/2010 5:10 PM, Nathan Froyd wrote:
> > But your point about this being a public API raises an interesting
> > question: what to do about those macros which are legitimately used in
> > both the compiler and libgcc?  (Examples include HAS_INIT_SECTION,
> > EH_FRAME_SECTION_NAME, and CLEAR_CACHE.)
> 
> I think CLEAR_CACHE is actually a built-in now, right?  So, that should
> be no problem.

CLEAR_INSN_CACHE (sorry, botched the name, confused it with the builtin
name) is problematic because the builtin expander uses its presence to
determine how to expand, e.g. builtins.c:expand_builtin___clear_cache:

#ifndef HAVE_clear_cache
#ifdef CLEAR_INSN_CACHE
  /* There is no "clear_cache" insn, and __clear_cache() in libgcc
     does something.  Just do the default expansion to a call to
     __clear_cache().  */
  return NULL_RTX;
#else
  /* There is no "clear_cache" insn, and __clear_cache() in libgcc
     does nothing.  There is no need to call it.  Do nothing.  */
  return const0_rtx;
#endif /* CLEAR_INSN_CACHE */
#else
  /* We have a "clear_cache" insn, and it will handle everything.  */
  ...

and in libgcc2.c:

void
__clear_cache (char *beg __attribute__((__unused__)),
	       char *end __attribute__((__unused__)))
{
#ifdef CLEAR_INSN_CACHE
  CLEAR_INSN_CACHE (beg, end);
#endif /* CLEAR_INSN_CACHE */
}

I guess for that particular one, we could try converting the
CLEAR_INSN_CACHE users into clear_cache insns.  That would have the
downside of inlining code where it might not be desirable.

> I suppose autoconf tests are a possibility, but that seems pretty
> fragile; for example, we'd have to compile something with initializers
> and then grep around in the generated .s file to figure out whether
> HAS_INIT_SECTION did something or not.

I didn't think about autoconf tests, but...oof.  Yes, please, not that.

-Nathan
Mark Mitchell - Oct. 14, 2010, 12:36 a.m.
On 10/13/2010 5:26 PM, Nathan Froyd wrote:

Given the libgcc use:

> void
> __clear_cache (char *beg __attribute__((__unused__)),
> 	       char *end __attribute__((__unused__)))
> {
> #ifdef CLEAR_INSN_CACHE
>   CLEAR_INSN_CACHE (beg, end);
> #endif /* CLEAR_INSN_CACHE */
> }

Why not make CLEAR_INSN_CACHE a builtin, then, with the target back-end
providing the definition of the built-in?  Then, ligcc can just call it.
 It can be a no-op builtin if we don't have anything to do.

And, in the compiler proper, instead of CLEAR_INSN_CACHE, we just have a
boolean, defined by the target header if it doesn't provide a
clear_cache instruction, that says whether to call the libgcc function.
David Daney - Oct. 14, 2010, 1:01 a.m.
On 10/13/2010 05:36 PM, Mark Mitchell wrote:
> On 10/13/2010 5:26 PM, Nathan Froyd wrote:
>
> Given the libgcc use:
>
>> void
>> __clear_cache (char *beg __attribute__((__unused__)),
>> 	       char *end __attribute__((__unused__)))
>> {
>> #ifdef CLEAR_INSN_CACHE
>>    CLEAR_INSN_CACHE (beg, end);
>> #endif /* CLEAR_INSN_CACHE */
>> }
>
> Why not make CLEAR_INSN_CACHE a builtin, then, with the target back-end
> providing the definition of the built-in?

I think it is (see __builtin___clear_cache) , and this libgcc function 
is the fallback.

>  Then, ligcc can just call it.
>   It can be a no-op builtin if we don't have anything to do.
>

??

> And, in the compiler proper, instead of CLEAR_INSN_CACHE, we just have a
> boolean, defined by the target header if it doesn't provide a
> clear_cache instruction, that says whether to call the libgcc function.
>

In retrospect, I think adding __builtin___clear_cache was a mistake. 
Working on a single-cpu system, I had not considered the complexity of 
maintaining ICache consistency in an SMP environment.  For many systems, 
you have to make an operating system call, so the benefit of the GCC 
builtin is minimal at best.

The original motivation was for libffi closure and nested function 
trampolines, but it is an utter failure on SMP systems, so it couldn't 
be used.  Now it lives on as legacy GCC code.

David Daney
Joseph S. Myers - Oct. 14, 2010, 1:37 a.m.
On Wed, 13 Oct 2010, Nathan Froyd wrote:

> But your point about this being a public API raises an interesting
> question: what to do about those macros which are legitimately used in
> both the compiler and libgcc?  (Examples include HAS_INIT_SECTION,
> EH_FRAME_SECTION_NAME, and CLEAR_CACHE.)  I don't think anybody would be
> happy with duplicate definitions in libgcc/config and gcc/config.  Is it
> legitimate to define macros for such target macros to effectively
> transfer information from the compiler to runtime libraries, or is there
> a better way?

If you don't think a particular predefined macro would ever be of use to 
user code, and so don't want defining that macro added to startup cost for 
compiling user code, there is always the option of a -fbuilding-libgcc or 
similar option to cause such macros to be defined.
Mark Mitchell - Oct. 14, 2010, 2:29 a.m.
On 10/13/2010 6:01 PM, David Daney wrote:

>> Why not make CLEAR_INSN_CACHE a builtin, then, with the target back-end
>> providing the definition of the built-in?
> 
> I think it is (see __builtin___clear_cache) , and this libgcc function
> is the fallback.

Yes, but there's no reason that the fallback couldn't *also* be a
builtin, intended for use only within ligbcc.

> The original motivation was for libffi closure and nested function
> trampolines, but it is an utter failure on SMP systems, so it couldn't
> be used.  Now it lives on as legacy GCC code.

I'm not sure it's as bad an invention as you think, but in any case,
yes, we have to keep both the builtin and the libgcc interface now.
Richard Henderson - Oct. 14, 2010, 2:33 a.m.
On 10/13/2010 06:37 PM, Joseph S. Myers wrote:
> If you don't think a particular predefined macro would ever be of use to 
> user code, and so don't want defining that macro added to startup cost for 
> compiling user code, there is always the option of a -fbuilding-libgcc or 
> similar option to cause such macros to be defined.

I was just about to suggest this.  In particular, -fbuilding-libgcc
lets us hide anything we don't want to expose as part of a stable
user-interface.

Hopefully the set of macros that actually need to be shared like
this is reasonably small, but this gives us a reasonably easy out.
I suppose time will tell.


r~
Richard Earnshaw - Dec. 9, 2010, 3:39 p.m.
On Tue, 2010-10-12 at 23:48 +0000, Joseph S. Myers wrote:
> * arm, with -mwords-little-endian.  "Note: this option should only be used 
> if you require compatibility with code for big-endian ARM processors 
> generated by versions of the compiler prior to 2.8.".  It could probably 
> be removed by now.

Agreed.  It should certainly be deprecated in 4.6 and I would propose
removing it in 4.7.

The chances are high that the option produces buggy code.  Big-endian
code gets far too little testing as it is, and I suspect that option is
never tested at all these days.

R.
Paul Koning - Dec. 9, 2010, 3:43 p.m.
On Dec 9, 2010, at 10:39 AM, Richard Earnshaw wrote:

> 
> On Tue, 2010-10-12 at 23:48 +0000, Joseph S. Myers wrote:
>> * arm, with -mwords-little-endian.  "Note: this option should only be used 
>> if you require compatibility with code for big-endian ARM processors 
>> generated by versions of the compiler prior to 2.8.".  It could probably 
>> be removed by now.
> 
> Agreed.  It should certainly be deprecated in 4.6 and I would propose
> removing it in 4.7.
> 
> The chances are high that the option produces buggy code.  Big-endian
> code gets far too little testing as it is, and I suspect that option is
> never tested at all these days.

FWIW, I've been running pdp11 testsuites, including execution tests, with a fair amount of success.  It's not particularly clean so I'm not sure how or whether to commit it, but it does give the "pdp-endian" code a bit of a workout.  (In fact, there's a pending patch request for one small bug in common code turned up that way.)

	paul
Richard Earnshaw - Dec. 9, 2010, 3:45 p.m.
On Thu, 2010-12-09 at 10:43 -0500, Paul Koning wrote:
> On Dec 9, 2010, at 10:39 AM, Richard Earnshaw wrote:
> 
> > 
> > On Tue, 2010-10-12 at 23:48 +0000, Joseph S. Myers wrote:
> >> * arm, with -mwords-little-endian.  "Note: this option should only be used 
> >> if you require compatibility with code for big-endian ARM processors 
> >> generated by versions of the compiler prior to 2.8.".  It could probably 
> >> be removed by now.
> > 
> > Agreed.  It should certainly be deprecated in 4.6 and I would propose
> > removing it in 4.7.
> > 
> > The chances are high that the option produces buggy code.  Big-endian
> > code gets far too little testing as it is, and I suspect that option is
> > never tested at all these days.
> 
> FWIW, I've been running pdp11 testsuites, including execution tests, with a fair amount of success.  It's not particularly clean so I'm not sure how or whether to commit it, but it does give the "pdp-endian" code a bit of a workout.  (In fact, there's a pending patch request for one small bug in common code turned up that way.)

I should have been clearer that I was referring explicitly to big-endian
on ARM here, not other targets.

R.

Patch

diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index f2d273d..bb47224 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -99,14 +99,6 @@  extern int arc_cpu_type;
    numbered.  */
 #define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN)
 
-/* Define this to set the endianness to use in libgcc2.c, which can
-   not depend on target_flags.  */
-#ifdef __big_endian__
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#endif
-
 /* Width of a word, in units (bytes).  */
 #define UNITS_PER_WORD 4
 
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index c8cbfa2..0764285 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -560,14 +560,6 @@  extern int arm_arch_hwdiv;
    This is always false, even when in big-endian mode.  */
 #define WORDS_BIG_ENDIAN  (BYTES_BIG_ENDIAN && ! TARGET_LITTLE_WORDS)
 
-/* LIBGCC2_WORDS_BIG_ENDIAN has to be a constant, so we define this based
-   on processor pre-defineds when compiling libgcc2.c.  */
-#if defined(__ARMEB__) && !defined(__ARMWEL__)
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#endif
-
 /* Define this if most significant word of doubles is the lowest numbered.
    The rules are different based on whether or not we use FPA-format,
    VFP-format or some other floating point co-processor's format doubles.  */
diff --git a/gcc/config/dfp-bit.h b/gcc/config/dfp-bit.h
index f093785..aecd82a 100644
--- a/gcc/config/dfp-bit.h
+++ b/gcc/config/dfp-bit.h
@@ -33,12 +33,8 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include "coretypes.h"
 #include "tm.h"
 
-#ifndef LIBGCC2_WORDS_BIG_ENDIAN
-#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
-#endif
-
 #ifndef LIBGCC2_FLOAT_WORDS_BIG_ENDIAN
-#define LIBGCC2_FLOAT_WORDS_BIG_ENDIAN LIBGCC2_WORDS_BIG_ENDIAN
+#define LIBGCC2_FLOAT_WORDS_BIG_ENDIAN __WORDS_BIG_ENDIAN__
 #endif
 
 #ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
diff --git a/gcc/config/fixed-bit.h b/gcc/config/fixed-bit.h
index ce5b96e..2fac578 100644
--- a/gcc/config/fixed-bit.h
+++ b/gcc/config/fixed-bit.h
@@ -41,14 +41,6 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    Ex: If we define FROM_QQ and TO_SI, the conversion from QQ to SI is
    generated.  */
 
-/* Permit the tm.h file to select the endianness to use just for this
-   file.  This is used when the endianness is determined when the
-   compiler is run.  */
-
-#ifndef LIBGCC2_WORDS_BIG_ENDIAN
-#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
-#endif
-
 #ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
 #endif
@@ -428,7 +420,7 @@  typedef int word_type __attribute__ ((mode (__word__)));
 /* The following defines are based on the previous defines.  */
 
 #if defined (HINT_C_TYPE)
-#if LIBGCC2_WORDS_BIG_ENDIAN
+#if __WORDS_BIG_ENDIAN__
   struct INTstruct {HINT_C_TYPE high, low;};
 #else
   struct INTstruct {HINT_C_TYPE low, high;};
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 98e9b64..8605592 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -148,12 +148,6 @@  extern enum processor_type ia64_tune;
 
 #define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
 
-#if defined(__BIG_ENDIAN__)
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#endif
-
 #define UNITS_PER_WORD 8
 
 #define POINTER_SIZE (TARGET_ILP32 ? 32 : 64)
diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h
index 6e670ba..05b02f7 100644
--- a/gcc/config/iq2000/iq2000.h
+++ b/gcc/config/iq2000/iq2000.h
@@ -76,7 +76,6 @@ 
 #define BITS_BIG_ENDIAN 		0
 #define BYTES_BIG_ENDIAN 		1 
 #define WORDS_BIG_ENDIAN 		1
-#define LIBGCC2_WORDS_BIG_ENDIAN	1
 #define BITS_PER_WORD 			32
 #define MAX_BITS_PER_WORD 		64
 #define UNITS_PER_WORD 			4
diff --git a/gcc/config/lm32/lm32.h b/gcc/config/lm32/lm32.h
index b0c2d59..afe9a6b 100644
--- a/gcc/config/lm32/lm32.h
+++ b/gcc/config/lm32/lm32.h
@@ -84,7 +84,6 @@ 
 #define BITS_BIG_ENDIAN 0
 #define BYTES_BIG_ENDIAN 1
 #define WORDS_BIG_ENDIAN 1
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
 
 #define BITS_PER_UNIT 8
 #define BITS_PER_WORD 32
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index d767cb9..7bfc975 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -328,12 +328,6 @@  extern enum m32r_sdata m32r_sdata;
    numbered.  */
 #define WORDS_BIG_ENDIAN (TARGET_LITTLE_ENDIAN == 0)
 
-/* Define this macro if WORDS_BIG_ENDIAN is not constant.  This must
-   be a constant value with the same meaning as WORDS_BIG_ENDIAN,
-   which will be used only when compiling libgcc2.c.  Typically the
-   value will be set based on preprocessor defines.  */
-/*#define LIBGCC2_WORDS_BIG_ENDIAN 1*/
-
 /* Width of a word, in units (bytes).  */
 #define UNITS_PER_WORD 4
 
diff --git a/gcc/config/mcore/mcore.h b/gcc/config/mcore/mcore.h
index a149eb1..8efe64f 100644
--- a/gcc/config/mcore/mcore.h
+++ b/gcc/config/mcore/mcore.h
@@ -106,12 +106,6 @@  extern char * mcore_current_function_name;
    numbered.  */
 #define WORDS_BIG_ENDIAN (! TARGET_LITTLE_END)
 
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#ifdef __MCORELE__
-#undef  LIBGCC2_WORDS_BIG_ENDIAN
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#endif
-
 #define MAX_BITS_PER_WORD 32
 
 /* Width of a word, in units (bytes).  */
diff --git a/gcc/config/mep/mep.h b/gcc/config/mep/mep.h
index 07f0c85..1f51aa9 100644
--- a/gcc/config/mep/mep.h
+++ b/gcc/config/mep/mep.h
@@ -167,12 +167,6 @@  crtbegin.o%s"
 #define BYTES_BIG_ENDIAN (TARGET_LITTLE_ENDIAN ? 0 : 1)
 #define WORDS_BIG_ENDIAN (TARGET_LITTLE_ENDIAN ? 0 : 1)
 
-#ifdef __LITTLE_ENDIAN__
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#endif
-
 #define UNITS_PER_WORD 4
 
 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)	\
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 23dba7c..449c893 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1290,14 +1290,6 @@  enum mips_code_readable_setting {
 #define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
 #define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
 
-/* Define this to set the endianness to use in libgcc2.c, which can
-   not depend on target_flags.  */
-#if !defined(MIPSEL) && !defined(__MIPSEL__)
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#endif
-
 #define MAX_BITS_PER_WORD 64
 
 /* Width of a word, in units (bytes).  */
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 25584b2..6d88e32 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -258,14 +258,6 @@  do {									\
 #define	BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN)
 #define	WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN)
 
-/* Define this to set the endianness to use in libgcc2.c, which can
-   not depend on target_flags.  */
-#if !defined(__LITTLE_ENDIAN__) && !defined(__sun__)
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#endif
-
 /* Define cutoff for using external functions to save floating point.
    When optimizing for size, use external functions when profitable.  */
 #define FP_SAVE_INLINE(FIRST_REG) (optimize_size			\
diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h
index 7da4de1..534da5f 100644
--- a/gcc/config/rx/rx.h
+++ b/gcc/config/rx/rx.h
@@ -96,12 +96,6 @@  extern enum rx_cpu_types  rx_cpu_type;
 #define BYTES_BIG_ENDIAN 		TARGET_BIG_ENDIAN_DATA
 #define WORDS_BIG_ENDIAN 		TARGET_BIG_ENDIAN_DATA
 
-#ifdef __RX_BIG_ENDIAN__
-#define LIBGCC2_WORDS_BIG_ENDIAN	1
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN	0
-#endif
-
 #define UNITS_PER_WORD 			4
 
 #define INT_TYPE_SIZE			32
diff --git a/gcc/config/score/score.h b/gcc/config/score/score.h
index 621f56e..a01ffed 100644
--- a/gcc/config/score/score.h
+++ b/gcc/config/score/score.h
@@ -106,14 +106,6 @@ 
 #define BYTES_BIG_ENDIAN       (TARGET_LITTLE_ENDIAN == 0)
 #define WORDS_BIG_ENDIAN       (TARGET_LITTLE_ENDIAN == 0)
 
-/* Define this to set the endianness to use in libgcc2.c, which can
-   not depend on target_flags.  */
-#if defined(__scorele__)
-#define LIBGCC2_WORDS_BIG_ENDIAN       0
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN       1
-#endif
-
 /* Width of a word, in units (bytes).  */
 #define UNITS_PER_WORD                 4
 
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 8f149dc..145f496 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -518,14 +518,6 @@  extern enum sh_divide_strategy_e sh_div_strategy;
    numbered.  */
 #define WORDS_BIG_ENDIAN (TARGET_LITTLE_ENDIAN == 0)
 
-/* Define this to set the endianness to use in libgcc2.c, which can
-   not depend on target_flags.  */
-#if defined(__LITTLE_ENDIAN__)
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#endif
-
 #define MAX_BITS_PER_WORD 64
 
 /* Width in bits of an `int'.  We want just 32-bits, even if words are
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index ccb7dca..1955e99 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -585,14 +585,6 @@  extern struct sparc_cpu_select sparc_select[];
    numbered.  */
 #define WORDS_BIG_ENDIAN 1
 
-/* Define this to set the endianness to use in libgcc2.c, which can
-   not depend on target_flags.  */
-#if defined (__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN_DATA__)
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#endif
-
 #define MAX_BITS_PER_WORD	64
 
 /* Width of a word, in units (bytes).  */
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index 7dc22a2..435c21a 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -94,12 +94,6 @@  extern unsigned xtensa_current_frame_size;
 #define EXTRA_SPECS							\
   { "subtarget_cpp_spec", SUBTARGET_CPP_SPEC },
 
-#ifdef __XTENSA_EB__
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#endif
-
 /* Show we can debug even without a frame pointer.  */
 #define CAN_DEBUG_WITHOUT_FP
 
diff --git a/gcc/cppbuiltin.c b/gcc/cppbuiltin.c
index 89b0f41..cf71fcf 100644
--- a/gcc/cppbuiltin.c
+++ b/gcc/cppbuiltin.c
@@ -137,6 +137,7 @@  define_builtin_macros_for_type_sizes (cpp_reader *pfile)
 			TYPE_PRECISION (char_type_node));
   cpp_define_formatted (pfile, "__BIGGEST_ALIGNMENT__=%d",
 			BIGGEST_ALIGNMENT / BITS_PER_UNIT);
+  cpp_define_formatted (pfile, "__WORDS_BIG_ENDIAN__=%u", WORDS_BIG_ENDIAN);
 
   /* ptr_type_node can't be used here since ptr_mode is only set when
      toplev calls backend_init which is not done with -E switch.  */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index a268617..ab4e893 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -938,13 +938,6 @@  order of words in memory is the same as the order in registers.  This
 macro need not be a constant.
 @end defmac
 
-@defmac LIBGCC2_WORDS_BIG_ENDIAN
-Define this macro if @code{WORDS_BIG_ENDIAN} is not constant.  This must be a
-constant value with the same meaning as @code{WORDS_BIG_ENDIAN}, which will be
-used only when compiling @file{libgcc2.c}.  Typically the value will be set
-based on preprocessor defines.
-@end defmac
-
 @defmac FLOAT_WORDS_BIG_ENDIAN
 Define this macro to have the value 1 if @code{DFmode}, @code{XFmode} or
 @code{TFmode} floating point numbers are stored in memory with the word
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 74cf927..23fa032 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -936,13 +936,6 @@  order of words in memory is the same as the order in registers.  This
 macro need not be a constant.
 @end defmac
 
-@defmac LIBGCC2_WORDS_BIG_ENDIAN
-Define this macro if @code{WORDS_BIG_ENDIAN} is not constant.  This must be a
-constant value with the same meaning as @code{WORDS_BIG_ENDIAN}, which will be
-used only when compiling @file{libgcc2.c}.  Typically the value will be set
-based on preprocessor defines.
-@end defmac
-
 @defmac FLOAT_WORDS_BIG_ENDIAN
 Define this macro to have the value 1 if @code{DFmode}, @code{XFmode} or
 @code{TFmode} floating point numbers are stored in memory with the word
diff --git a/gcc/libgcc2.h b/gcc/libgcc2.h
index d2d86ef..d000dc3 100644
--- a/gcc/libgcc2.h
+++ b/gcc/libgcc2.h
@@ -35,14 +35,6 @@  extern void __clear_cache (char *, char *);
 extern void __eprintf (const char *, const char *, unsigned int, const char *)
   __attribute__ ((__noreturn__));
 
-/* Permit the tm.h file to select the endianness to use just for this
-   file.  This is used when the endianness is determined when the
-   compiler is run.  */
-
-#ifndef LIBGCC2_WORDS_BIG_ENDIAN
-#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
-#endif
-
 #ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
 #endif
@@ -407,9 +399,9 @@  extern TCtype __multc3 (TFtype, TFtype, TFtype, TFtype);
 #define int bogus_type
 
 /* DWstructs are pairs of Wtype values in the order determined by
-   LIBGCC2_WORDS_BIG_ENDIAN.  */
+   __WORDS_BIG_ENDIAN__.  */
 
-#if LIBGCC2_WORDS_BIG_ENDIAN
+#if __WORDS_BIG_ENDIAN__
   struct DWstruct {Wtype high, low;};
 #else
   struct DWstruct {Wtype low, high;};
diff --git a/gcc/system.h b/gcc/system.h
index 5131fed..ec0c796 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -785,7 +785,7 @@  extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
 	LANG_HOOKS_MISSING_ARGUMENT LANG_HOOKS_HASH_TYPES
 
 /* Hooks into libgcc2.  */
- #pragma GCC poison LIBGCC2_DOUBLE_TYPE_SIZE
+ #pragma GCC poison LIBGCC2_DOUBLE_TYPE_SIZE LIBGCC2_WORDS_BIG_ENDIAN
 
 /* Miscellaneous macros that are no longer used.  */
  #pragma GCC poison USE_MAPPED_LOCATION
diff --git a/libdecnumber/dconfig.h b/libdecnumber/dconfig.h
index 91aa334..e8c1a44 100644
--- a/libdecnumber/dconfig.h
+++ b/libdecnumber/dconfig.h
@@ -28,12 +28,8 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include "coretypes.h"
 #include "tm.h"
 
-#ifndef LIBGCC2_WORDS_BIG_ENDIAN
-#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
-#endif
-
 #ifndef LIBGCC2_FLOAT_WORDS_BIG_ENDIAN
-#define LIBGCC2_FLOAT_WORDS_BIG_ENDIAN LIBGCC2_WORDS_BIG_ENDIAN
+#define LIBGCC2_FLOAT_WORDS_BIG_ENDIAN __WORDS_BIG_ENDIAN__
 #endif
 
 #if LIBGCC2_FLOAT_WORDS_BIG_ENDIAN
diff --git a/libgcc/config/libbid/bid_gcc_intrinsics.h b/libgcc/config/libbid/bid_gcc_intrinsics.h
index f5bd8d0..8852d08 100644
--- a/libgcc/config/libbid/bid_gcc_intrinsics.h
+++ b/libgcc/config/libbid/bid_gcc_intrinsics.h
@@ -30,12 +30,8 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include "coretypes.h"
 #include "tm.h"
 
-#ifndef LIBGCC2_WORDS_BIG_ENDIAN
-#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
-#endif
-
 #ifndef LIBGCC2_FLOAT_WORDS_BIG_ENDIAN
-#define LIBGCC2_FLOAT_WORDS_BIG_ENDIAN LIBGCC2_WORDS_BIG_ENDIAN
+#define LIBGCC2_FLOAT_WORDS_BIG_ENDIAN __WORDS_BIG_ENDIAN__
 #endif
 
 #ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE