From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libstdc++-v3/doc/html/manual/internals.html | 371 ++++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 libstdc++-v3/doc/html/manual/internals.html (limited to 'libstdc++-v3/doc/html/manual/internals.html') diff --git a/libstdc++-v3/doc/html/manual/internals.html b/libstdc++-v3/doc/html/manual/internals.html new file mode 100644 index 000000000..c6531fb55 --- /dev/null +++ b/libstdc++-v3/doc/html/manual/internals.html @@ -0,0 +1,371 @@ + + +Porting to New Hardware or Operating Systems

+

This document explains how to port libstdc++ (the GNU C++ library) to +a new target. +

In order to make the GNU C++ library (libstdc++) work with a new +target, you must edit some configuration files and provide some new +header files. Unless this is done, libstdc++ will use generic +settings which may not be correct for your target; even if they are +correct, they will likely be inefficient. +

Before you get started, make sure that you have a working C library on +your target. The C library need not precisely comply with any +particular standard, but should generally conform to the requirements +imposed by the ANSI/ISO standard. +

In addition, you should try to verify that the C++ compiler generally +works. It is difficult to test the C++ compiler without a working +library, but you should at least try some minimal test cases. +

(Note that what we think of as a "target," the library refers to as +a "host." The comment at the top of configure.ac explains why.) +

If you are porting to a new operating system (as opposed to a new chip +using an existing operating system), you will need to create a new +directory in the config/os hierarchy. For example, the IRIX +configuration files are all in config/os/irix. There is no set +way to organize the OS configuration directory. For example, +config/os/solaris/solaris-2.6 and +config/os/solaris/solaris-2.7 are used as configuration +directories for these two versions of Solaris. On the other hand, both +Solaris 2.7 and Solaris 2.8 use the config/os/solaris/solaris-2.7 +directory. The important information is that there needs to be a +directory under config/os to store the files for your operating +system. +

You might have to change the configure.host file to ensure that +your new directory is activated. Look for the switch statement that sets +os_include_dir, and add a pattern to handle your operating system +if the default will not suffice. The switch statement switches on only +the OS portion of the standard target triplet; e.g., the solaris2.8 +in sparc-sun-solaris2.8. If the new directory is named after the +OS portion of the triplet (the default), then nothing needs to be changed. +

The first file to create in this directory, should be called +os_defines.h. This file contains basic macro definitions +that are required to allow the C++ library to work with your C library. +

Several libstdc++ source files unconditionally define the macro +_POSIX_SOURCE. On many systems, defining this macro causes +large portions of the C library header files to be eliminated +at preprocessing time. Therefore, you may have to #undef this +macro, or define other macros (like _LARGEFILE_SOURCE or +__EXTENSIONS__). You won't know what macros to define or +undefine at this point; you'll have to try compiling the library and +seeing what goes wrong. If you see errors about calling functions +that have not been declared, look in your C library headers to see if +the functions are declared there, and then figure out what macros you +need to define. You will need to add them to the +CPLUSPLUS_CPP_SPEC macro in the GCC configuration file for your +target. It will not work to simply define these macros in +os_defines.h. +

At this time, there are a few libstdc++-specific macros which may be +defined: +

_GLIBCXX_USE_C99_CHECK may be defined to 1 to check C99 +function declarations (which are not covered by specialization below) +found in system headers against versions found in the library headers +derived from the standard. +

_GLIBCXX_USE_C99_DYNAMIC may be defined to an expression that +yields 0 if and only if the system headers are exposing proper support +for C99 functions (which are not covered by specialization below). If +defined, it must be 0 while bootstrapping the compiler/rebuilding the +library. +

_GLIBCXX_USE_C99_LONG_LONG_CHECK may be defined to 1 to check +the set of C99 long long function declarations found in system headers +against versions found in the library headers derived from the +standard. + +

_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC may be defined to an +expression that yields 0 if and only if the system headers are +exposing proper support for the set of C99 long long functions. If +defined, it must be 0 while bootstrapping the compiler/rebuilding the +library. +

_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC may be defined to an +expression that yields 0 if and only if the system headers +are exposing proper support for the related set of macros. If defined, +it must be 0 while bootstrapping the compiler/rebuilding the library. +

_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_CHECK may be defined +to 1 to check the related set of function declarations found in system +headers against versions found in the library headers derived from +the standard. +

_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC may be defined +to an expression that yields 0 if and only if the system headers +are exposing proper support for the related set of functions. If defined, +it must be 0 while bootstrapping the compiler/rebuilding the library. +

Finally, you should bracket the entire file in an include-guard, like +this: +

