xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/doc/xml/manual/internals.xml (revision b1e838363e3c6fc78a55519254d99869742dd33c)
148fb7bfaSmrg<section xmlns="http://docbook.org/ns/docbook" version="5.0"
248fb7bfaSmrg	 xml:id="appendix.porting.internals" xreflabel="Portin Internals">
34fee23f9Smrg<?dbhtml filename="internals.html"?>
44fee23f9Smrg
548fb7bfaSmrg<info><title>Porting to New Hardware or Operating Systems</title>
64fee23f9Smrg  <keywordset>
748fb7bfaSmrg    <keyword>ISO C++</keyword>
848fb7bfaSmrg    <keyword>internals</keyword>
94fee23f9Smrg  </keywordset>
1048fb7bfaSmrg</info>
114fee23f9Smrg
1248fb7bfaSmrg
134fee23f9Smrg
144fee23f9Smrg<para>
154fee23f9Smrg</para>
164fee23f9Smrg
174fee23f9Smrg
184fee23f9Smrg<para>This document explains how to port libstdc++ (the GNU C++ library) to
194fee23f9Smrga new target.
204fee23f9Smrg</para>
214fee23f9Smrg
224fee23f9Smrg   <para>In order to make the GNU C++ library (libstdc++) work with a new
234fee23f9Smrgtarget, you must edit some configuration files and provide some new
244fee23f9Smrgheader files.  Unless this is done, libstdc++ will use generic
254fee23f9Smrgsettings which may not be correct for your target; even if they are
264fee23f9Smrgcorrect, they will likely be inefficient.
274fee23f9Smrg   </para>
284fee23f9Smrg
294fee23f9Smrg   <para>Before you get started, make sure that you have a working C library on
304fee23f9Smrgyour target.  The C library need not precisely comply with any
314fee23f9Smrgparticular standard, but should generally conform to the requirements
324fee23f9Smrgimposed by the ANSI/ISO standard.
334fee23f9Smrg   </para>
344fee23f9Smrg
354fee23f9Smrg   <para>In addition, you should try to verify that the C++ compiler generally
364fee23f9Smrgworks.  It is difficult to test the C++ compiler without a working
374fee23f9Smrglibrary, but you should at least try some minimal test cases.
384fee23f9Smrg   </para>
394fee23f9Smrg
404fee23f9Smrg   <para>(Note that what we think of as a "target," the library refers to as
414fee23f9Smrga "host."  The comment at the top of <code>configure.ac</code> explains why.)
424fee23f9Smrg   </para>
434fee23f9Smrg
444fee23f9Smrg
4548fb7bfaSmrg<section xml:id="internals.os"><info><title>Operating System</title></info>
4648fb7bfaSmrg
474fee23f9Smrg
484fee23f9Smrg<para>If you are porting to a new operating system (as opposed to a new chip
494fee23f9Smrgusing an existing operating system), you will need to create a new
504fee23f9Smrgdirectory in the <code>config/os</code> hierarchy.  For example, the IRIX
514fee23f9Smrgconfiguration files are all in <code>config/os/irix</code>.  There is no set
524fee23f9Smrgway to organize the OS configuration directory.  For example,
534fee23f9Smrg<code>config/os/solaris/solaris-2.6</code> and
544fee23f9Smrg<code>config/os/solaris/solaris-2.7</code> are used as configuration
554fee23f9Smrgdirectories for these two versions of Solaris.  On the other hand, both
564fee23f9SmrgSolaris 2.7 and Solaris 2.8 use the <code>config/os/solaris/solaris-2.7</code>
574fee23f9Smrgdirectory.  The important information is that there needs to be a
584fee23f9Smrgdirectory under <code>config/os</code> to store the files for your operating
594fee23f9Smrgsystem.
604fee23f9Smrg</para>
614fee23f9Smrg
624fee23f9Smrg   <para>You might have to change the <code>configure.host</code> file to ensure that
634fee23f9Smrgyour new directory is activated.  Look for the switch statement that sets
644fee23f9Smrg<code>os_include_dir</code>, and add a pattern to handle your operating system
654fee23f9Smrgif the default will not suffice.  The switch statement switches on only
664fee23f9Smrgthe OS portion of the standard target triplet; e.g., the <code>solaris2.8</code>
674fee23f9Smrgin <code>sparc-sun-solaris2.8</code>.  If the new directory is named after the
684fee23f9SmrgOS portion of the triplet (the default), then nothing needs to be changed.
694fee23f9Smrg   </para>
704fee23f9Smrg
714fee23f9Smrg   <para>The first file to create in this directory, should be called
724fee23f9Smrg<code>os_defines.h</code>.  This file contains basic macro definitions
734fee23f9Smrgthat are required to allow the C++ library to work with your C library.
744fee23f9Smrg   </para>
754fee23f9Smrg
764fee23f9Smrg   <para>Several libstdc++ source files unconditionally define the macro
774fee23f9Smrg<code>_POSIX_SOURCE</code>.  On many systems, defining this macro causes
784fee23f9Smrglarge portions of the C library header files to be eliminated
794fee23f9Smrgat preprocessing time.  Therefore, you may have to <code>#undef</code> this
804fee23f9Smrgmacro, or define other macros (like <code>_LARGEFILE_SOURCE</code> or
814fee23f9Smrg<code>__EXTENSIONS__</code>).  You won't know what macros to define or
824fee23f9Smrgundefine at this point; you'll have to try compiling the library and
834fee23f9Smrgseeing what goes wrong.  If you see errors about calling functions
844fee23f9Smrgthat have not been declared, look in your C library headers to see if
854fee23f9Smrgthe functions are declared there, and then figure out what macros you
864fee23f9Smrgneed to define.  You will need to add them to the
874fee23f9Smrg<code>CPLUSPLUS_CPP_SPEC</code> macro in the GCC configuration file for your
884fee23f9Smrgtarget.  It will not work to simply define these macros in
894fee23f9Smrg<code>os_defines.h</code>.
904fee23f9Smrg   </para>
914fee23f9Smrg
924fee23f9Smrg   <para>At this time, there are a few libstdc++-specific macros which may be
934fee23f9Smrgdefined:
944fee23f9Smrg   </para>
954fee23f9Smrg
964fee23f9Smrg   <para><code>_GLIBCXX_USE_C99_CHECK</code> may be defined to 1 to check C99
974fee23f9Smrgfunction declarations (which are not covered by specialization below)
984fee23f9Smrgfound in system headers against versions found in the library headers
994fee23f9Smrgderived from the standard.
1004fee23f9Smrg   </para>
1014fee23f9Smrg
1024fee23f9Smrg   <para><code>_GLIBCXX_USE_C99_DYNAMIC</code> may be defined to an expression that
1034fee23f9Smrgyields 0 if and only if the system headers are exposing proper support
1044fee23f9Smrgfor C99 functions (which are not covered by specialization below).  If
1054fee23f9Smrgdefined, it must be 0 while bootstrapping the compiler/rebuilding the
1064fee23f9Smrglibrary.
1074fee23f9Smrg   </para>
1084fee23f9Smrg
1094fee23f9Smrg   <para><code>_GLIBCXX_USE_C99_LONG_LONG_CHECK</code> may be defined to 1 to check
1104fee23f9Smrgthe set of C99 long long function declarations found in system headers
1114fee23f9Smrgagainst versions found in the library headers derived from the
1124fee23f9Smrgstandard.
1134fee23f9Smrg
1144fee23f9Smrg   </para>
1154fee23f9Smrg   <para><code>_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC</code> may be defined to an
1164fee23f9Smrgexpression that yields 0 if and only if the system headers are
1174fee23f9Smrgexposing proper support for the set of C99 long long functions.  If
1184fee23f9Smrgdefined, it must be 0 while bootstrapping the compiler/rebuilding the
1194fee23f9Smrglibrary.
1204fee23f9Smrg   </para>
1214fee23f9Smrg   <para><code>_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC</code> may be defined to an
1224fee23f9Smrgexpression that yields 0 if and only if the system headers
1234fee23f9Smrgare exposing proper support for the related set of macros.  If defined,
1244fee23f9Smrgit must be 0 while bootstrapping the compiler/rebuilding the library.
1254fee23f9Smrg   </para>
1264fee23f9Smrg   <para><code>_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_CHECK</code> may be defined
1274fee23f9Smrgto 1 to check the related set of function declarations found in system
1284fee23f9Smrgheaders against versions found in the library headers derived from
1294fee23f9Smrgthe standard.
1304fee23f9Smrg   </para>
1314fee23f9Smrg   <para><code>_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC</code> may be defined
1324fee23f9Smrgto an expression that yields 0 if and only if the system headers
1334fee23f9Smrgare exposing proper support for the related set of functions.  If defined,
1344fee23f9Smrgit must be 0 while bootstrapping the compiler/rebuilding the library.
1354fee23f9Smrg   </para>
136*f9a78e0eSmrg   <para><code>_GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC</code> may be defined
137*f9a78e0eSmrgto an expression that yields 0 if and only if the system headers
138*f9a78e0eSmrgare exposing non-standard <code>isinf(double)</code> and
139*f9a78e0eSmrg<code>isnan(double)</code> functions in the global namespace. Those functions
140*f9a78e0eSmrgshould be detected automatically by the <code>configure</code> script when
141*f9a78e0eSmrglibstdc++ is built but if their presence depends on compilation flags or
142*f9a78e0eSmrgother macros the static configuration can be overridden.
143*f9a78e0eSmrg   </para>
1444fee23f9Smrg   <para>Finally, you should bracket the entire file in an include-guard, like
1454fee23f9Smrgthis:
1464fee23f9Smrg   </para>
1474fee23f9Smrg
1484fee23f9Smrg<programlisting>
1494fee23f9Smrg
1504fee23f9Smrg#ifndef _GLIBCXX_OS_DEFINES
1514fee23f9Smrg#define _GLIBCXX_OS_DEFINES
1524fee23f9Smrg...
1534fee23f9Smrg#endif
1544fee23f9Smrg</programlisting>
1554fee23f9Smrg
1564fee23f9Smrg   <para>We recommend copying an existing <code>os_defines.h</code> to use as a
1574fee23f9Smrgstarting point.
1584fee23f9Smrg   </para>
15948fb7bfaSmrg</section>
1604fee23f9Smrg
1614fee23f9Smrg
16248fb7bfaSmrg<section xml:id="internals.cpu"><info><title>CPU</title></info>
16348fb7bfaSmrg
1644fee23f9Smrg
1654fee23f9Smrg<para>If you are porting to a new chip (as opposed to a new operating system
1664fee23f9Smrgrunning on an existing chip), you will need to create a new directory in the
1674fee23f9Smrg<code>config/cpu</code> hierarchy.  Much like the <link linkend="internals.os">Operating system</link> setup,
1684fee23f9Smrgthere are no strict rules on how to organize the CPU configuration
1694fee23f9Smrgdirectory, but careful naming choices will allow the configury to find your
1704fee23f9Smrgsetup files without explicit help.
1714fee23f9Smrg</para>
1724fee23f9Smrg
1734fee23f9Smrg   <para>We recommend that for a target triplet <code>&lt;CPU&gt;-&lt;vendor&gt;-&lt;OS&gt;</code>, you
1744fee23f9Smrgname your configuration directory <code>config/cpu/&lt;CPU&gt;</code>.  If you do this,
1754fee23f9Smrgthe configury will find the directory by itself.  Otherwise you will need to
1764fee23f9Smrgedit the <code>configure.host</code> file and, in the switch statement that sets
1774fee23f9Smrg<code>cpu_include_dir</code>, add a pattern to handle your chip.
1784fee23f9Smrg   </para>
1794fee23f9Smrg
1804fee23f9Smrg   <para>Note that some chip families share a single configuration directory, for
1814fee23f9Smrgexample, <code>alpha</code>, <code>alphaev5</code>, and <code>alphaev6</code> all use the
1824fee23f9Smrg<code>config/cpu/alpha</code> directory, and there is an entry in the
1834fee23f9Smrg<code>configure.host</code> switch statement to handle this.
1844fee23f9Smrg   </para>
1854fee23f9Smrg
1864fee23f9Smrg   <para>The <code>cpu_include_dir</code> sets default locations for the files controlling
1874fee23f9Smrg<link linkend="internals.thread_safety">Thread safety</link> and <link linkend="internals.numeric_limits">Numeric limits</link>, if the defaults are not
1884fee23f9Smrgappropriate for your chip.
1894fee23f9Smrg   </para>
1904fee23f9Smrg
19148fb7bfaSmrg</section>
1924fee23f9Smrg
1934fee23f9Smrg
19448fb7bfaSmrg<section xml:id="internals.char_types"><info><title>Character Types</title></info>
19548fb7bfaSmrg
1964fee23f9Smrg
1974fee23f9Smrg<para>The library requires that you provide three header files to implement
1984fee23f9Smrgcharacter classification, analogous to that provided by the C libraries
1994fee23f9Smrg<code>&lt;ctype.h&gt;</code> header.  You can model these on the files provided in
2004fee23f9Smrg<code>config/os/generic</code>.  However, these files will almost
2014fee23f9Smrgcertainly need some modification.
2024fee23f9Smrg</para>
2034fee23f9Smrg
2044fee23f9Smrg   <para>The first file to write is <code>ctype_base.h</code>.  This file provides
2054fee23f9Smrgsome very basic information about character classification.  The libstdc++
2064fee23f9Smrglibrary assumes that your C library implements <code>&lt;ctype.h&gt;</code> by using
2074fee23f9Smrga table (indexed by character code) containing integers, where each of
2084fee23f9Smrgthese integers is a bit-mask indicating whether the character is
2094fee23f9Smrgupper-case, lower-case, alphabetic, etc.  The <code>ctype_base.h</code>
2104fee23f9Smrgfile gives the type of the integer, and the values of the various bit
2114fee23f9Smrgmasks.  You will have to peer at your own <code>&lt;ctype.h&gt;</code> to figure out
2124fee23f9Smrghow to define the values required by this file.
2134fee23f9Smrg   </para>
2144fee23f9Smrg
2154fee23f9Smrg   <para>The <code>ctype_base.h</code> header file does not need include guards.
2164fee23f9SmrgIt should contain a single <code>struct</code> definition called
2174fee23f9Smrg<code>ctype_base</code>.  This <code>struct</code> should contain two type
2184fee23f9Smrgdeclarations, and one enumeration declaration, like this example, taken
2194fee23f9Smrgfrom the IRIX configuration:
2204fee23f9Smrg   </para>
2214fee23f9Smrg
2224fee23f9Smrg<programlisting>
2234fee23f9Smrg  struct ctype_base
2244fee23f9Smrg     {
2254fee23f9Smrg       typedef unsigned int 	mask;
2264fee23f9Smrg       typedef int* 		__to_type;
2274fee23f9Smrg
2284fee23f9Smrg       enum
2294fee23f9Smrg       {
2304fee23f9Smrg	 space = _ISspace,
2314fee23f9Smrg	 print = _ISprint,
2324fee23f9Smrg	 cntrl = _IScntrl,
2334fee23f9Smrg	 upper = _ISupper,
2344fee23f9Smrg	 lower = _ISlower,
2354fee23f9Smrg	 alpha = _ISalpha,
2364fee23f9Smrg	 digit = _ISdigit,
2374fee23f9Smrg	 punct = _ISpunct,
2384fee23f9Smrg	 xdigit = _ISxdigit,
2394fee23f9Smrg	 alnum = _ISalnum,
2404fee23f9Smrg	 graph = _ISgraph
2414fee23f9Smrg       };
2424fee23f9Smrg     };
2434fee23f9Smrg</programlisting>
2444fee23f9Smrg
2454fee23f9Smrg<para>The <code>mask</code> type is the type of the elements in the table.  If your
2464fee23f9SmrgC library uses a table to map lower-case numbers to upper-case numbers,
2474fee23f9Smrgand vice versa, you should define <code>__to_type</code> to be the type of the
2484fee23f9Smrgelements in that table.  If you don't mind taking a minor performance
2494fee23f9Smrgpenalty, or if your library doesn't implement <code>toupper</code> and
2504fee23f9Smrg<code>tolower</code> in this way, you can pick any pointer-to-integer type,
2514fee23f9Smrgbut you must still define the type.
2524fee23f9Smrg</para>
2534fee23f9Smrg
2544fee23f9Smrg   <para>The enumeration should give definitions for all the values in the above
2554fee23f9Smrgexample, using the values from your native <code>&lt;ctype.h&gt;</code>.  They can
2564fee23f9Smrgbe given symbolically (as above), or numerically, if you prefer.  You do
2574fee23f9Smrgnot have to include <code>&lt;ctype.h&gt;</code> in this header; it will always be
2584fee23f9Smrgincluded before <code>ctype_base.h</code> is included.
2594fee23f9Smrg   </para>
2604fee23f9Smrg
26148fb7bfaSmrg   <para>The next file to write is <code>ctype_configure_char.cc</code>.
26248fb7bfaSmrgThe first function that must be written is the <code>ctype&lt;char&gt;::ctype</code> constructor.  Here is the IRIX example:
2634fee23f9Smrg   </para>
2644fee23f9Smrg
2654fee23f9Smrg<programlisting>
2664fee23f9Smrgctype&lt;char&gt;::ctype(const mask* __table = 0, bool __del = false,
2674fee23f9Smrg	   size_t __refs = 0)
2684fee23f9Smrg       : _Ctype_nois&lt;char&gt;(__refs), _M_del(__table != 0 &amp;&amp; __del),
2694fee23f9Smrg	 _M_toupper(NULL),
2704fee23f9Smrg	 _M_tolower(NULL),
2714fee23f9Smrg	 _M_ctable(NULL),
2724fee23f9Smrg	 _M_table(!__table
2734fee23f9Smrg		  ? (const mask*) (__libc_attr._ctype_tbl-&gt;_class + 1)
2744fee23f9Smrg		  : __table)
2754fee23f9Smrg       { }
2764fee23f9Smrg</programlisting>
2774fee23f9Smrg
2784fee23f9Smrg<para>There are two parts of this that you might choose to alter. The first,
2794fee23f9Smrgand most important, is the line involving <code>__libc_attr</code>.  That is
2804fee23f9SmrgIRIX system-dependent code that gets the base of the table mapping
2814fee23f9Smrgcharacter codes to attributes.  You need to substitute code that obtains
2824fee23f9Smrgthe address of this table on your system.  If you want to use your
2834fee23f9Smrgoperating system's tables to map upper-case letters to lower-case, and
2844fee23f9Smrgvice versa, you should initialize <code>_M_toupper</code> and
2854fee23f9Smrg<code>_M_tolower</code> with those tables, in similar fashion.
2864fee23f9Smrg</para>
2874fee23f9Smrg
2884fee23f9Smrg   <para>Now, you have to write two functions to convert from upper-case to
2894fee23f9Smrglower-case, and vice versa.  Here are the IRIX versions:
2904fee23f9Smrg   </para>
2914fee23f9Smrg
2924fee23f9Smrg<programlisting>
2934fee23f9Smrg     char
2944fee23f9Smrg     ctype&lt;char&gt;::do_toupper(char __c) const
2954fee23f9Smrg     { return _toupper(__c); }
2964fee23f9Smrg
2974fee23f9Smrg     char
2984fee23f9Smrg     ctype&lt;char&gt;::do_tolower(char __c) const
2994fee23f9Smrg     { return _tolower(__c); }
3004fee23f9Smrg</programlisting>
3014fee23f9Smrg
3024fee23f9Smrg<para>Your C library provides equivalents to IRIX's <code>_toupper</code> and
3034fee23f9Smrg<code>_tolower</code>.  If you initialized <code>_M_toupper</code> and
3044fee23f9Smrg<code>_M_tolower</code> above, then you could use those tables instead.
3054fee23f9Smrg</para>
3064fee23f9Smrg
3074fee23f9Smrg   <para>Finally, you have to provide two utility functions that convert strings
3084fee23f9Smrgof characters.  The versions provided here will always work - but you
3094fee23f9Smrgcould use specialized routines for greater performance if you have
3104fee23f9Smrgmachinery to do that on your system:
3114fee23f9Smrg   </para>
3124fee23f9Smrg
3134fee23f9Smrg<programlisting>
3144fee23f9Smrg     const char*
3154fee23f9Smrg     ctype&lt;char&gt;::do_toupper(char* __low, const char* __high) const
3164fee23f9Smrg     {
3174fee23f9Smrg       while (__low &lt; __high)
3184fee23f9Smrg	 {
3194fee23f9Smrg	   *__low = do_toupper(*__low);
3204fee23f9Smrg	   ++__low;
3214fee23f9Smrg	 }
3224fee23f9Smrg       return __high;
3234fee23f9Smrg     }
3244fee23f9Smrg
3254fee23f9Smrg     const char*
3264fee23f9Smrg     ctype&lt;char&gt;::do_tolower(char* __low, const char* __high) const
3274fee23f9Smrg     {
3284fee23f9Smrg       while (__low &lt; __high)
3294fee23f9Smrg	 {
3304fee23f9Smrg	   *__low = do_tolower(*__low);
3314fee23f9Smrg	   ++__low;
3324fee23f9Smrg	 }
3334fee23f9Smrg       return __high;
3344fee23f9Smrg     }
3354fee23f9Smrg</programlisting>
3364fee23f9Smrg
3374fee23f9Smrg   <para>You must also provide the <code>ctype_inline.h</code> file, which
3384fee23f9Smrgcontains a few more functions.  On most systems, you can just copy
3394fee23f9Smrg<code>config/os/generic/ctype_inline.h</code> and use it on your system.
3404fee23f9Smrg   </para>
3414fee23f9Smrg
3424fee23f9Smrg   <para>In detail, the functions provided test characters for particular
3434fee23f9Smrgproperties; they are analogous to the functions like <code>isalpha</code> and
3444fee23f9Smrg<code>islower</code> provided by the C library.
3454fee23f9Smrg   </para>
3464fee23f9Smrg
3474fee23f9Smrg   <para>The first function is implemented like this on IRIX:
3484fee23f9Smrg   </para>
3494fee23f9Smrg
3504fee23f9Smrg<programlisting>
3514fee23f9Smrg     bool
3524fee23f9Smrg     ctype&lt;char&gt;::
3534fee23f9Smrg     is(mask __m, char __c) const throw()
3544fee23f9Smrg     { return (_M_table)[(unsigned char)(__c)] &amp; __m; }
3554fee23f9Smrg</programlisting>
3564fee23f9Smrg
3574fee23f9Smrg<para>The <code>_M_table</code> is the table passed in above, in the constructor.
3584fee23f9SmrgThis is the table that contains the bitmasks for each character.  The
3594fee23f9Smrgimplementation here should work on all systems.
3604fee23f9Smrg</para>
3614fee23f9Smrg
3624fee23f9Smrg   <para>The next function is:
3634fee23f9Smrg   </para>
3644fee23f9Smrg
3654fee23f9Smrg<programlisting>
3664fee23f9Smrg     const char*
3674fee23f9Smrg     ctype&lt;char&gt;::
3684fee23f9Smrg     is(const char* __low, const char* __high, mask* __vec) const throw()
3694fee23f9Smrg     {
3704fee23f9Smrg       while (__low &lt; __high)
3714fee23f9Smrg	 *__vec++ = (_M_table)[(unsigned char)(*__low++)];
3724fee23f9Smrg       return __high;
3734fee23f9Smrg     }
3744fee23f9Smrg</programlisting>
3754fee23f9Smrg
3764fee23f9Smrg<para>This function is similar; it copies the masks for all the characters
3774fee23f9Smrgfrom <code>__low</code> up until <code>__high</code> into the vector given by
3784fee23f9Smrg<code>__vec</code>.
3794fee23f9Smrg</para>
3804fee23f9Smrg
3814fee23f9Smrg   <para>The last two functions again are entirely generic:
3824fee23f9Smrg   </para>
3834fee23f9Smrg
3844fee23f9Smrg<programlisting>
3854fee23f9Smrg     const char*
3864fee23f9Smrg     ctype&lt;char&gt;::
3874fee23f9Smrg     scan_is(mask __m, const char* __low, const char* __high) const throw()
3884fee23f9Smrg     {
3894fee23f9Smrg       while (__low &lt; __high &amp;&amp; !this-&gt;is(__m, *__low))
3904fee23f9Smrg	 ++__low;
3914fee23f9Smrg       return __low;
3924fee23f9Smrg     }
3934fee23f9Smrg
3944fee23f9Smrg     const char*
3954fee23f9Smrg     ctype&lt;char&gt;::
3964fee23f9Smrg     scan_not(mask __m, const char* __low, const char* __high) const throw()
3974fee23f9Smrg     {
3984fee23f9Smrg       while (__low &lt; __high &amp;&amp; this-&gt;is(__m, *__low))
3994fee23f9Smrg	 ++__low;
4004fee23f9Smrg       return __low;
4014fee23f9Smrg     }
4024fee23f9Smrg</programlisting>
4034fee23f9Smrg
40448fb7bfaSmrg</section>
4054fee23f9Smrg
4064fee23f9Smrg
40748fb7bfaSmrg<section xml:id="internals.thread_safety"><info><title>Thread Safety</title></info>
40848fb7bfaSmrg
4094fee23f9Smrg
4104fee23f9Smrg<para>The C++ library string functionality requires a couple of atomic
4114fee23f9Smrgoperations to provide thread-safety.  If you don't take any special
4124fee23f9Smrgaction, the library will use stub versions of these functions that are
4134fee23f9Smrgnot thread-safe.  They will work fine, unless your applications are
4144fee23f9Smrgmulti-threaded.
4154fee23f9Smrg</para>
4164fee23f9Smrg
4174fee23f9Smrg   <para>If you want to provide custom, safe, versions of these functions, there
4184fee23f9Smrgare two distinct approaches.  One is to provide a version for your CPU,
4194fee23f9Smrgusing assembly language constructs.  The other is to use the
4204fee23f9Smrgthread-safety primitives in your operating system.  In either case, you
4214fee23f9Smrgmake a file called <code>atomicity.h</code>, and the variable
4224fee23f9Smrg<code>ATOMICITYH</code> must point to this file.
4234fee23f9Smrg   </para>
4244fee23f9Smrg
4254fee23f9Smrg   <para>If you are using the assembly-language approach, put this code in
4264fee23f9Smrg<code>config/cpu/&lt;chip&gt;/atomicity.h</code>, where chip is the name of
4274fee23f9Smrgyour processor (see <link linkend="internals.cpu">CPU</link>).  No additional changes are necessary to
4284fee23f9Smrglocate the file in this case; <code>ATOMICITYH</code> will be set by default.
4294fee23f9Smrg   </para>
4304fee23f9Smrg
4314fee23f9Smrg   <para>If you are using the operating system thread-safety primitives approach,
4324fee23f9Smrgyou can also put this code in the same CPU directory, in which case no more
4334fee23f9Smrgwork is needed to locate the file.  For examples of this approach,
4344fee23f9Smrgsee the <code>atomicity.h</code> file for IRIX or IA64.
4354fee23f9Smrg   </para>
4364fee23f9Smrg
4374fee23f9Smrg   <para>Alternatively, if the primitives are more closely related to the OS
4384fee23f9Smrgthan they are to the CPU, you can put the <code>atomicity.h</code> file in
4394fee23f9Smrgthe <link linkend="internals.os">Operating system</link> directory instead.  In this case, you must
4404fee23f9Smrgedit <code>configure.host</code>, and in the switch statement that handles
4414fee23f9Smrgoperating systems, override the <code>ATOMICITYH</code> variable to point to
4424fee23f9Smrgthe appropriate <code>os_include_dir</code>.  For examples of this approach,
4434fee23f9Smrgsee the <code>atomicity.h</code> file for AIX.
4444fee23f9Smrg   </para>
4454fee23f9Smrg
4464fee23f9Smrg   <para>With those bits out of the way, you have to actually write
4474fee23f9Smrg<code>atomicity.h</code> itself.  This file should be wrapped in an
4484fee23f9Smrginclude guard named <code>_GLIBCXX_ATOMICITY_H</code>.  It should define one
4494fee23f9Smrgtype, and two functions.
4504fee23f9Smrg   </para>
4514fee23f9Smrg
4524fee23f9Smrg   <para>The type is <code>_Atomic_word</code>.  Here is the version used on IRIX:
4534fee23f9Smrg   </para>
4544fee23f9Smrg
4554fee23f9Smrg<programlisting>
4564fee23f9Smrgtypedef long _Atomic_word;
4574fee23f9Smrg</programlisting>
4584fee23f9Smrg
4594fee23f9Smrg<para>This type must be a signed integral type supporting atomic operations.
4604fee23f9SmrgIf you're using the OS approach, use the same type used by your system's
4614fee23f9Smrgprimitives.  Otherwise, use the type for which your CPU provides atomic
4624fee23f9Smrgprimitives.
4634fee23f9Smrg</para>
4644fee23f9Smrg
4654fee23f9Smrg   <para>Then, you must provide two functions.  The bodies of these functions
4664fee23f9Smrgmust be equivalent to those provided here, but using atomic operations:
4674fee23f9Smrg   </para>
4684fee23f9Smrg
4694fee23f9Smrg<programlisting>
4704fee23f9Smrg     static inline _Atomic_word
4714fee23f9Smrg     __attribute__ ((__unused__))
4724fee23f9Smrg     __exchange_and_add (_Atomic_word* __mem, int __val)
4734fee23f9Smrg     {
4744fee23f9Smrg       _Atomic_word __result = *__mem;
4754fee23f9Smrg       *__mem += __val;
4764fee23f9Smrg       return __result;
4774fee23f9Smrg     }
4784fee23f9Smrg
4794fee23f9Smrg     static inline void
4804fee23f9Smrg     __attribute__ ((__unused__))
4814fee23f9Smrg     __atomic_add (_Atomic_word* __mem, int __val)
4824fee23f9Smrg     {
4834fee23f9Smrg       *__mem += __val;
4844fee23f9Smrg     }
4854fee23f9Smrg</programlisting>
4864fee23f9Smrg
48748fb7bfaSmrg</section>
4884fee23f9Smrg
4894fee23f9Smrg
49048fb7bfaSmrg<section xml:id="internals.numeric_limits"><info><title>Numeric Limits</title></info>
49148fb7bfaSmrg
4924fee23f9Smrg
4934fee23f9Smrg<para>The C++ library requires information about the fundamental data types,
4944fee23f9Smrgsuch as the minimum and maximum representable values of each type.
4954fee23f9SmrgYou can define each of these values individually, but it is usually
4964fee23f9Smrgeasiest just to indicate how many bits are used in each of the data
4974fee23f9Smrgtypes and let the library do the rest.  For information about the
4984fee23f9Smrgmacros to define, see the top of <code>include/bits/std_limits.h</code>.
4994fee23f9Smrg</para>
5004fee23f9Smrg
5014fee23f9Smrg   <para>If you need to define any macros, you can do so in <code>os_defines.h</code>.
5024fee23f9SmrgHowever, if all operating systems for your CPU are likely to use the
5034fee23f9Smrgsame values, you can provide a CPU-specific file instead so that you
5044fee23f9Smrgdo not have to provide the same definitions for each operating system.
5054fee23f9SmrgTo take that approach, create a new file called <code>cpu_limits.h</code> in
5064fee23f9Smrgyour CPU configuration directory (see <link linkend="internals.cpu">CPU</link>).
5074fee23f9Smrg   </para>
5084fee23f9Smrg
50948fb7bfaSmrg</section>
5104fee23f9Smrg
5114fee23f9Smrg
51248fb7bfaSmrg<section xml:id="internals.libtool"><info><title>Libtool</title></info>
51348fb7bfaSmrg
5144fee23f9Smrg
5154fee23f9Smrg<para>The C++ library is compiled, archived and linked with libtool.
5164fee23f9SmrgExplaining the full workings of libtool is beyond the scope of this
5174fee23f9Smrgdocument, but there are a few, particular bits that are necessary for
5184fee23f9Smrgporting.
5194fee23f9Smrg</para>
5204fee23f9Smrg
5214fee23f9Smrg   <para>Some parts of the libstdc++ library are compiled with the libtool
5224fee23f9Smrg<code>--tags CXX</code> option (the C++ definitions for libtool).  Therefore,
5234fee23f9Smrg<code>ltcf-cxx.sh</code> in the top-level directory needs to have the correct
5244fee23f9Smrglogic to compile and archive objects equivalent to the C version of libtool,
5254fee23f9Smrg<code>ltcf-c.sh</code>.  Some libtool targets have definitions for C but not
5264fee23f9Smrgfor C++, or C++ definitions which have not been kept up to date.
5274fee23f9Smrg   </para>
5284fee23f9Smrg
5294fee23f9Smrg   <para>The C++ run-time library contains initialization code that needs to be
5304fee23f9Smrgrun as the library is loaded.  Often, that requires linking in special
5314fee23f9Smrgobject files when the C++ library is built as a shared library, or
5324fee23f9Smrgtaking other system-specific actions.
5334fee23f9Smrg   </para>
5344fee23f9Smrg
5354fee23f9Smrg   <para>The libstdc++ library is linked with the C version of libtool, even
5364fee23f9Smrgthough it is a C++ library.  Therefore, the C version of libtool needs to
5374fee23f9Smrgensure that the run-time library initializers are run.  The usual way to
5384fee23f9Smrgdo this is to build the library using <code>gcc -shared</code>.
5394fee23f9Smrg   </para>
5404fee23f9Smrg
5414fee23f9Smrg   <para>If you need to change how the library is linked, look at
5424fee23f9Smrg<code>ltcf-c.sh</code> in the top-level directory.  Find the switch statement
5434fee23f9Smrgthat sets <code>archive_cmds</code>.  Here, adjust the setting for your
5444fee23f9Smrgoperating system.
5454fee23f9Smrg   </para>
5464fee23f9Smrg
5474fee23f9Smrg
54848fb7bfaSmrg</section>
5494fee23f9Smrg
55048fb7bfaSmrg</section>
551