+
+#ifndef _GLIBCXX_OS_DEFINES
+#define _GLIBCXX_OS_DEFINES
+...
+#endif
+

We recommend copying an existing os_defines.h to use as a +starting point. +

If you are porting to a new chip (as opposed to a new operating system +running on an existing chip), you will need to create a new directory in the +config/cpu hierarchy. Much like the Operating system setup, +there are no strict rules on how to organize the CPU configuration +directory, but careful naming choices will allow the configury to find your +setup files without explicit help. +

We recommend that for a target triplet <CPU>-<vendor>-<OS>, you +name your configuration directory config/cpu/<CPU>. If you do this, +the configury will find the directory by itself. Otherwise you will need to +edit the configure.host file and, in the switch statement that sets +cpu_include_dir, add a pattern to handle your chip. +

Note that some chip families share a single configuration directory, for +example, alpha, alphaev5, and alphaev6 all use the +config/cpu/alpha directory, and there is an entry in the +configure.host switch statement to handle this. +

The cpu_include_dir sets default locations for the files controlling +Thread safety and Numeric limits, if the defaults are not +appropriate for your chip. +

The library requires that you provide three header files to implement +character classification, analogous to that provided by the C libraries +<ctype.h> header. You can model these on the files provided in +config/os/generic. However, these files will almost +certainly need some modification. +

The first file to write is ctype_base.h. This file provides +some very basic information about character classification. The libstdc++ +library assumes that your C library implements <ctype.h> by using +a table (indexed by character code) containing integers, where each of +these integers is a bit-mask indicating whether the character is +upper-case, lower-case, alphabetic, etc. The ctype_base.h +file gives the type of the integer, and the values of the various bit +masks. You will have to peer at your own <ctype.h> to figure out +how to define the values required by this file. +

The ctype_base.h header file does not need include guards. +It should contain a single struct definition called +ctype_base. This struct should contain two type +declarations, and one enumeration declaration, like this example, taken +from the IRIX configuration: +

+  struct ctype_base
+     {
+       typedef unsigned int 	mask;
+       typedef int* 		__to_type;
+
+       enum
+       {
+	 space = _ISspace,
+	 print = _ISprint,
+	 cntrl = _IScntrl,
+	 upper = _ISupper,
+	 lower = _ISlower,
+	 alpha = _ISalpha,
+	 digit = _ISdigit,
+	 punct = _ISpunct,
+	 xdigit = _ISxdigit,
+	 alnum = _ISalnum,
+	 graph = _ISgraph
+       };
+     };
+

The mask type is the type of the elements in the table. If your +C library uses a table to map lower-case numbers to upper-case numbers, +and vice versa, you should define __to_type to be the type of the +elements in that table. If you don't mind taking a minor performance +penalty, or if your library doesn't implement toupper and +tolower in this way, you can pick any pointer-to-integer type, +but you must still define the type. +

The enumeration should give definitions for all the values in the above +example, using the values from your native <ctype.h>. They can +be given symbolically (as above), or numerically, if you prefer. You do +not have to include <ctype.h> in this header; it will always be +included before ctype_base.h is included. +

The next file to write is ctype_noninline.h, which also does +not require include guards. This file defines a few member functions +that will be included in include/bits/locale_facets.h. The first +function that must be written is the ctype<char>::ctype +constructor. Here is the IRIX example: +

+ctype<char>::ctype(const mask* __table = 0, bool __del = false,
+	   size_t __refs = 0)
+       : _Ctype_nois<char>(__refs), _M_del(__table != 0 && __del),
+	 _M_toupper(NULL),
+	 _M_tolower(NULL),
+	 _M_ctable(NULL),
+	 _M_table(!__table
+		  ? (const mask*) (__libc_attr._ctype_tbl->_class + 1)
+		  : __table)
+       { }
+

There are two parts of this that you might choose to alter. The first, +and most important, is the line involving __libc_attr. That is +IRIX system-dependent code that gets the base of the table mapping +character codes to attributes. You need to substitute code that obtains +the address of this table on your system. If you want to use your +operating system's tables to map upper-case letters to lower-case, and +vice versa, you should initialize _M_toupper and +_M_tolower with those tables, in similar fashion. +

Now, you have to write two functions to convert from upper-case to +lower-case, and vice versa. Here are the IRIX versions: +

+     char
+     ctype<char>::do_toupper(char __c) const
+     { return _toupper(__c); }
+
+     char
+     ctype<char>::do_tolower(char __c) const
+     { return _tolower(__c); }
+

Your C library provides equivalents to IRIX's _toupper and +_tolower. If you initialized _M_toupper and +_M_tolower above, then you could use those tables instead. +

Finally, you have to provide two utility functions that convert strings +of characters. The versions provided here will always work - but you +could use specialized routines for greater performance if you have +machinery to do that on your system: +

+     const char*
+     ctype<char>::do_toupper(char* __low, const char* __high) const
+     {
+       while (__low < __high)
+	 {
+	   *__low = do_toupper(*__low);
+	   ++__low;
+	 }
+       return __high;
+     }
+
+     const char*
+     ctype<char>::do_tolower(char* __low, const char* __high) const
+     {
+       while (__low < __high)
+	 {
+	   *__low = do_tolower(*__low);
+	   ++__low;
+	 }
+       return __high;
+     }
+

You must also provide the ctype_inline.h file, which +contains a few more functions. On most systems, you can just copy +config/os/generic/ctype_inline.h and use it on your system. +

In detail, the functions provided test characters for particular +properties; they are analogous to the functions like isalpha and +islower provided by the C library. +

The first function is implemented like this on IRIX: +

+     bool
+     ctype<char>::
+     is(mask __m, char __c) const throw()
+     { return (_M_table)[(unsigned char)(__c)] & __m; }
+

The _M_table is the table passed in above, in the constructor. +This is the table that contains the bitmasks for each character. The +implementation here should work on all systems. +

The next function is: +

+     const char*
+     ctype<char>::
+     is(const char* __low, const char* __high, mask* __vec) const throw()
+     {
+       while (__low < __high)
+	 *__vec++ = (_M_table)[(unsigned char)(*__low++)];
+       return __high;
+     }
+

This function is similar; it copies the masks for all the characters +from __low up until __high into the vector given by +__vec. +

The last two functions again are entirely generic: +

+     const char*
+     ctype<char>::
+     scan_is(mask __m, const char* __low, const char* __high) const throw()
+     {
+       while (__low < __high && !this->is(__m, *__low))
+	 ++__low;
+       return __low;
+     }
+
+     const char*
+     ctype<char>::
+     scan_not(mask __m, const char* __low, const char* __high) const throw()
+     {
+       while (__low < __high && this->is(__m, *__low))
+	 ++__low;
+       return __low;
+     }
+

The C++ library string functionality requires a couple of atomic +operations to provide thread-safety. If you don't take any special +action, the library will use stub versions of these functions that are +not thread-safe. They will work fine, unless your applications are +multi-threaded. +

If you want to provide custom, safe, versions of these functions, there +are two distinct approaches. One is to provide a version for your CPU, +using assembly language constructs. The other is to use the +thread-safety primitives in your operating system. In either case, you +make a file called atomicity.h, and the variable +ATOMICITYH must point to this file. +

If you are using the assembly-language approach, put this code in +config/cpu/<chip>/atomicity.h, where chip is the name of +your processor (see CPU). No additional changes are necessary to +locate the file in this case; ATOMICITYH will be set by default. +

If you are using the operating system thread-safety primitives approach, +you can also put this code in the same CPU directory, in which case no more +work is needed to locate the file. For examples of this approach, +see the atomicity.h file for IRIX or IA64. +

Alternatively, if the primitives are more closely related to the OS +than they are to the CPU, you can put the atomicity.h file in +the Operating system directory instead. In this case, you must +edit configure.host, and in the switch statement that handles +operating systems, override the ATOMICITYH variable to point to +the appropriate os_include_dir. For examples of this approach, +see the atomicity.h file for AIX. +

With those bits out of the way, you have to actually write +atomicity.h itself. This file should be wrapped in an +include guard named _GLIBCXX_ATOMICITY_H. It should define one +type, and two functions. +

The type is _Atomic_word. Here is the version used on IRIX: +

+typedef long _Atomic_word;
+

This type must be a signed integral type supporting atomic operations. +If you're using the OS approach, use the same type used by your system's +primitives. Otherwise, use the type for which your CPU provides atomic +primitives. +

Then, you must provide two functions. The bodies of these functions +must be equivalent to those provided here, but using atomic operations: +

+     static inline _Atomic_word
+     __attribute__ ((__unused__))
+     __exchange_and_add (_Atomic_word* __mem, int __val)
+     {
+       _Atomic_word __result = *__mem;
+       *__mem += __val;
+       return __result;
+     }
+
+     static inline void
+     __attribute__ ((__unused__))
+     __atomic_add (_Atomic_word* __mem, int __val)
+     {
+       *__mem += __val;
+     }
+
-- cgit v1.2.3